From e602a464db566b968a3e3ce7befefc3ed9392136 Mon Sep 17 00:00:00 2001 From: Manu <4445816+tr4nt0r@users.noreply.github.com> Date: Tue, 29 Oct 2024 19:03:41 +0100 Subject: [PATCH] Add tests for buttons in Habitica integration (#128194) * Add tests for button platform * update tests * Add skill buttons * Assert state, add fixtures/parametrization * entity as list --- .../fixtures/common_buttons_unavailable.json | 39 + .../habitica/fixtures/healer_fixture.json | 40 + .../fixtures/healer_skills_unavailable.json | 39 + .../habitica/fixtures/rogue_fixture.json | 40 + .../fixtures/rogue_skills_unavailable.json | 39 + .../fixtures/rogue_stealth_unavailable.json | 39 + tests/components/habitica/fixtures/user.json | 18 +- .../habitica/fixtures/warrior_fixture.json | 40 + .../fixtures/warrior_skills_unavailable.json | 39 + .../habitica/fixtures/wizard_fixture.json | 40 + .../fixtures/wizard_frost_unavailable.json | 39 + .../fixtures/wizard_skills_unavailable.json | 39 + .../habitica/snapshots/test_button.ambr | 1631 +++++++++++++++++ tests/components/habitica/test_button.py | 332 ++++ 14 files changed, 2413 insertions(+), 1 deletion(-) create mode 100644 tests/components/habitica/fixtures/common_buttons_unavailable.json create mode 100644 tests/components/habitica/fixtures/healer_fixture.json create mode 100644 tests/components/habitica/fixtures/healer_skills_unavailable.json create mode 100644 tests/components/habitica/fixtures/rogue_fixture.json create mode 100644 tests/components/habitica/fixtures/rogue_skills_unavailable.json create mode 100644 tests/components/habitica/fixtures/rogue_stealth_unavailable.json create mode 100644 tests/components/habitica/fixtures/warrior_fixture.json create mode 100644 tests/components/habitica/fixtures/warrior_skills_unavailable.json create mode 100644 tests/components/habitica/fixtures/wizard_fixture.json create mode 100644 tests/components/habitica/fixtures/wizard_frost_unavailable.json create mode 100644 tests/components/habitica/fixtures/wizard_skills_unavailable.json create mode 100644 tests/components/habitica/snapshots/test_button.ambr create mode 100644 tests/components/habitica/test_button.py diff --git a/tests/components/habitica/fixtures/common_buttons_unavailable.json b/tests/components/habitica/fixtures/common_buttons_unavailable.json new file mode 100644 index 00000000000..08039ae1762 --- /dev/null +++ b/tests/components/habitica/fixtures/common_buttons_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": true, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 50, + "exp": 737, + "gp": 0, + "lvl": 5, + "class": "wizard", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/fixtures/healer_fixture.json b/tests/components/habitica/fixtures/healer_fixture.json new file mode 100644 index 00000000000..04cbabcfa2d --- /dev/null +++ b/tests/components/habitica/fixtures/healer_fixture.json @@ -0,0 +1,40 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 45, + "mp": 50.89999999999998, + "exp": 737, + "gp": 137.62587214609795, + "lvl": 38, + "class": "healer", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 5 + }, + "preferences": { + "sleep": false, + "automaticAllocation": true, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": true, + "lastCron": "2024-09-21T22:01:55.586Z" + } +} diff --git a/tests/components/habitica/fixtures/healer_skills_unavailable.json b/tests/components/habitica/fixtures/healer_skills_unavailable.json new file mode 100644 index 00000000000..305a5f8cda1 --- /dev/null +++ b/tests/components/habitica/fixtures/healer_skills_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 10, + "exp": 737, + "gp": 0, + "lvl": 34, + "class": "healer", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/fixtures/rogue_fixture.json b/tests/components/habitica/fixtures/rogue_fixture.json new file mode 100644 index 00000000000..f0ea42a7182 --- /dev/null +++ b/tests/components/habitica/fixtures/rogue_fixture.json @@ -0,0 +1,40 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 0, + "mp": 50.89999999999998, + "exp": 737, + "gp": 137.62587214609795, + "lvl": 38, + "class": "rogue", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 5 + }, + "preferences": { + "sleep": false, + "automaticAllocation": true, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": true, + "lastCron": "2024-09-21T22:01:55.586Z" + } +} diff --git a/tests/components/habitica/fixtures/rogue_skills_unavailable.json b/tests/components/habitica/fixtures/rogue_skills_unavailable.json new file mode 100644 index 00000000000..2709731ba55 --- /dev/null +++ b/tests/components/habitica/fixtures/rogue_skills_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": true, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 20, + "exp": 737, + "gp": 0, + "lvl": 38, + "class": "rogue", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/fixtures/rogue_stealth_unavailable.json b/tests/components/habitica/fixtures/rogue_stealth_unavailable.json new file mode 100644 index 00000000000..a4e86abbb91 --- /dev/null +++ b/tests/components/habitica/fixtures/rogue_stealth_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 4, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 50, + "exp": 737, + "gp": 0, + "lvl": 38, + "class": "rogue", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/fixtures/user.json b/tests/components/habitica/fixtures/user.json index 810e4351107..c2efe3e84e3 100644 --- a/tests/components/habitica/fixtures/user.json +++ b/tests/components/habitica/fixtures/user.json @@ -3,6 +3,18 @@ "api_user": "test-api-user", "profile": { "name": "test-user" }, "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, "hp": 0, "mp": 50.89999999999998, "exp": 737, @@ -16,7 +28,11 @@ }, "preferences": { "sleep": false, - "automaticAllocation": true + "automaticAllocation": true, + "disableClasses": false + }, + "flags": { + "classSelected": true }, "needsCron": true, "lastCron": "2024-09-21T22:01:55.586Z" diff --git a/tests/components/habitica/fixtures/warrior_fixture.json b/tests/components/habitica/fixtures/warrior_fixture.json new file mode 100644 index 00000000000..53d18206f9a --- /dev/null +++ b/tests/components/habitica/fixtures/warrior_fixture.json @@ -0,0 +1,40 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 50.89999999999998, + "exp": 737, + "gp": 137.62587214609795, + "lvl": 38, + "class": "warrior", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 5 + }, + "preferences": { + "sleep": false, + "automaticAllocation": true, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": true, + "lastCron": "2024-09-21T22:01:55.586Z" + } +} diff --git a/tests/components/habitica/fixtures/warrior_skills_unavailable.json b/tests/components/habitica/fixtures/warrior_skills_unavailable.json new file mode 100644 index 00000000000..53160646569 --- /dev/null +++ b/tests/components/habitica/fixtures/warrior_skills_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 10, + "exp": 737, + "gp": 0, + "lvl": 34, + "class": "warrior", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/fixtures/wizard_fixture.json b/tests/components/habitica/fixtures/wizard_fixture.json new file mode 100644 index 00000000000..0f9f2a49639 --- /dev/null +++ b/tests/components/habitica/fixtures/wizard_fixture.json @@ -0,0 +1,40 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 50.89999999999998, + "exp": 737, + "gp": 137.62587214609795, + "lvl": 38, + "class": "wizard", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 5 + }, + "preferences": { + "sleep": false, + "automaticAllocation": true, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": true, + "lastCron": "2024-09-21T22:01:55.586Z" + } +} diff --git a/tests/components/habitica/fixtures/wizard_frost_unavailable.json b/tests/components/habitica/fixtures/wizard_frost_unavailable.json new file mode 100644 index 00000000000..ba57568e99e --- /dev/null +++ b/tests/components/habitica/fixtures/wizard_frost_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": true, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 50, + "exp": 737, + "gp": 0, + "lvl": 34, + "class": "wizard", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/fixtures/wizard_skills_unavailable.json b/tests/components/habitica/fixtures/wizard_skills_unavailable.json new file mode 100644 index 00000000000..11bf0a19193 --- /dev/null +++ b/tests/components/habitica/fixtures/wizard_skills_unavailable.json @@ -0,0 +1,39 @@ +{ + "data": { + "api_user": "test-api-user", + "profile": { "name": "test-user" }, + "stats": { + "buffs": { + "str": 0, + "int": 0, + "per": 0, + "con": 0, + "stealth": 0, + "streaks": false, + "seafoam": false, + "shinySeed": false, + "snowball": false, + "spookySparkles": false + }, + "hp": 50, + "mp": 10, + "exp": 737, + "gp": 0, + "lvl": 34, + "class": "wizard", + "maxHealth": 50, + "maxMP": 166, + "toNextLevel": 880, + "points": 0 + }, + "preferences": { + "sleep": false, + "automaticAllocation": false, + "disableClasses": false + }, + "flags": { + "classSelected": true + }, + "needsCron": false + } +} diff --git a/tests/components/habitica/snapshots/test_button.ambr b/tests/components/habitica/snapshots/test_button.ambr new file mode 100644 index 00000000000..04e43f23c5c --- /dev/null +++ b/tests/components/habitica/snapshots/test_button.ambr @@ -0,0 +1,1631 @@ +# serializer version: 1 +# name: test_button_unavailable[button.test_user_allocate_all_stat_points-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Allocate all stat points', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_allocate_all_stat_points', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_allocate_all_stat_points-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Allocate all stat points', + }), + 'context': , + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_button_unavailable[button.test_user_buy_a_health_potion-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_buy_a_health_potion', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Buy a health potion', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_buy_health_potion', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_buy_a_health_potion-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_potion.png', + 'friendly_name': 'test-user Buy a health potion', + }), + 'context': , + 'entity_id': 'button.test_user_buy_a_health_potion', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_button_unavailable[button.test_user_chilling_frost-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_chilling_frost', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Chilling frost', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_frost', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_chilling_frost-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_frost.png', + 'friendly_name': 'test-user Chilling frost', + }), + 'context': , + 'entity_id': 'button.test_user_chilling_frost', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_button_unavailable[button.test_user_earthquake-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_earthquake', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Earthquake', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_earth', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_earthquake-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_earth.png', + 'friendly_name': 'test-user Earthquake', + }), + 'context': , + 'entity_id': 'button.test_user_earthquake', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_button_unavailable[button.test_user_ethereal_surge-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_ethereal_surge', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Ethereal surge', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_mpheal', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_ethereal_surge-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_mpheal.png', + 'friendly_name': 'test-user Ethereal surge', + }), + 'context': , + 'entity_id': 'button.test_user_ethereal_surge', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_button_unavailable[button.test_user_revive_from_death-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_revive_from_death', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Revive from death', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_revive', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_revive_from_death-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Revive from death', + }), + 'context': , + 'entity_id': 'button.test_user_revive_from_death', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_button_unavailable[button.test_user_start_my_day-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_start_my_day', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Start my day', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_run_cron', + 'unit_of_measurement': None, + }) +# --- +# name: test_button_unavailable[button.test_user_start_my_day-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Start my day', + }), + 'context': , + 'entity_id': 'button.test_user_start_my_day', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_allocate_all_stat_points-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Allocate all stat points', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_allocate_all_stat_points', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_allocate_all_stat_points-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Allocate all stat points', + }), + 'context': , + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_blessing-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_blessing', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Blessing', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_heal_all', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_blessing-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_healAll.png', + 'friendly_name': 'test-user Blessing', + }), + 'context': , + 'entity_id': 'button.test_user_blessing', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_buy_a_health_potion-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_buy_a_health_potion', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Buy a health potion', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_buy_health_potion', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_buy_a_health_potion-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_potion.png', + 'friendly_name': 'test-user Buy a health potion', + }), + 'context': , + 'entity_id': 'button.test_user_buy_a_health_potion', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_healing_light-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_healing_light', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Healing light', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_heal', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_healing_light-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_heal.png', + 'friendly_name': 'test-user Healing light', + }), + 'context': , + 'entity_id': 'button.test_user_healing_light', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_protective_aura-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_protective_aura', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Protective aura', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_protect_aura', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_protective_aura-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_protectAura.png', + 'friendly_name': 'test-user Protective aura', + }), + 'context': , + 'entity_id': 'button.test_user_protective_aura', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_revive_from_death-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_revive_from_death', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Revive from death', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_revive', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_revive_from_death-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Revive from death', + }), + 'context': , + 'entity_id': 'button.test_user_revive_from_death', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_searing_brightness-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_searing_brightness', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Searing brightness', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_brightness', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_searing_brightness-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_brightness.png', + 'friendly_name': 'test-user Searing brightness', + }), + 'context': , + 'entity_id': 'button.test_user_searing_brightness', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_start_my_day-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_start_my_day', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Start my day', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_run_cron', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[healer_fixture][button.test_user_start_my_day-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Start my day', + }), + 'context': , + 'entity_id': 'button.test_user_start_my_day', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_allocate_all_stat_points-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Allocate all stat points', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_allocate_all_stat_points', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_allocate_all_stat_points-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Allocate all stat points', + }), + 'context': , + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_buy_a_health_potion-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_buy_a_health_potion', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Buy a health potion', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_buy_health_potion', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_buy_a_health_potion-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_potion.png', + 'friendly_name': 'test-user Buy a health potion', + }), + 'context': , + 'entity_id': 'button.test_user_buy_a_health_potion', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_revive_from_death-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_revive_from_death', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Revive from death', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_revive', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_revive_from_death-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Revive from death', + }), + 'context': , + 'entity_id': 'button.test_user_revive_from_death', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_start_my_day-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_start_my_day', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Start my day', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_run_cron', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_start_my_day-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Start my day', + }), + 'context': , + 'entity_id': 'button.test_user_start_my_day', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_stealth-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_stealth', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Stealth', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_stealth', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_stealth-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_stealth.png', + 'friendly_name': 'test-user Stealth', + }), + 'context': , + 'entity_id': 'button.test_user_stealth', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_tools_of_the_trade-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_tools_of_the_trade', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Tools of the trade', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_tools_of_trade', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[rogue_fixture][button.test_user_tools_of_the_trade-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_toolsOfTrade.png', + 'friendly_name': 'test-user Tools of the trade', + }), + 'context': , + 'entity_id': 'button.test_user_tools_of_the_trade', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_allocate_all_stat_points-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Allocate all stat points', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_allocate_all_stat_points', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_allocate_all_stat_points-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Allocate all stat points', + }), + 'context': , + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_buy_a_health_potion-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_buy_a_health_potion', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Buy a health potion', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_buy_health_potion', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_buy_a_health_potion-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_potion.png', + 'friendly_name': 'test-user Buy a health potion', + }), + 'context': , + 'entity_id': 'button.test_user_buy_a_health_potion', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_defensive_stance-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_defensive_stance', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Defensive stance', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_defensive_stance', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_defensive_stance-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_defensiveStance.png', + 'friendly_name': 'test-user Defensive stance', + }), + 'context': , + 'entity_id': 'button.test_user_defensive_stance', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_intimidating_gaze-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_intimidating_gaze', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Intimidating gaze', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_intimidate', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_intimidating_gaze-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_intimidate.png', + 'friendly_name': 'test-user Intimidating gaze', + }), + 'context': , + 'entity_id': 'button.test_user_intimidating_gaze', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_revive_from_death-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_revive_from_death', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Revive from death', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_revive', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_revive_from_death-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Revive from death', + }), + 'context': , + 'entity_id': 'button.test_user_revive_from_death', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_start_my_day-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_start_my_day', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Start my day', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_run_cron', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_start_my_day-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Start my day', + }), + 'context': , + 'entity_id': 'button.test_user_start_my_day', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_valorous_presence-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_valorous_presence', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Valorous presence', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_valorous_presence', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[warrior_fixture][button.test_user_valorous_presence-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_valorousPresence.png', + 'friendly_name': 'test-user Valorous presence', + }), + 'context': , + 'entity_id': 'button.test_user_valorous_presence', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_allocate_all_stat_points-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Allocate all stat points', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_allocate_all_stat_points', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_allocate_all_stat_points-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Allocate all stat points', + }), + 'context': , + 'entity_id': 'button.test_user_allocate_all_stat_points', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_buy_a_health_potion-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_buy_a_health_potion', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Buy a health potion', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_buy_health_potion', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_buy_a_health_potion-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_potion.png', + 'friendly_name': 'test-user Buy a health potion', + }), + 'context': , + 'entity_id': 'button.test_user_buy_a_health_potion', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_chilling_frost-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_chilling_frost', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Chilling frost', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_frost', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_chilling_frost-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_frost.png', + 'friendly_name': 'test-user Chilling frost', + }), + 'context': , + 'entity_id': 'button.test_user_chilling_frost', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_earthquake-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_earthquake', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Earthquake', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_earth', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_earthquake-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_earth.png', + 'friendly_name': 'test-user Earthquake', + }), + 'context': , + 'entity_id': 'button.test_user_earthquake', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_ethereal_surge-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_ethereal_surge', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Ethereal surge', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_mpheal', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_ethereal_surge-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'entity_picture': 'https://habitica-assets.s3.amazonaws.com/mobileApp/images/shop_mpheal.png', + 'friendly_name': 'test-user Ethereal surge', + }), + 'context': , + 'entity_id': 'button.test_user_ethereal_surge', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_revive_from_death-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_revive_from_death', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Revive from death', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_revive', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_revive_from_death-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Revive from death', + }), + 'context': , + 'entity_id': 'button.test_user_revive_from_death', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unavailable', + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_start_my_day-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': None, + 'entity_id': 'button.test_user_start_my_day', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Start my day', + 'platform': 'habitica', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': , + 'unique_id': '00000000-0000-0000-0000-000000000000_run_cron', + 'unit_of_measurement': None, + }) +# --- +# name: test_buttons[wizard_fixture][button.test_user_start_my_day-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'test-user Start my day', + }), + 'context': , + 'entity_id': 'button.test_user_start_my_day', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- diff --git a/tests/components/habitica/test_button.py b/tests/components/habitica/test_button.py new file mode 100644 index 00000000000..e7eda1609c8 --- /dev/null +++ b/tests/components/habitica/test_button.py @@ -0,0 +1,332 @@ +"""Tests for Habitica button platform.""" + +from collections.abc import Generator +from http import HTTPStatus +import re +from unittest.mock import patch + +import pytest +from syrupy.assertion import SnapshotAssertion + +from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS +from homeassistant.components.habitica.const import DEFAULT_URL, DOMAIN +from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, Platform +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError, ServiceValidationError +from homeassistant.helpers import entity_registry as er + +from .conftest import mock_called_with + +from tests.common import MockConfigEntry, load_json_object_fixture, snapshot_platform +from tests.test_util.aiohttp import AiohttpClientMocker + + +@pytest.fixture(autouse=True) +def button_only() -> Generator[None]: + """Enable only the button platform.""" + with patch( + "homeassistant.components.habitica.PLATFORMS", + [Platform.BUTTON], + ): + yield + + +@pytest.mark.parametrize( + "fixture", + [ + "wizard_fixture", + "rogue_fixture", + "warrior_fixture", + "healer_fixture", + ], +) +async def test_buttons( + hass: HomeAssistant, + config_entry: MockConfigEntry, + aioclient_mock: AiohttpClientMocker, + snapshot: SnapshotAssertion, + entity_registry: er.EntityRegistry, + fixture: str, +) -> None: + """Test button entities.""" + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/user", + json=load_json_object_fixture(f"{fixture}.json", DOMAIN), + ) + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/tasks/user", + params={"type": "completedTodos"}, + json=load_json_object_fixture("completed_todos.json", DOMAIN), + ) + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/tasks/user", + json=load_json_object_fixture("tasks.json", DOMAIN), + ) + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.LOADED + + await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id) + + +@pytest.mark.parametrize( + ("entity_id", "api_url", "fixture"), + [ + ("button.test_user_allocate_all_stat_points", "user/allocate-now", "user"), + ("button.test_user_buy_a_health_potion", "user/buy-health-potion", "user"), + ("button.test_user_revive_from_death", "user/revive", "user"), + ("button.test_user_start_my_day", "cron", "user"), + ( + "button.test_user_chilling_frost", + "user/class/cast/frost", + "wizard_fixture", + ), + ( + "button.test_user_earthquake", + "user/class/cast/earth", + "wizard_fixture", + ), + ( + "button.test_user_ethereal_surge", + "user/class/cast/mpheal", + "wizard_fixture", + ), + ( + "button.test_user_stealth", + "user/class/cast/stealth", + "rogue_fixture", + ), + ( + "button.test_user_tools_of_the_trade", + "user/class/cast/toolsOfTrade", + "rogue_fixture", + ), + ( + "button.test_user_defensive_stance", + "user/class/cast/defensiveStance", + "warrior_fixture", + ), + ( + "button.test_user_intimidating_gaze", + "user/class/cast/intimidate", + "warrior_fixture", + ), + ( + "button.test_user_valorous_presence", + "user/class/cast/valorousPresence", + "warrior_fixture", + ), + ( + "button.test_user_healing_light", + "user/class/cast/heal", + "healer_fixture", + ), + ( + "button.test_user_protective_aura", + "user/class/cast/protectAura", + "healer_fixture", + ), + ( + "button.test_user_searing_brightness", + "user/class/cast/brightness", + "healer_fixture", + ), + ( + "button.test_user_blessing", + "user/class/cast/healAll", + "healer_fixture", + ), + ], +) +async def test_button_press( + hass: HomeAssistant, + config_entry: MockConfigEntry, + aioclient_mock: AiohttpClientMocker, + entity_id: str, + api_url: str, + fixture: str, +) -> None: + """Test button press method.""" + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/user", + json=load_json_object_fixture(f"{fixture}.json", DOMAIN), + ) + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/tasks/user", + params={"type": "completedTodos"}, + json=load_json_object_fixture("completed_todos.json", DOMAIN), + ) + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/tasks/user", + json=load_json_object_fixture("tasks.json", DOMAIN), + ) + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.LOADED + + aioclient_mock.post(f"{DEFAULT_URL}/api/v3/{api_url}", json={"data": None}) + + await hass.services.async_call( + BUTTON_DOMAIN, + SERVICE_PRESS, + {ATTR_ENTITY_ID: entity_id}, + blocking=True, + ) + + assert mock_called_with(aioclient_mock, "post", f"{DEFAULT_URL}/api/v3/{api_url}") + + +@pytest.mark.parametrize( + ("entity_id", "api_url"), + [ + ("button.test_user_allocate_all_stat_points", "user/allocate-now"), + ("button.test_user_buy_a_health_potion", "user/buy-health-potion"), + ("button.test_user_revive_from_death", "user/revive"), + ("button.test_user_start_my_day", "cron"), + ("button.test_user_chilling_frost", "user/class/cast/frost"), + ("button.test_user_earthquake", "user/class/cast/earth"), + ("button.test_user_ethereal_surge", "user/class/cast/mpheal"), + ], + ids=[ + "allocate-points", + "health-potion", + "revive", + "run-cron", + "chilling frost", + "earthquake", + "ethereal surge", + ], +) +@pytest.mark.parametrize( + ("status_code", "msg", "exception"), + [ + ( + HTTPStatus.TOO_MANY_REQUESTS, + "Currently rate limited", + ServiceValidationError, + ), + ( + HTTPStatus.BAD_REQUEST, + "Unable to connect to Habitica, try again later", + HomeAssistantError, + ), + ( + HTTPStatus.UNAUTHORIZED, + "Unable to carry out this action", + ServiceValidationError, + ), + ], +) +async def test_button_press_exceptions( + hass: HomeAssistant, + config_entry: MockConfigEntry, + mock_habitica: AiohttpClientMocker, + entity_id: str, + api_url: str, + status_code: HTTPStatus, + msg: str, + exception: Exception, +) -> None: + """Test button press exceptions.""" + + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.LOADED + + mock_habitica.post( + f"{DEFAULT_URL}/api/v3/{api_url}", + status=status_code, + json={"data": None}, + ) + + with pytest.raises(exception, match=msg): + await hass.services.async_call( + BUTTON_DOMAIN, + SERVICE_PRESS, + {ATTR_ENTITY_ID: entity_id}, + blocking=True, + ) + + assert mock_called_with(mock_habitica, "post", f"{DEFAULT_URL}/api/v3/{api_url}") + + +@pytest.mark.parametrize( + ("fixture", "entity_ids"), + [ + ( + "common_buttons_unavailable", + [ + "button.test_user_allocate_all_stat_points", + "button.test_user_revive_from_death", + "button.test_user_buy_a_health_potion", + "button.test_user_start_my_day", + ], + ), + ( + "wizard_skills_unavailable", + [ + "button.test_user_chilling_frost", + "button.test_user_earthquake", + "button.test_user_ethereal_surge", + ], + ), + ("wizard_frost_unavailable", ["button.test_user_chilling_frost"]), + ( + "rogue_skills_unavailable", + ["button.test_user_tools_of_the_trade", "button.test_user_stealth"], + ), + ("rogue_stealth_unavailable", ["button.test_user_stealth"]), + ( + "warrior_skills_unavailable", + [ + "button.test_user_defensive_stance", + "button.test_user_intimidating_gaze", + "button.test_user_valorous_presence", + ], + ), + ( + "healer_skills_unavailable", + [ + "button.test_user_healing_light", + "button.test_user_protective_aura", + "button.test_user_searing_brightness", + "button.test_user_blessing", + ], + ), + ], +) +async def test_button_unavailable( + hass: HomeAssistant, + config_entry: MockConfigEntry, + aioclient_mock: AiohttpClientMocker, + fixture: str, + entity_ids: list[str], +) -> None: + """Test buttons are unavailable if conditions are not met.""" + + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/user", + json=load_json_object_fixture(f"{fixture}.json", DOMAIN), + ) + aioclient_mock.get( + f"{DEFAULT_URL}/api/v3/tasks/user", + json=load_json_object_fixture("tasks.json", DOMAIN), + ) + aioclient_mock.get(re.compile(r".*"), json={"data": []}) + + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.LOADED + + for entity_id in entity_ids: + assert (state := hass.states.get(entity_id)) + assert state.state == STATE_UNAVAILABLE