33// The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
44// See the LICENSE and NOTICES files in the project root for more information.
55
6+ using System ;
7+ using System . Threading ;
68using System . Threading . Tasks ;
79using EdFi . Ods . AdminApi . Common . Constants ;
10+ using EdFi . Ods . AdminApi . Common . Infrastructure . Context ;
811using EdFi . Ods . AdminApi . Common . Infrastructure . ErrorHandling ;
912using EdFi . Ods . AdminApi . Common . Infrastructure . Models ;
13+ using EdFi . Ods . AdminApi . Common . Infrastructure . MultiTenancy ;
14+ using EdFi . Ods . AdminApi . Common . Settings ;
1015using EdFi . Ods . AdminApi . V3 . Features . DbInstances ;
1116using EdFi . Ods . AdminApi . V3 . Infrastructure . Database . Commands ;
1217using EdFi . Ods . AdminApi . V3 . Infrastructure . Database . Queries ;
1318using FakeItEasy ;
1419using FluentValidation ;
20+ using Microsoft . AspNetCore . Http ;
1521using Microsoft . AspNetCore . Http . HttpResults ;
22+ using Microsoft . Extensions . Options ;
1623using NUnit . Framework ;
24+ using Quartz ;
1725using Shouldly ;
1826
1927#nullable enable
@@ -25,161 +33,226 @@ public class DeleteDbInstanceTests
2533{
2634 private IGetDbInstanceByIdQuery _getDbInstanceByIdQuery = null ! ;
2735 private IDeleteDbInstanceCommand _deleteDbInstanceCommand = null ! ;
36+ private ISchedulerFactory _schedulerFactory = null ! ;
37+ private IContextProvider < TenantConfiguration > _tenantConfigurationProvider = null ! ;
38+ private IOptions < AppSettings > _options = null ! ;
2839
2940 [ SetUp ]
3041 public void SetUp ( )
3142 {
3243 _getDbInstanceByIdQuery = A . Fake < IGetDbInstanceByIdQuery > ( ) ;
3344 _deleteDbInstanceCommand = A . Fake < IDeleteDbInstanceCommand > ( ) ;
45+
46+ var scheduler = A . Fake < IScheduler > ( ) ;
47+ A . CallTo ( ( ) => scheduler . ScheduleJob ( A < IJobDetail > . _ , A < ITrigger > . _ , A < CancellationToken > . _ ) )
48+ . Returns ( Task . FromResult ( DateTimeOffset . UtcNow ) ) ;
49+
50+ _schedulerFactory = A . Fake < ISchedulerFactory > ( ) ;
51+ A . CallTo ( ( ) => _schedulerFactory . GetScheduler ( A < CancellationToken > . _ ) )
52+ . Returns ( Task . FromResult ( scheduler ) ) ;
53+
54+ _tenantConfigurationProvider = A . Fake < IContextProvider < TenantConfiguration > > ( ) ;
55+ A . CallTo ( ( ) => _tenantConfigurationProvider . Get ( ) ) . Returns ( null ) ;
56+
57+ _options = Options . Create ( new AppSettings { DatabaseEngine = "SqlServer" } ) ;
3458 }
3559
60+ private Task < IResult > Handle ( int id )
61+ => DeleteDbInstance . Handle (
62+ _getDbInstanceByIdQuery ,
63+ _deleteDbInstanceCommand ,
64+ _schedulerFactory ,
65+ _tenantConfigurationProvider ,
66+ _options ,
67+ id ) ;
68+
3669 [ Test ]
3770 public async Task Handle_WhenDbInstanceNotFound_ThrowsNotFoundException ( )
3871 {
3972 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 99 ) ) . Returns ( null ) ;
4073
41- await Should . ThrowAsync < NotFoundException < int > > ( ( ) =>
42- DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 99 )
43- ) ;
74+ await Should . ThrowAsync < NotFoundException < int > > ( ( ) => Handle ( 99 ) ) ;
4475 }
4576
4677 [ Test ]
47- public async Task Handle_WhenStatusIsPending_ThrowsValidationException ( )
78+ public async Task Handle_WhenStatusIsCreated_ExecutesCommandAndReturnsAccepted ( )
4879 {
4980 var dbInstance = new DbInstance
5081 {
5182 Id = 1 ,
5283 Name = "Test" ,
53- Status = DbInstanceStatus . PendingCreate . ToString ( ) ,
84+ Status = DbInstanceStatus . Created . ToString ( ) ,
5485 DatabaseTemplate = "Minimal" ,
5586 } ;
5687 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 1 ) ) . Returns ( dbInstance ) ;
5788
58- var ex = await Should . ThrowAsync < ValidationException > ( ( ) =>
59- DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 1 )
60- ) ;
89+ var result = await Handle ( 1 ) ;
6190
62- ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "provisioned" ) ) ;
63- A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
91+ result . ShouldBeOfType < NoContent > ( ) ;
92+ A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( 1 ) ) . MustHaveHappenedOnceExactly ( ) ;
6493 }
6594
6695 [ Test ]
67- public async Task Handle_WhenStatusIsInProgress_ThrowsValidationException ( )
96+ public async Task Handle_WhenStatusIsPendingCreate_ThrowsValidationException ( )
6897 {
6998 var dbInstance = new DbInstance
7099 {
71100 Id = 2 ,
72101 Name = "Test" ,
73- Status = DbInstanceStatus . CreateInProgress . ToString ( ) ,
102+ Status = DbInstanceStatus . PendingCreate . ToString ( ) ,
74103 DatabaseTemplate = "Minimal" ,
75104 } ;
76105 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 2 ) ) . Returns ( dbInstance ) ;
77106
78- var ex = await Should . ThrowAsync < ValidationException > (
79- ( ) => DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 2 )
80- ) ;
107+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 2 ) ) ;
81108
82109 ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "provisioned" ) ) ;
83110 A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
84111 }
85112
86113 [ Test ]
87- public async Task Handle_WhenStatusIsCompleted_ExecutesCommandAndReturnsNoContent ( )
114+ public async Task Handle_WhenStatusIsCreateInProgress_ThrowsValidationException ( )
88115 {
89116 var dbInstance = new DbInstance
90117 {
91118 Id = 3 ,
92119 Name = "Test" ,
93- Status = DbInstanceStatus . Created . ToString ( ) ,
120+ Status = DbInstanceStatus . CreateInProgress . ToString ( ) ,
94121 DatabaseTemplate = "Minimal" ,
95122 } ;
96123 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 3 ) ) . Returns ( dbInstance ) ;
97124
98- var result = await DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 3 ) ;
125+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 3 ) ) ;
99126
100- result . ShouldBeOfType < NoContent > ( ) ;
101- A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( 3 ) ) . MustHaveHappenedOnceExactly ( ) ;
127+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "provisioned" ) ) ;
128+ A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
102129 }
103130
104131 [ Test ]
105- public async Task Handle_WhenStatusIsDeleteFailed_ExecutesCommandAndReturnsNoContent ( )
132+ public async Task Handle_WhenStatusIsCreateFailed_ThrowsValidationException ( )
106133 {
107134 var dbInstance = new DbInstance
108135 {
109136 Id = 4 ,
110137 Name = "Test" ,
111- Status = DbInstanceStatus . DeleteFailed . ToString ( ) ,
138+ Status = DbInstanceStatus . CreateFailed . ToString ( ) ,
112139 DatabaseTemplate = "Minimal" ,
113140 } ;
114141 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 4 ) ) . Returns ( dbInstance ) ;
115142
116- var result = await DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 4 ) ;
143+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 4 ) ) ;
117144
118- result . ShouldBeOfType < NoContent > ( ) ;
119- A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( 4 ) ) . MustHaveHappenedOnceExactly ( ) ;
145+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "creation failed" ) ) ;
146+ A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
120147 }
121148
122149 [ Test ]
123- public async Task Handle_WhenStatusIsPendingDelete_ThrowsValidationException ( )
150+ public async Task Handle_WhenStatusIsCreateError_ThrowsValidationException ( )
124151 {
125152 var dbInstance = new DbInstance
126153 {
127154 Id = 5 ,
128155 Name = "Test" ,
129- Status = DbInstanceStatus . PendingDelete . ToString ( ) ,
156+ Status = DbInstanceStatus . CreateError . ToString ( ) ,
130157 DatabaseTemplate = "Minimal" ,
131158 } ;
132159 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 5 ) ) . Returns ( dbInstance ) ;
133160
134- var ex = await Should . ThrowAsync < ValidationException > ( ( ) =>
135- DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 5 )
136- ) ;
161+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 5 ) ) ;
137162
138- ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "queued for deletion " ) ) ;
163+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "creation failed permanently " ) ) ;
139164 A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
140165 }
141166
142167 [ Test ]
143- public async Task Handle_WhenStatusIsError_ThrowsValidationException ( )
168+ public async Task Handle_WhenStatusIsPendingDelete_ThrowsValidationException ( )
144169 {
145170 var dbInstance = new DbInstance
146171 {
147172 Id = 6 ,
148173 Name = "Test" ,
149- Status = DbInstanceStatus . CreateError . ToString ( ) ,
174+ Status = DbInstanceStatus . PendingDelete . ToString ( ) ,
150175 DatabaseTemplate = "Minimal" ,
151176 } ;
152177 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 6 ) ) . Returns ( dbInstance ) ;
153178
154- var ex = await Should . ThrowAsync < ValidationException > ( ( ) =>
155- DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 6 )
156- ) ;
179+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 6 ) ) ;
157180
158- ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "error during provisioning " ) ) ;
181+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "queued for deletion " ) ) ;
159182 A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
160183 }
161184
162185 [ Test ]
163- public async Task Handle_WhenStatusIsDeleted_ThrowsNotFoundException ( )
186+ public async Task Handle_WhenStatusIsDeleteInProgress_ThrowsValidationException ( )
164187 {
165188 var dbInstance = new DbInstance
166189 {
167190 Id = 7 ,
168191 Name = "Test" ,
169- Status = DbInstanceStatus . Deleted . ToString ( ) ,
192+ Status = DbInstanceStatus . DeleteInProgress . ToString ( ) ,
170193 DatabaseTemplate = "Minimal" ,
171194 } ;
172195 A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 7 ) ) . Returns ( dbInstance ) ;
173196
174- await Should . ThrowAsync < NotFoundException < int > > ( ( ) =>
175- DeleteDbInstance . Handle ( _getDbInstanceByIdQuery , _deleteDbInstanceCommand , 7 )
176- ) ;
197+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 7 ) ) ;
177198
199+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "currently being deleted" ) ) ;
178200 A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
179201 }
180- }
181202
182- #nullable restore
203+ [ Test ]
204+ public async Task Handle_WhenStatusIsDeleteFailed_ThrowsValidationException ( )
205+ {
206+ var dbInstance = new DbInstance
207+ {
208+ Id = 8 ,
209+ Name = "Test" ,
210+ Status = DbInstanceStatus . DeleteFailed . ToString ( ) ,
211+ DatabaseTemplate = "Minimal" ,
212+ } ;
213+ A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 8 ) ) . Returns ( dbInstance ) ;
214+
215+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 8 ) ) ;
216+
217+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "retried automatically" ) ) ;
218+ A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
219+ }
220+
221+ [ Test ]
222+ public async Task Handle_WhenStatusIsDeleteError_ThrowsValidationException ( )
223+ {
224+ var dbInstance = new DbInstance
225+ {
226+ Id = 9 ,
227+ Name = "Test" ,
228+ Status = DbInstanceStatus . DeleteError . ToString ( ) ,
229+ DatabaseTemplate = "Minimal" ,
230+ } ;
231+ A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 9 ) ) . Returns ( dbInstance ) ;
183232
233+ var ex = await Should . ThrowAsync < ValidationException > ( ( ) => Handle ( 9 ) ) ;
184234
235+ ex . Errors . ShouldContain ( e => e . ErrorMessage . Contains ( "deletion failed permanently" ) ) ;
236+ A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
237+ }
238+
239+ [ Test ]
240+ public async Task Handle_WhenStatusIsDeleted_ThrowsNotFoundException ( )
241+ {
242+ var dbInstance = new DbInstance
243+ {
244+ Id = 10 ,
245+ Name = "Test" ,
246+ Status = DbInstanceStatus . Deleted . ToString ( ) ,
247+ DatabaseTemplate = "Minimal" ,
248+ } ;
249+ A . CallTo ( ( ) => _getDbInstanceByIdQuery . Execute ( 10 ) ) . Returns ( dbInstance ) ;
250+
251+ await Should . ThrowAsync < NotFoundException < int > > ( ( ) => Handle ( 10 ) ) ;
252+
253+ A . CallTo ( ( ) => _deleteDbInstanceCommand . Execute ( A < int > . _ ) ) . MustNotHaveHappened ( ) ;
254+ }
255+ }
256+
257+ #nullable restore
185258
0 commit comments