"""Rule 3: an applicationIdSuffix variant hides LAUNCHER but keeps MAIN."""
from __future__ import annotations
from pathlib import Path
from repo_contract import android_manifest as am
from .conftest import write
from .flutter_app import MAIN, NS, REMOVE, SANDBOX_GRADLE, flutter_app, hide, manifest
SANDBOX = "android/app/src/sandbox/AndroidManifest.xml"
def sandbox_app(root: Path) -> Path:
return flutter_app(root, gradle=SANDBOX_GRADLE)
def test_no_suffix_variant_passes(tmp_path: Path) -> None:
assert am.variant_problems(flutter_app(tmp_path)) == []
def test_no_gradle_passes(tmp_path: Path) -> None:
assert am.variant_problems(flutter_app(tmp_path, gradle=None)) == []
def test_hidden_variant_passes(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, SANDBOX, hide())
assert am.variant_problems(app) == []
def test_fully_qualified_activity_name_matches(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, SANDBOX, hide("com.kuhy.demo.MainActivity"))
assert am.variant_problems(app) == []
def test_missing_variant_manifest_fails(tmp_path: Path) -> None:
got = am.variant_problems(sandbox_app(tmp_path))
assert got == [
(
f"variant 'sandbox' sets applicationIdSuffix but {SANDBOX} is missing:"
' hide it with in .MainActivity\'s intent-filter'
)
]
def test_variant_manifest_without_remove_fails(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, SANDBOX, hide(tag=""))
assert am.variant_problems(app) == [
(
f"variant 'sandbox': {SANDBOX} does not remove the LAUNCHER category from"
' .MainActivity (tools:node="remove" on the )'
)
]
def test_remove_on_other_activity_fails(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, SANDBOX, hide(".OtherActivity"))
assert len(am.variant_problems(app)) == 1
def test_removing_main_fails(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, SANDBOX, hide(main=REMOVE))
assert am.variant_problems(app) == [
(
f"variant 'sandbox': {SANDBOX} removes android.intent.action.MAIN from"
" .MainActivity; keep MAIN so `am start -n` still works"
)
]
def test_removing_whole_activity_fails(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
body = hide().replace(
'',
'',
)
write(app, SANDBOX, body)
assert "removes android.intent.action.MAIN" in am.variant_problems(app)[0]
def test_removing_main_intent_filter_fails(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(
app,
SANDBOX,
hide(tag="").replace("", f""),
)
assert "removes android.intent.action.MAIN" in am.variant_problems(app)[0]
def test_invalid_variant_manifest_fails(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, SANDBOX, hide().replace(f" {am.TOOLS_DECL}", ""))
got = am.variant_problems(app)
assert len(got) == 1 and got[0].startswith(f"{SANDBOX} is not valid XML:")
def test_main_manifest_without_launcher_needs_nothing(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, MAIN.as_posix(), f"")
assert am.variant_problems(app) == []
def test_unreadable_main_manifest_needs_nothing(tmp_path: Path) -> None:
app = sandbox_app(tmp_path)
write(app, MAIN.as_posix(), " None:
app = sandbox_app(tmp_path)
body = (
manifest()
.replace("", "")
)
write(app, MAIN.as_posix(), body)
got = am.variant_problems(app)
assert len(got) == 1 and "is missing" in got[0]
def test_groovy_buildtype_suffix(tmp_path: Path) -> None:
gradle = "android { buildTypes { debug { applicationIdSuffix '.debug' } } }\n"
app = flutter_app(tmp_path, gradle=gradle, kts=False)
write(app, "android/app/src/debug/AndroidManifest.xml", hide())
assert am.variant_problems(app) == []