@digital-alchemy/hass 24.9.3 → 24.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (276) hide show
  1. package/README.md +3 -0
  2. package/dist/dynamic.d.ts +1 -1
  3. package/dist/dynamic.js +7 -2
  4. package/dist/dynamic.js.map +1 -1
  5. package/dist/extensions/area.extension.d.ts +2 -12
  6. package/dist/extensions/area.extension.js +20 -26
  7. package/dist/extensions/area.extension.js.map +1 -1
  8. package/dist/extensions/backup.extension.d.ts +2 -7
  9. package/dist/extensions/backup.extension.js +5 -8
  10. package/dist/extensions/backup.extension.js.map +1 -1
  11. package/dist/extensions/call-proxy.extension.d.ts +1 -1
  12. package/dist/extensions/call-proxy.extension.js +3 -22
  13. package/dist/extensions/call-proxy.extension.js.map +1 -1
  14. package/dist/extensions/config.extension.d.ts +2 -6
  15. package/dist/extensions/config.extension.js +21 -25
  16. package/dist/extensions/config.extension.js.map +1 -1
  17. package/dist/extensions/conversation.extension.d.ts +2 -6
  18. package/dist/extensions/conversation.extension.js +5 -8
  19. package/dist/extensions/conversation.extension.js.map +1 -1
  20. package/dist/extensions/device.extension.d.ts +2 -5
  21. package/dist/extensions/device.extension.js +16 -22
  22. package/dist/extensions/device.extension.js.map +1 -1
  23. package/dist/extensions/entity.extension.d.ts +2 -61
  24. package/dist/extensions/entity.extension.js +42 -83
  25. package/dist/extensions/entity.extension.js.map +1 -1
  26. package/dist/extensions/events.extension.d.ts +3 -11
  27. package/dist/extensions/events.extension.js +8 -11
  28. package/dist/extensions/events.extension.js.map +1 -1
  29. package/dist/extensions/fetch-api.extension.d.ts +12 -4
  30. package/dist/extensions/fetch-api.extension.js +23 -35
  31. package/dist/extensions/fetch-api.extension.js.map +1 -1
  32. package/dist/extensions/floor.extension.d.ts +2 -9
  33. package/dist/extensions/floor.extension.js +17 -23
  34. package/dist/extensions/floor.extension.js.map +1 -1
  35. package/dist/extensions/id-by.extension.js +15 -20
  36. package/dist/extensions/id-by.extension.js.map +1 -1
  37. package/dist/extensions/index.d.ts +1 -0
  38. package/dist/extensions/index.js +16 -18
  39. package/dist/extensions/index.js.map +1 -1
  40. package/dist/extensions/internal.extension.d.ts +18 -0
  41. package/dist/extensions/internal.extension.js +102 -0
  42. package/dist/extensions/internal.extension.js.map +1 -0
  43. package/dist/extensions/label.extension.d.ts +2 -9
  44. package/dist/extensions/label.extension.js +17 -23
  45. package/dist/extensions/label.extension.js.map +1 -1
  46. package/dist/extensions/reference.extension.d.ts +2 -12
  47. package/dist/extensions/reference.extension.js +19 -25
  48. package/dist/extensions/reference.extension.js.map +1 -1
  49. package/dist/extensions/registry.extension.d.ts +2 -7
  50. package/dist/extensions/registry.extension.js +1 -4
  51. package/dist/extensions/registry.extension.js.map +1 -1
  52. package/dist/extensions/websocket-api.extension.d.ts +3 -78
  53. package/dist/extensions/websocket-api.extension.js +82 -165
  54. package/dist/extensions/websocket-api.extension.js.map +1 -1
  55. package/dist/extensions/zone.extension.d.ts +2 -7
  56. package/dist/extensions/zone.extension.js +15 -21
  57. package/dist/extensions/zone.extension.js.map +1 -1
  58. package/dist/hass.module.d.ts +47 -36
  59. package/dist/hass.module.js +70 -70
  60. package/dist/hass.module.js.map +1 -1
  61. package/dist/helpers/backup.helper.js +1 -2
  62. package/dist/helpers/constants.helper.js +15 -18
  63. package/dist/helpers/constants.helper.js.map +1 -1
  64. package/dist/helpers/device.helper.js +2 -5
  65. package/dist/helpers/device.helper.js.map +1 -1
  66. package/dist/helpers/entity-state.helper.d.ts +3 -8
  67. package/dist/helpers/entity-state.helper.js +1 -8
  68. package/dist/helpers/entity-state.helper.js.map +1 -1
  69. package/dist/helpers/features.helper.js +79 -85
  70. package/dist/helpers/features.helper.js.map +1 -1
  71. package/dist/helpers/fetch/calendar.js +1 -2
  72. package/dist/helpers/fetch/configuration.js +2 -5
  73. package/dist/helpers/fetch/configuration.js.map +1 -1
  74. package/dist/helpers/fetch/index.js +5 -8
  75. package/dist/helpers/fetch/index.js.map +1 -1
  76. package/dist/helpers/fetch/server-log.js +1 -2
  77. package/dist/helpers/fetch/server-log.js.map +1 -1
  78. package/dist/helpers/fetch/service-list.js +1 -2
  79. package/dist/helpers/fetch/weather-forecasts.js +1 -2
  80. package/dist/helpers/fetch/weather-forecasts.js.map +1 -1
  81. package/dist/helpers/fetch.helper.d.ts +162 -0
  82. package/dist/helpers/fetch.helper.js +161 -0
  83. package/dist/helpers/fetch.helper.js.map +1 -0
  84. package/dist/helpers/id-by.helper.js +1 -2
  85. package/dist/helpers/index.d.ts +2 -1
  86. package/dist/helpers/index.js +13 -15
  87. package/dist/helpers/index.js.map +1 -1
  88. package/dist/helpers/interfaces.helper.d.ts +228 -0
  89. package/dist/helpers/interfaces.helper.js +10 -0
  90. package/dist/helpers/interfaces.helper.js.map +1 -0
  91. package/dist/helpers/manifest.helper.d.ts +0 -1
  92. package/dist/helpers/manifest.helper.js +0 -1
  93. package/dist/helpers/notify.helper.d.ts +13 -5
  94. package/dist/helpers/notify.helper.js +1 -2
  95. package/dist/helpers/registry.js +7 -10
  96. package/dist/helpers/registry.js.map +1 -1
  97. package/dist/helpers/utility.helper.d.ts +6 -1
  98. package/dist/helpers/utility.helper.js +9 -13
  99. package/dist/helpers/utility.helper.js.map +1 -1
  100. package/dist/helpers/websocket.helper.d.ts +1 -2
  101. package/dist/helpers/websocket.helper.js +1 -2
  102. package/dist/index.js +5 -8
  103. package/dist/index.js.map +1 -1
  104. package/dist/mock_assistant/extensions/area.extension.d.ts +8 -0
  105. package/dist/mock_assistant/extensions/area.extension.js +51 -0
  106. package/dist/mock_assistant/extensions/area.extension.js.map +1 -0
  107. package/dist/mock_assistant/extensions/config.extension.d.ts +14 -0
  108. package/dist/mock_assistant/extensions/config.extension.js +29 -0
  109. package/dist/mock_assistant/extensions/config.extension.js.map +1 -0
  110. package/dist/mock_assistant/extensions/device.extension.d.ts +8 -0
  111. package/dist/mock_assistant/extensions/device.extension.js +33 -0
  112. package/dist/mock_assistant/extensions/device.extension.js.map +1 -0
  113. package/dist/mock_assistant/extensions/entity-registry.extension.d.ts +13 -0
  114. package/dist/mock_assistant/extensions/entity-registry.extension.js +28 -0
  115. package/dist/mock_assistant/extensions/entity-registry.extension.js.map +1 -0
  116. package/dist/mock_assistant/extensions/entity.extension.d.ts +30 -0
  117. package/dist/mock_assistant/extensions/entity.extension.js +77 -0
  118. package/dist/mock_assistant/extensions/entity.extension.js.map +1 -0
  119. package/dist/mock_assistant/extensions/events.extension.d.ts +1 -1
  120. package/dist/mock_assistant/extensions/events.extension.js +3 -6
  121. package/dist/mock_assistant/extensions/events.extension.js.map +1 -1
  122. package/dist/mock_assistant/extensions/fetch.extension.d.ts +1 -0
  123. package/dist/mock_assistant/extensions/fetch.extension.js +4 -0
  124. package/dist/mock_assistant/extensions/fetch.extension.js.map +1 -0
  125. package/dist/mock_assistant/extensions/fixtures.extension.d.ts +1 -1
  126. package/dist/mock_assistant/extensions/fixtures.extension.js +29 -33
  127. package/dist/mock_assistant/extensions/fixtures.extension.js.map +1 -1
  128. package/dist/mock_assistant/extensions/floor.extension.d.ts +8 -0
  129. package/dist/mock_assistant/extensions/floor.extension.js +51 -0
  130. package/dist/mock_assistant/extensions/floor.extension.js.map +1 -0
  131. package/dist/mock_assistant/extensions/index.d.ts +10 -0
  132. package/dist/mock_assistant/extensions/index.js +12 -5
  133. package/dist/mock_assistant/extensions/index.js.map +1 -1
  134. package/dist/mock_assistant/extensions/label.extension.d.ts +8 -0
  135. package/dist/mock_assistant/extensions/label.extension.js +51 -0
  136. package/dist/mock_assistant/extensions/label.extension.js.map +1 -0
  137. package/dist/mock_assistant/extensions/services.extension.d.ts +12 -0
  138. package/dist/mock_assistant/extensions/services.extension.js +20 -0
  139. package/dist/mock_assistant/extensions/services.extension.js.map +1 -0
  140. package/dist/mock_assistant/extensions/websocket-api.extension.d.ts +15 -0
  141. package/dist/mock_assistant/extensions/websocket-api.extension.js +68 -0
  142. package/dist/mock_assistant/extensions/websocket-api.extension.js.map +1 -0
  143. package/dist/mock_assistant/extensions/zone.extension.d.ts +8 -0
  144. package/dist/mock_assistant/extensions/zone.extension.js +51 -0
  145. package/dist/mock_assistant/extensions/zone.extension.js.map +1 -0
  146. package/dist/mock_assistant/helpers/fixtures.js +1 -2
  147. package/dist/mock_assistant/helpers/index.d.ts +0 -1
  148. package/dist/mock_assistant/helpers/index.js +1 -5
  149. package/dist/mock_assistant/helpers/index.js.map +1 -1
  150. package/dist/mock_assistant/index.js +3 -6
  151. package/dist/mock_assistant/index.js.map +1 -1
  152. package/dist/mock_assistant/main.js +11 -15
  153. package/dist/mock_assistant/main.js.map +1 -1
  154. package/dist/mock_assistant/mock-assistant.module.d.ts +156 -3
  155. package/dist/mock_assistant/mock-assistant.module.js +56 -11
  156. package/dist/mock_assistant/mock-assistant.module.js.map +1 -1
  157. package/dist/quickboot.module.js +5 -8
  158. package/dist/quickboot.module.js.map +1 -1
  159. package/dist/testing/area.spec.js +106 -194
  160. package/dist/testing/area.spec.js.map +1 -1
  161. package/dist/testing/backup.spec.js +97 -139
  162. package/dist/testing/backup.spec.js.map +1 -1
  163. package/dist/testing/config.spec.js +79 -153
  164. package/dist/testing/config.spec.js.map +1 -1
  165. package/dist/testing/device.spec.js +35 -69
  166. package/dist/testing/device.spec.js.map +1 -1
  167. package/dist/testing/entity.spec.js +94 -149
  168. package/dist/testing/entity.spec.js.map +1 -1
  169. package/dist/testing/events.spec.js +33 -57
  170. package/dist/testing/events.spec.js.map +1 -1
  171. package/dist/testing/fetch-api.spec.js +242 -427
  172. package/dist/testing/fetch-api.spec.js.map +1 -1
  173. package/dist/testing/fixtures.spec.d.ts +1 -0
  174. package/dist/testing/fixtures.spec.js +150 -0
  175. package/dist/testing/fixtures.spec.js.map +1 -0
  176. package/dist/testing/floor.spec.js +106 -194
  177. package/dist/testing/floor.spec.js.map +1 -1
  178. package/dist/testing/id-by.spec.js +68 -107
  179. package/dist/testing/id-by.spec.js.map +1 -1
  180. package/dist/testing/label.spec.js +106 -194
  181. package/dist/testing/label.spec.js.map +1 -1
  182. package/dist/testing/ref-by.spec.js +155 -219
  183. package/dist/testing/ref-by.spec.js.map +1 -1
  184. package/dist/testing/websocket.spec.d.ts +1 -8
  185. package/dist/testing/websocket.spec.js +35 -50
  186. package/dist/testing/websocket.spec.js.map +1 -1
  187. package/dist/testing/workflow.spec.js +82 -81
  188. package/dist/testing/workflow.spec.js.map +1 -1
  189. package/dist/testing/zone.spec.js +61 -113
  190. package/dist/testing/zone.spec.js.map +1 -1
  191. package/package.json +62 -44
  192. package/scripts/mock-assistant.sh +5 -0
  193. package/scripts/run-e2e.sh +7 -0
  194. package/scripts/test.sh +2 -0
  195. package/src/dynamic.ts +4254 -0
  196. package/src/extensions/area.extension.ts +118 -0
  197. package/src/extensions/backup.extension.ts +63 -0
  198. package/src/extensions/call-proxy.extension.ts +113 -0
  199. package/src/extensions/config.extension.ts +119 -0
  200. package/src/extensions/conversation.extension.ts +46 -0
  201. package/src/extensions/device.extension.ts +56 -0
  202. package/src/extensions/entity.extension.ts +344 -0
  203. package/src/extensions/events.extension.ts +25 -0
  204. package/src/extensions/fetch-api.extension.ts +269 -0
  205. package/src/extensions/floor.extension.ts +76 -0
  206. package/src/extensions/id-by.extension.ts +157 -0
  207. package/src/extensions/index.ts +16 -0
  208. package/src/extensions/internal.extension.ts +145 -0
  209. package/src/extensions/label.extension.ts +83 -0
  210. package/src/extensions/reference.extension.ts +330 -0
  211. package/src/extensions/registry.extension.ts +44 -0
  212. package/src/extensions/websocket-api.extension.ts +554 -0
  213. package/src/extensions/zone.extension.ts +69 -0
  214. package/src/hass.module.ts +217 -0
  215. package/src/helpers/backup.helper.ts +11 -0
  216. package/src/helpers/constants.helper.ts +30 -0
  217. package/src/helpers/device.helper.ts +25 -0
  218. package/src/helpers/entity-state.helper.ts +171 -0
  219. package/src/helpers/features.helper.ts +580 -0
  220. package/src/helpers/fetch/calendar.ts +54 -0
  221. package/src/helpers/fetch/configuration.ts +75 -0
  222. package/src/helpers/fetch/index.ts +5 -0
  223. package/src/helpers/fetch/server-log.ts +28 -0
  224. package/src/helpers/fetch/service-list.ts +64 -0
  225. package/src/helpers/fetch/weather-forecasts.ts +86 -0
  226. package/src/helpers/fetch.helper.ts +328 -0
  227. package/src/helpers/id-by.helper.ts +53 -0
  228. package/src/helpers/index.ts +13 -0
  229. package/src/helpers/interfaces.helper.ts +340 -0
  230. package/src/helpers/manifest.helper.ts +0 -0
  231. package/src/helpers/notify.helper.ts +302 -0
  232. package/src/helpers/registry.ts +281 -0
  233. package/src/helpers/utility.helper.ts +147 -0
  234. package/src/helpers/websocket.helper.ts +117 -0
  235. package/src/index.ts +5 -0
  236. package/src/mock_assistant/extensions/area.extension.ts +62 -0
  237. package/src/mock_assistant/extensions/config.extension.ts +33 -0
  238. package/src/mock_assistant/extensions/device.extension.ts +44 -0
  239. package/src/mock_assistant/extensions/entity-registry.extension.ts +41 -0
  240. package/src/mock_assistant/extensions/entity.extension.ts +114 -0
  241. package/src/mock_assistant/extensions/events.extension.ts +37 -0
  242. package/src/mock_assistant/extensions/fetch.extension.ts +3 -0
  243. package/src/mock_assistant/extensions/fixtures.extension.ts +79 -0
  244. package/src/mock_assistant/extensions/floor.extension.ts +64 -0
  245. package/src/mock_assistant/extensions/index.ts +12 -0
  246. package/src/mock_assistant/extensions/label.extension.ts +64 -0
  247. package/src/mock_assistant/extensions/services.extension.ts +25 -0
  248. package/src/mock_assistant/extensions/websocket-api.extension.ts +84 -0
  249. package/src/mock_assistant/extensions/zone.extension.ts +65 -0
  250. package/src/mock_assistant/helpers/fixtures.ts +22 -0
  251. package/src/mock_assistant/helpers/index.ts +1 -0
  252. package/src/mock_assistant/index.ts +3 -0
  253. package/src/mock_assistant/main.ts +46 -0
  254. package/src/mock_assistant/mock-assistant.module.ts +90 -0
  255. package/src/quickboot.module.ts +23 -0
  256. package/src/testing/area.spec.ts +189 -0
  257. package/src/testing/backup.spec.ts +157 -0
  258. package/src/testing/config.spec.ts +188 -0
  259. package/src/testing/device.spec.ts +89 -0
  260. package/src/testing/entity.spec.ts +171 -0
  261. package/src/testing/events.spec.ts +78 -0
  262. package/src/testing/fetch-api.spec.ts +410 -0
  263. package/src/testing/fixtures.spec.ts +158 -0
  264. package/src/testing/floor.spec.ts +186 -0
  265. package/src/testing/id-by.spec.ts +140 -0
  266. package/src/testing/label.spec.ts +186 -0
  267. package/src/testing/ref-by.spec.ts +300 -0
  268. package/src/testing/websocket.spec.ts +63 -0
  269. package/src/testing/workflow.spec.ts +195 -0
  270. package/src/testing/zone.spec.ts +109 -0
  271. package/dist/helpers/metrics.helper.d.ts +0 -29
  272. package/dist/helpers/metrics.helper.js +0 -62
  273. package/dist/helpers/metrics.helper.js.map +0 -1
  274. package/dist/mock_assistant/helpers/utils.d.ts +0 -4
  275. package/dist/mock_assistant/helpers/utils.js +0 -57
  276. package/dist/mock_assistant/helpers/utils.js.map +0 -1
@@ -0,0 +1,89 @@
1
+ import { sleep } from "@digital-alchemy/core";
2
+
3
+ import { DeviceDetails } from "../helpers";
4
+ import { hassTestRunner } from "../mock_assistant";
5
+
6
+ describe("Device", () => {
7
+ const EXAMPLE_DEVICE = {
8
+ area_id: null,
9
+ config_entries: ["42816b768aa8697c18c1b6d241112cef"],
10
+ configuration_url: null,
11
+ connections: [],
12
+ disabled_by: null,
13
+ entry_type: "service",
14
+ hw_version: null,
15
+ id: "e328cb3f7ec4e37b3b102374b05c37a9",
16
+ identifiers: [["hassio", "core"]],
17
+ labels: [],
18
+ manufacturer: "Home Assistant",
19
+ model: "Home Assistant Core",
20
+ name: "Home Assistant Core",
21
+ name_by_user: null,
22
+ serial_number: null,
23
+ sw_version: "2024.4.3",
24
+ via_device_id: null,
25
+ } as unknown as DeviceDetails;
26
+
27
+ afterEach(async () => {
28
+ await hassTestRunner.teardown();
29
+ jest.restoreAllMocks();
30
+ });
31
+
32
+ describe("Lifecycle", () => {
33
+ it("should force values to be available before ready", async () => {
34
+ expect.assertions(1);
35
+ await hassTestRunner.run(({ lifecycle, hass }) => {
36
+ const spy = jest
37
+ .spyOn(hass.socket, "sendMessage")
38
+ .mockImplementation(async () => [EXAMPLE_DEVICE]);
39
+ lifecycle.onReady(async () => {
40
+ await hass.device.list();
41
+ expect(spy).toHaveBeenCalledWith(
42
+ expect.objectContaining({ type: "config/device_registry/list" }),
43
+ );
44
+ });
45
+ });
46
+ });
47
+ });
48
+
49
+ it("should debounce updates properly", async () => {
50
+ expect.assertions(1);
51
+ await hassTestRunner.run(({ lifecycle, hass }) => {
52
+ jest.spyOn(hass.socket, "sendMessage").mockImplementation(async () => undefined);
53
+ let counter = 0;
54
+ hass.events.onDeviceRegistryUpdate(() => counter++);
55
+ lifecycle.onReady(async () => {
56
+ setImmediate(async () => {
57
+ hass.socket.socketEvents.emit("device_registry_updated");
58
+ await sleep(5);
59
+ hass.socket.socketEvents.emit("device_registry_updated");
60
+ await sleep(5);
61
+ hass.socket.socketEvents.emit("device_registry_updated");
62
+ await sleep(75);
63
+ hass.socket.socketEvents.emit("device_registry_updated");
64
+ });
65
+ await sleep(200);
66
+ expect(counter).toBe(2);
67
+ });
68
+ });
69
+ });
70
+
71
+ describe("API", () => {
72
+ describe("Formatting", () => {
73
+ it("should call list properly", async () => {
74
+ expect.assertions(1);
75
+ await hassTestRunner.run(({ lifecycle, hass }) => {
76
+ const spy = jest.spyOn(hass.socket, "sendMessage").mockImplementation(async () => []);
77
+ lifecycle.onReady(async () => {
78
+ await hass.device.list();
79
+ expect(spy).toHaveBeenCalledWith(
80
+ expect.objectContaining({
81
+ type: "config/device_registry/list",
82
+ }),
83
+ );
84
+ });
85
+ });
86
+ });
87
+ });
88
+ });
89
+ });
@@ -0,0 +1,171 @@
1
+ import { sleep } from "@digital-alchemy/core";
2
+
3
+ import { ANY_ENTITY, ENTITY_STATE } from "../helpers";
4
+ import { hassTestRunner } from "../mock_assistant";
5
+
6
+ describe("Entity", () => {
7
+ afterEach(async () => {
8
+ await hassTestRunner.teardown();
9
+ jest.restoreAllMocks();
10
+ });
11
+
12
+ describe("API", () => {
13
+ describe("Updates", () => {
14
+ xit("should debounce updates properly", async () => {
15
+ expect.assertions(1);
16
+ await new Promise<void>(async done => {
17
+ await hassTestRunner.run(({ hass }) => {
18
+ const spy = jest.fn();
19
+ hass.events.onEntityRegistryUpdate(spy);
20
+ hass.socket.onConnect(async () => {
21
+ setImmediate(async () => {
22
+ hass.socket.socketEvents.emit("entity_registry_updated");
23
+ await sleep(5);
24
+ hass.socket.socketEvents.emit("entity_registry_updated");
25
+ await sleep(5);
26
+ hass.socket.socketEvents.emit("entity_registry_updated");
27
+ await sleep(20);
28
+ hass.socket.socketEvents.emit("entity_registry_updated");
29
+ });
30
+ await sleep(50);
31
+ expect(spy).toHaveReturnedTimes(2);
32
+ done();
33
+ });
34
+ });
35
+ });
36
+ });
37
+
38
+ it("should emit updates on change", async () => {
39
+ expect.assertions(3);
40
+ await hassTestRunner.run(({ lifecycle, hass, event }) => {
41
+ lifecycle.onReady(() => {
42
+ const old_state = hass.entity.getCurrentState("sensor.magic");
43
+ const new_state = { ...old_state, state: "test" };
44
+ const spy = jest.spyOn(event, "emit");
45
+ hass.entity._entityUpdateReceiver("sensor.magic", new_state, old_state);
46
+ expect(spy).toHaveReturnedTimes(2);
47
+ expect(spy).toHaveBeenCalledWith("sensor.magic", new_state, old_state);
48
+ expect(spy).toHaveBeenCalledWith(
49
+ "e1806fdc93296bbd5ab42967003cd38729ff9ba6cfeefc3e15a03ad01ac894fe",
50
+ new_state,
51
+ old_state,
52
+ );
53
+ });
54
+ });
55
+ });
56
+
57
+ it("returns undefined from nextState when timeout is exceeded", async () => {
58
+ expect.assertions(1);
59
+ await hassTestRunner.run(({ lifecycle, hass }) => {
60
+ lifecycle.onReady(async () => {
61
+ const entity = hass.refBy.id("sensor.magic");
62
+ const old_state = hass.entity.getCurrentState("sensor.magic");
63
+
64
+ // Set a timeout of 100ms
65
+ const wait = new Promise<ENTITY_STATE<ANY_ENTITY> | undefined>(async done => {
66
+ done(await entity.nextState(25));
67
+ });
68
+
69
+ // Simulate delay longer than the timeout to ensure timeout is exceeded
70
+ setTimeout(() => {
71
+ const new_state = { ...old_state, state: "test" };
72
+ hass.entity._entityUpdateReceiver("sensor.magic", new_state, old_state);
73
+ }, 50); // 200ms delay
74
+
75
+ const result = await wait;
76
+ expect(result).toBeUndefined();
77
+ });
78
+ });
79
+ });
80
+ });
81
+
82
+ it("should find entities by unique_id", async () => {
83
+ expect.assertions(2);
84
+ await hassTestRunner.run(({ lifecycle, hass }) => {
85
+ lifecycle.onReady(() => {
86
+ const entity = hass.refBy.unique_id("5622d76001a335e3ea893c4d60d31b3d-next_dawn");
87
+ expect(entity).toBeDefined();
88
+ expect(entity.entity_id).toBe("sensor.sun_next_dawn");
89
+ });
90
+ });
91
+ });
92
+
93
+ it("should return unmodified entity state with .raw", async () => {
94
+ expect.assertions(1);
95
+ await hassTestRunner.run(({ lifecycle, hass }) => {
96
+ lifecycle.onReady(() => {
97
+ const allData = hass.entity._masterState();
98
+ const single = hass.entity.getCurrentState("sun.sun");
99
+ expect(single).toBe(allData.sun.sun);
100
+ });
101
+ });
102
+ });
103
+
104
+ it("should return previous entity state with .previous", async () => {
105
+ expect.assertions(3);
106
+ await hassTestRunner.run(({ lifecycle, hass, mock_assistant }) => {
107
+ const entity_id = "sensor.magic";
108
+ const value = "bar";
109
+ lifecycle.onReady(async () => {
110
+ const start = hass.entity.getCurrentState(entity_id);
111
+ await mock_assistant.events.emitEntityUpdate(entity_id, {
112
+ state: value,
113
+ });
114
+ const updated = hass.entity.getCurrentState(entity_id);
115
+ const previous = hass.entity.previousState(entity_id);
116
+ expect(updated.state).toBe(value);
117
+ expect(start.state).not.toBe(value);
118
+ expect(start).toEqual(previous);
119
+ });
120
+ });
121
+ });
122
+
123
+ it("should return undefined for no matches", async () => {
124
+ expect.assertions(1);
125
+ await hassTestRunner.run(({ lifecycle, hass }) => {
126
+ lifecycle.onReady(() => {
127
+ const entity = hass.refBy.unique_id(
128
+ // @ts-expect-error test
129
+ "5622d76001a335e3ea893c4d60d31b3d-previous_dawn",
130
+ );
131
+ expect(entity).not.toBeDefined();
132
+ });
133
+ });
134
+ });
135
+ });
136
+
137
+ describe("Refresh", () => {
138
+ it("should attempt to load entities onBootstrap", async () => {
139
+ expect.assertions(2);
140
+ await hassTestRunner.run(({ lifecycle, hass }) => {
141
+ const spy = jest.spyOn(hass.entity, "refresh").mockImplementation(async () => undefined);
142
+
143
+ lifecycle.onPostConfig(function latePostConfig() {
144
+ expect(spy).toHaveBeenCalled();
145
+ }, -1);
146
+ lifecycle.onPostConfig(function earlyPostConfig() {
147
+ expect(spy).not.toHaveBeenCalled();
148
+ }, 0);
149
+ });
150
+ });
151
+
152
+ it("should retry on failure", async () => {
153
+ expect.assertions(1);
154
+ await hassTestRunner.configure({ hass: { RETRY_INTERVAL: 0 } }).run(({ lifecycle, hass }) => {
155
+ const responses = [
156
+ { text: "502 Bad Gateway" },
157
+ { text: "502 Bad Gateway" },
158
+ { text: "502 Bad Gateway" },
159
+ [],
160
+ [{ entity_id: "sensor.magic" } as ENTITY_STATE<ANY_ENTITY>],
161
+ ];
162
+ const spy = jest
163
+ .spyOn(hass.fetch, "getAllEntities")
164
+ // @ts-expect-error it happens
165
+ .mockImplementation(async () => responses.shift());
166
+
167
+ lifecycle.onBootstrap(() => expect(spy).toHaveBeenCalledTimes(5));
168
+ });
169
+ });
170
+ });
171
+ });
@@ -0,0 +1,78 @@
1
+ import {
2
+ AREA_REGISTRY_UPDATED,
3
+ DEVICE_REGISTRY_UPDATED,
4
+ ENTITY_REGISTRY_UPDATED,
5
+ FLOOR_REGISTRY_UPDATED,
6
+ LABEL_REGISTRY_UPDATED,
7
+ ZONE_REGISTRY_UPDATED,
8
+ } from "../helpers";
9
+ import { hassTestRunner } from "../mock_assistant";
10
+
11
+ describe("Events", () => {
12
+ afterEach(async () => {
13
+ await hassTestRunner.teardown();
14
+ jest.restoreAllMocks();
15
+ });
16
+
17
+ describe("Event Callbacks", () => {
18
+ it("should register callback for AREA_REGISTRY_UPDATED", async () => {
19
+ expect.assertions(1);
20
+ await hassTestRunner.run(({ event, hass }) => {
21
+ const spy = jest.spyOn(event, "on");
22
+ const callback = jest.fn();
23
+ hass.events.onAreaRegistryUpdate(callback);
24
+ expect(spy).toHaveBeenCalledWith(AREA_REGISTRY_UPDATED, callback);
25
+ });
26
+ });
27
+
28
+ it("should register callback for DEVICE_REGISTRY_UPDATED", async () => {
29
+ expect.assertions(1);
30
+ await hassTestRunner.run(({ event, hass }) => {
31
+ const spy = jest.spyOn(event, "on");
32
+ const callback = jest.fn();
33
+ hass.events.onDeviceRegistryUpdate(callback);
34
+ expect(spy).toHaveBeenCalledWith(DEVICE_REGISTRY_UPDATED, callback);
35
+ });
36
+ });
37
+
38
+ it("should register callback for ENTITY_REGISTRY_UPDATED", async () => {
39
+ expect.assertions(1);
40
+ await hassTestRunner.run(({ event, hass }) => {
41
+ const spy = jest.spyOn(event, "on");
42
+ const callback = jest.fn();
43
+ hass.events.onEntityRegistryUpdate(callback);
44
+ expect(spy).toHaveBeenCalledWith(ENTITY_REGISTRY_UPDATED, callback);
45
+ });
46
+ });
47
+
48
+ it("should register callback for FLOOR_REGISTRY_UPDATED", async () => {
49
+ expect.assertions(1);
50
+ await hassTestRunner.run(({ event, hass }) => {
51
+ const spy = jest.spyOn(event, "on");
52
+ const callback = jest.fn();
53
+ hass.events.onFloorRegistryUpdate(callback);
54
+ expect(spy).toHaveBeenCalledWith(FLOOR_REGISTRY_UPDATED, callback);
55
+ });
56
+ });
57
+
58
+ it("should register callback for LABEL_REGISTRY_UPDATED", async () => {
59
+ expect.assertions(1);
60
+ await hassTestRunner.run(({ event, hass }) => {
61
+ const spy = jest.spyOn(event, "on");
62
+ const callback = jest.fn();
63
+ hass.events.onLabelRegistryUpdate(callback);
64
+ expect(spy).toHaveBeenCalledWith(LABEL_REGISTRY_UPDATED, callback);
65
+ });
66
+ });
67
+
68
+ it("should register callback for ZONE_REGISTRY_UPDATED", async () => {
69
+ expect.assertions(1);
70
+ await hassTestRunner.run(({ event, hass }) => {
71
+ const spy = jest.spyOn(event, "on");
72
+ const callback = jest.fn();
73
+ hass.events.onZoneRegistryUpdate(callback);
74
+ expect(spy).toHaveBeenCalledWith(ZONE_REGISTRY_UPDATED, callback);
75
+ });
76
+ });
77
+ });
78
+ });