diff --git a/hmdriver2/driver.py b/hmdriver2/driver.py index 5d588cc..fe79b48 100644 --- a/hmdriver2/driver.py +++ b/hmdriver2/driver.py @@ -188,7 +188,7 @@ def get_app_abilities(self, package_name: str) -> List[Dict]: try: is_launcher_ability = False skills = ability_info['skills'] - if len(skills) > 0 or "action.system.home" in skills[0]["actions"]: + if len(skills) > 0 and "action.system.home" in (skills[0].get("actions") or []): is_launcher_ability = True icon_ability_info = { "name": ability_info["name"], diff --git a/tests/fixtures/bm_dump_app_abilities.json b/tests/fixtures/bm_dump_app_abilities.json new file mode 100644 index 0000000..4d9152f --- /dev/null +++ b/tests/fixtures/bm_dump_app_abilities.json @@ -0,0 +1,52 @@ +{ + "appId": "com.samples.test.uitest_test_signature", + "compatibleVersion": 40100011, + "cpuAbi": "arm64-v8a", + "hapModuleInfos": [ + { + "mainAbility": "EntryAbility", + "moduleName": "entry", + "abilityInfos": [ + { + "name": "EmptySkillsAbility", + "moduleName": "entry", + "skills": [] + }, + { + "name": "ShareAbility", + "moduleName": "entry", + "skills": [ + { + "actions": ["ohos.want.action.sendData"], + "entities": ["entity.system.default"] + } + ] + }, + { + "name": "NoActionsAbility", + "moduleName": "entry", + "skills": [ + { + "entities": ["entity.system.default"] + } + ] + }, + { + "name": "EntryAbility", + "moduleName": "entry", + "skills": [ + { + "actions": ["action.system.home"], + "entities": ["entity.system.home"] + } + ] + } + ] + } + ], + "mainEntry": "entry", + "name": "com.samples.test.uitest", + "vendor": "samples", + "versionCode": 1000000, + "versionName": "1.0.0" +} diff --git a/tests/test_app_abilities.py b/tests/test_app_abilities.py new file mode 100644 index 0000000..6d7fa13 --- /dev/null +++ b/tests/test_app_abilities.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +import json +from pathlib import Path + +from hmdriver2.driver import Driver +from hmdriver2.proto import CommandResult + + +FIXTURE_PATH = Path(__file__).parent / "fixtures" / "bm_dump_app_abilities.json" + + +def _bm_dump_output() -> str: + """hdc shell `bm dump -n` prefixes the JSON object with the bundle name.""" + payload = FIXTURE_PATH.read_text(encoding="utf-8") + return f"com.samples.test.uitest:\n{payload}\n" + + +def _driver_from_bm_dump(output: str = None) -> Driver: + """Build a Driver that never talks to a Harmony device.""" + if output is None: + output = _bm_dump_output() + + driver = object.__new__(Driver) + + class _FakeHdc: + def shell(self, cmd): + return CommandResult(output, "", 0) + + driver.hdc = _FakeHdc() + return driver + + +def _abilities_by_name(driver: Driver): + abilities = driver.get_app_abilities("com.samples.test.uitest") + return {item["name"]: item for item in abilities} + + +def test_fixture_covers_empty_non_home_and_home_skills(): + dump = json.loads(FIXTURE_PATH.read_text(encoding="utf-8")) + skills_by_name = { + ability["name"]: ability["skills"] + for module in dump["hapModuleInfos"] + for ability in module["abilityInfos"] + } + assert skills_by_name["EmptySkillsAbility"] == [] + assert "action.system.home" not in skills_by_name["ShareAbility"][0].get("actions", []) + assert "action.system.home" in skills_by_name["EntryAbility"][0]["actions"] + + +def test_empty_skills_kept_and_not_launcher(): + by_name = _abilities_by_name(_driver_from_bm_dump()) + assert "EmptySkillsAbility" in by_name + assert by_name["EmptySkillsAbility"]["isLauncherAbility"] is False + + +def test_skills_without_home_action_not_launcher(): + by_name = _abilities_by_name(_driver_from_bm_dump()) + assert "ShareAbility" in by_name + assert by_name["ShareAbility"]["isLauncherAbility"] is False + assert "NoActionsAbility" in by_name + assert by_name["NoActionsAbility"]["isLauncherAbility"] is False + + +def test_skills_with_home_action_is_launcher(): + by_name = _abilities_by_name(_driver_from_bm_dump()) + assert "EntryAbility" in by_name + assert by_name["EntryAbility"]["isLauncherAbility"] is True + + +def test_get_app_main_ability_prefers_home_skill(): + main = _driver_from_bm_dump().get_app_main_ability("com.samples.test.uitest") + assert main["name"] == "EntryAbility" + assert main["isLauncherAbility"] is True + assert main["moduleName"] == "entry" + assert main["moduleMainAbility"] == "EntryAbility" + assert main["mainModule"] == "entry"