11using System . Net ;
22using System . Reactive . Subjects ;
33using Microsoft . Extensions . DependencyInjection ;
4+ using Microsoft . Extensions . Hosting ;
45using NetDaemon . AppModel ;
56using NetDaemon . Client . Internal . Exceptions ;
67using NetDaemon . HassModel ;
@@ -21,6 +22,7 @@ public async Task TestGetStateAsyncReturnsCorrectStateEnabled()
2122
2223 var provider = new ServiceCollection ( )
2324 . AddSingleton ( haRunnerMock . Object )
25+ . AddSingleton ( new Mock < IHostEnvironment > ( ) . Object )
2426 . AddNetDaemonStateManager ( )
2527 . BuildServiceProvider ( ) ;
2628 using var scopedProvider = provider . CreateScope ( ) ;
@@ -44,17 +46,9 @@ public async Task TestGetStateAsyncReturnsCorrectStateEnabled()
4446 public async Task TestGetStateAsyncReturnsCorrectStateDisabled ( )
4547 {
4648 // ARRANGE
47- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
48- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
49- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
50-
51- var provider = new ServiceCollection ( )
52- . AddSingleton ( haRunnerMock . Object )
53- . AddNetDaemonStateManager ( )
54- . BuildServiceProvider ( ) ;
55- using var scopedProvider = provider . CreateScope ( ) ;
49+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
5650
57- var appStateManager = scopedProvider . ServiceProvider . GetRequiredService < IAppStateManager > ( ) ;
51+ var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
5852
5953 // ACT
6054 // ASSERT
@@ -73,16 +67,9 @@ public async Task TestGetStateAsyncReturnsCorrectStateDisabled()
7367 public async Task TestSaveStateAsyncReturnsCorrectStateDisabled ( )
7468 {
7569 // ARRANGE
76- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
77- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
78- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
79-
80- var provider = new ServiceCollection ( )
81- . AddSingleton ( haRunnerMock . Object )
82- . AddNetDaemonStateManager ( )
83- . BuildServiceProvider ( ) ;
70+ var ( haConnectionMock , scopedProvider ) = SetupProviderAndMocks ( ) ;
8471
85- var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
72+ var appStateManager = scopedProvider . GetRequiredService < IAppStateManager > ( ) ;
8673 haConnectionMock . Setup ( n => n . GetApiCallAsync < HassState > ( It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
8774 . ReturnsAsync (
8875 new HassState
@@ -106,14 +93,7 @@ public async Task TestSaveStateAsyncReturnsCorrectStateDisabled()
10693 public async Task TestGetStateAsyncNotExistReturnsCorrectStateEnabled ( )
10794 {
10895 // ARRANGE
109- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
110- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
111- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
112-
113- var provider = new ServiceCollection ( )
114- . AddSingleton ( haRunnerMock . Object )
115- . AddNetDaemonStateManager ( )
116- . BuildServiceProvider ( ) ;
96+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
11797
11898 var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
11999 haConnectionMock . Setup ( n => n . GetApiCallAsync < HassState > ( It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
@@ -134,17 +114,34 @@ public async Task TestGetStateAsyncNotExistReturnsCorrectStateEnabled()
134114 }
135115
136116 [ Fact ]
137- public async Task TestSetStateAsyncEnabled ( )
117+ public async Task TestGetStateAsyncNotExistReturnsCorrectStateEnabledInDevelopment ( )
138118 {
139119 // ARRANGE
140- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
141- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
142- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
120+ var ( haConnectionMock , provider ) = SetupProviderAndMocksDevelopment ( ) ;
143121
144- var provider = new ServiceCollection ( )
145- . AddSingleton ( haRunnerMock . Object )
146- . AddNetDaemonStateManager ( )
147- . BuildServiceProvider ( ) ;
122+ var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
123+ haConnectionMock . Setup ( n => n . GetApiCallAsync < HassState > ( It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
124+ . ThrowsAsync (
125+ new HomeAssistantApiCallException ( "ohh no" , HttpStatusCode . NotFound ) ) ;
126+ // ACT
127+ _ = await appStateManager . GetStateAsync ( "helloapp" ) ;
128+ // ASSERT
129+ haConnectionMock . Verify ( n =>
130+ n . GetApiCallAsync < HassState > ( "states/input_boolean.dev_netdaemon_helloapp" , It . IsAny < CancellationToken > ( ) ) ) ;
131+ // It exists so it should turn it on
132+ haConnectionMock . Verify ( n =>
133+ n . SendCommandAndReturnResponseAsync < CreateInputBooleanHelperCommand , InputBooleanHelper > (
134+ It . IsAny < CreateInputBooleanHelperCommand > ( ) , It . IsAny < CancellationToken > ( ) ) ) ;
135+ haConnectionMock . Verify ( n =>
136+ n . SendCommandAndReturnResponseAsync < CallServiceCommand , object > ( It . IsAny < CallServiceCommand > ( ) ,
137+ It . IsAny < CancellationToken > ( ) ) ) ;
138+ }
139+
140+ [ Fact ]
141+ public async Task TestSetStateAsyncEnabled ( )
142+ {
143+ // ARRANGE
144+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
148145
149146 var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
150147 haConnectionMock . Setup ( n => n . GetApiCallAsync < HassState > ( It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
@@ -170,14 +167,7 @@ public async Task TestSetStateAsyncEnabled()
170167 public async Task TestSetStateAsyncRunning ( )
171168 {
172169 // ARRANGE
173- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
174- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
175- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
176-
177- var provider = new ServiceCollection ( )
178- . AddSingleton ( haRunnerMock . Object )
179- . AddNetDaemonStateManager ( )
180- . BuildServiceProvider ( ) ;
170+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
181171
182172 var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
183173 haConnectionMock . Setup ( n => n . GetApiCallAsync < HassState > ( It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
@@ -200,17 +190,9 @@ public async Task TestSetStateAsyncRunning()
200190 public async Task TestSetStateAsyncError ( )
201191 {
202192 // ARRANGE
203- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
204- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
205- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
193+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
206194
207- var provider = new ServiceCollection ( )
208- . AddSingleton ( haRunnerMock . Object )
209- . AddNetDaemonStateManager ( )
210- . BuildServiceProvider ( ) ;
211- using var scopedProvider = provider . CreateScope ( ) ;
212-
213- var appStateManager = scopedProvider . ServiceProvider . GetRequiredService < IAppStateManager > ( ) ;
195+ var appStateManager = provider . GetRequiredService < IAppStateManager > ( ) ;
214196
215197 haConnectionMock . Setup ( n => n . GetApiCallAsync < HassState > ( It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
216198 . ReturnsAsync (
@@ -233,15 +215,22 @@ public async Task TestInitialize()
233215 // ARRANGE
234216 var haContextMock = new Mock < IHaContext > ( ) ;
235217 var appModelContextMock = new Mock < IAppModelContext > ( ) ;
236- appModelContextMock . SetupGet ( n => n . Applications ) . Returns ( new List < IApplication > ( ) ) ;
218+ appModelContextMock . SetupGet ( n => n . Applications )
219+ . Returns ( new List < IApplication > ( ) { new Mock < IApplication > ( ) . Object } ) ;
220+
237221 var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
222+
238223 var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
239224 haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
240225
226+ var repositoryMock = new Mock < IAppStateRepository > ( ) ;
227+
241228 var provider = new ServiceCollection ( )
242229 . AddSingleton ( haRunnerMock . Object )
243230 . AddScoped ( _ => haContextMock . Object )
231+ . AddSingleton ( new Mock < IHostEnvironment > ( ) . Object )
244232 . AddNetDaemonStateManager ( )
233+ . AddSingleton ( repositoryMock . Object )
245234 . BuildServiceProvider ( ) ;
246235 using var scopedProvider = provider . CreateScope ( ) ;
247236
@@ -255,29 +244,58 @@ await homeAssistantStateUpdater.InitializeAsync(haConnectionMock.Object, appMode
255244 . ConfigureAwait ( false ) ;
256245 // ASSERT
257246 hassEvent . HasObservers . Should ( ) . BeTrue ( ) ;
247+ repositoryMock . Verify ( n => n . RemoveNotUsedStatesAsync ( It . IsAny < IReadOnlyCollection < string > > ( ) , It . IsAny < CancellationToken > ( ) ) , Times . Once ) ;
258248 }
259249
260250 [ Fact ]
261- public async Task TestAppDisabledShouldCallSetStateAsyncEnabled ( )
251+ public async Task InitializeShouldNeverTryDeleteUnusedInputBooleanHelpersWhenInDevelopmentEnvironment ( )
262252 {
263253 // ARRANGE
264254 var haContextMock = new Mock < IHaContext > ( ) ;
265255 var appModelContextMock = new Mock < IAppModelContext > ( ) ;
266- appModelContextMock . SetupGet ( n => n . Applications ) . Returns ( new List < IApplication > ( ) ) ;
267- var appMock = new Mock < IApplication > ( ) ;
256+ // Make sure we have at least one application for this scenario
257+ appModelContextMock . SetupGet ( n => n . Applications )
258+ . Returns ( new List < IApplication > ( ) { new Mock < IApplication > ( ) . Object } ) ;
268259 var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
260+ haConnectionMock . SetupGet ( n => n . OnHomeAssistantEvent ) . Returns ( new Subject < HassEvent > ( ) ) ;
269261 var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
270262 haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
271263
264+ var environmentMock = new Mock < IHostEnvironment > ( ) ;
265+ environmentMock . Setup ( n => n . EnvironmentName ) . Returns ( "Development" ) ;
266+ var repositoryMock = new Mock < IAppStateRepository > ( ) ;
267+
272268 var provider = new ServiceCollection ( )
273269 . AddSingleton ( haRunnerMock . Object )
274270 . AddScoped ( _ => haContextMock . Object )
271+ . AddSingleton ( environmentMock . Object )
275272 . AddNetDaemonStateManager ( )
273+ . AddSingleton ( repositoryMock . Object )
276274 . BuildServiceProvider ( ) ;
277275 using var scopedProvider = provider . CreateScope ( ) ;
278276
279277 var homeAssistantStateUpdater =
280278 scopedProvider . ServiceProvider . GetRequiredService < IHandleHomeAssistantAppStateUpdates > ( ) ;
279+
280+ // ACT
281+ await homeAssistantStateUpdater . InitializeAsync ( haConnectionMock . Object , appModelContextMock . Object )
282+ . ConfigureAwait ( false ) ;
283+ // ASSERT
284+ repositoryMock . Verify ( n => n . RemoveNotUsedStatesAsync ( It . IsAny < IReadOnlyCollection < string > > ( ) , It . IsAny < CancellationToken > ( ) ) , Times . Never ) ;
285+
286+ }
287+
288+ [ Fact ]
289+ public async Task TestAppDisabledShouldCallSetStateAsyncEnabled ( )
290+ {
291+ // ARRANGE
292+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
293+ var appModelContextMock = new Mock < IAppModelContext > ( ) ;
294+ appModelContextMock . SetupGet ( n => n . Applications ) . Returns ( new List < IApplication > ( ) ) ;
295+ var appMock = new Mock < IApplication > ( ) ;
296+
297+ var homeAssistantStateUpdater =
298+ provider . GetRequiredService < IHandleHomeAssistantAppStateUpdates > ( ) ;
281299 Subject < HassEvent > hassEvent = new ( ) ;
282300 haConnectionMock . SetupGet ( n => n . OnHomeAssistantEvent ) . Returns ( hassEvent ) ;
283301 appMock . SetupGet ( n => n . Id ) . Returns ( "app" ) ;
@@ -317,24 +335,18 @@ await homeAssistantStateUpdater.InitializeAsync(haConnectionMock.Object, appMode
317335 public async Task TestAppNoChangeShouldNotCallSetStateAsync ( )
318336 {
319337 // ARRANGE
320- var haContextMock = new Mock < IHaContext > ( ) ;
338+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
339+
340+ var homeAssistantStateUpdater =
341+ provider . GetRequiredService < IHandleHomeAssistantAppStateUpdates > ( ) ;
342+
343+ Subject < HassEvent > hassEvent = new ( ) ;
344+
321345 var appModelContextMock = new Mock < IAppModelContext > ( ) ;
322346 appModelContextMock . SetupGet ( n => n . Applications ) . Returns ( new List < IApplication > ( ) ) ;
323- var appMock = new Mock < IApplication > ( ) ;
324- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
325- var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
326- haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
327347
328- var provider = new ServiceCollection ( )
329- . AddSingleton ( haRunnerMock . Object )
330- . AddScoped ( _ => haContextMock . Object )
331- . AddNetDaemonStateManager ( )
332- . BuildServiceProvider ( ) ;
333- using var scopedProvider = provider . CreateScope ( ) ;
348+ var appMock = new Mock < IApplication > ( ) ;
334349
335- var homeAssistantStateUpdater =
336- scopedProvider . ServiceProvider . GetRequiredService < IHandleHomeAssistantAppStateUpdates > ( ) ;
337- Subject < HassEvent > hassEvent = new ( ) ;
338350 haConnectionMock . SetupGet ( n => n . OnHomeAssistantEvent ) . Returns ( hassEvent ) ;
339351 appMock . SetupGet ( n => n . Id ) . Returns ( "app" ) ;
340352 appModelContextMock . SetupGet ( n => n . Applications ) . Returns (
@@ -374,23 +386,19 @@ await homeAssistantStateUpdater.InitializeAsync(haConnectionMock.Object, appMode
374386 public async Task TestAppOneStateIsNullShouldNotCallSetStateAsync ( )
375387 {
376388 // ARRANGE
377- var haContextMock = new Mock < IHaContext > ( ) ;
389+ var ( haConnectionMock , provider ) = SetupProviderAndMocks ( ) ;
390+
378391 var appModelContextMock = new Mock < IAppModelContext > ( ) ;
379392 appModelContextMock . SetupGet ( n => n . Applications ) . Returns ( new List < IApplication > ( ) ) ;
393+
380394 var appMock = new Mock < IApplication > ( ) ;
381- var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
395+
382396 var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
383397 haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
384398
385- var provider = new ServiceCollection ( )
386- . AddSingleton ( haRunnerMock . Object )
387- . AddScoped ( _ => haContextMock . Object )
388- . AddNetDaemonStateManager ( )
389- . BuildServiceProvider ( ) ;
390- using var scopedProvider = provider . CreateScope ( ) ;
391399
392400 var homeAssistantStateUpdater =
393- scopedProvider . ServiceProvider . GetRequiredService < IHandleHomeAssistantAppStateUpdates > ( ) ;
401+ provider . GetRequiredService < IHandleHomeAssistantAppStateUpdates > ( ) ;
394402 Subject < HassEvent > hassEvent = new ( ) ;
395403 haConnectionMock . SetupGet ( n => n . OnHomeAssistantEvent ) . Returns ( hassEvent ) ;
396404 appMock . SetupGet ( n => n . Id ) . Returns ( "app" ) ;
@@ -419,4 +427,37 @@ public async Task TestAppOneStateIsNullShouldNotCallSetStateAsync()
419427 // ASSERT
420428 appMock . Verify ( n => n . SetStateAsync ( ApplicationState . Disabled ) , Times . Never ) ;
421429 }
430+
431+ private ( Mock < IHomeAssistantConnection > connection , IServiceProvider serviceProvider ) SetupProviderAndMocks ( )
432+ {
433+ var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
434+ var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
435+ haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
436+
437+ var provider = new ServiceCollection ( )
438+ . AddSingleton ( haRunnerMock . Object )
439+ . AddSingleton ( new Mock < IHostEnvironment > ( ) . Object )
440+ . AddNetDaemonStateManager ( )
441+ . BuildServiceProvider ( ) ;
442+ var scopedProvider = provider . CreateScope ( ) ;
443+
444+ return ( haConnectionMock , scopedProvider . ServiceProvider ) ;
445+ }
446+
447+ private ( Mock < IHomeAssistantConnection > connection , IServiceProvider serviceProvider ) SetupProviderAndMocksDevelopment ( )
448+ {
449+ var haConnectionMock = new Mock < IHomeAssistantConnection > ( ) ;
450+ var haRunnerMock = new Mock < IHomeAssistantRunner > ( ) ;
451+ haRunnerMock . SetupGet ( n => n . CurrentConnection ) . Returns ( haConnectionMock . Object ) ;
452+ var environmentMock = new Mock < IHostEnvironment > ( ) ;
453+ environmentMock . Setup ( n => n . EnvironmentName ) . Returns ( "Development" ) ;
454+ var provider = new ServiceCollection ( )
455+ . AddSingleton ( haRunnerMock . Object )
456+ . AddSingleton ( environmentMock . Object )
457+ . AddNetDaemonStateManager ( )
458+ . BuildServiceProvider ( ) ;
459+ var scopedProvider = provider . CreateScope ( ) ;
460+
461+ return ( haConnectionMock , scopedProvider . ServiceProvider ) ;
462+ }
422463}
0 commit comments