1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Linq ;
4+ using System . Security . Claims ;
5+ using System . Threading ;
6+ using System . Threading . Tasks ;
7+ using FluentValidation ;
8+ using Microsoft . AspNetCore . Http ;
9+ using Microsoft . AspNetCore . Mvc ;
10+ using Microsoft . EntityFrameworkCore ;
11+ using Microsoft . Extensions . Logging ;
12+ using Moq ;
13+ using NUnit . Framework ;
14+ using PathfinderHonorManager . Controllers ;
15+ using PathfinderHonorManager . DataAccess ;
16+ using PathfinderHonorManager . Service . Interfaces ;
17+ using PathfinderHonorManager . Tests . Helpers ;
18+ using Incoming = PathfinderHonorManager . Dto . Incoming ;
19+ using Outgoing = PathfinderHonorManager . Dto . Outgoing ;
20+
21+ namespace PathfinderHonorManager . Tests . Controllers
22+ {
23+ public class PathfindersControllerTests
24+ {
25+ private static readonly DbContextOptions < PathfinderContext > SharedContextOptions =
26+ new DbContextOptionsBuilder < PathfinderContext > ( )
27+ . UseInMemoryDatabase ( databaseName : Guid . NewGuid ( ) . ToString ( ) )
28+ . Options ;
29+
30+ private PathfindersController _controller ;
31+ private Mock < IPathfinderService > _pathfinderServiceMock ;
32+ private Mock < ILogger < PathfindersController > > _loggerMock ;
33+ private PathfinderContext _dbContext ;
34+ private const string TestClubCode = "TEST" ;
35+
36+ [ SetUp ]
37+ public async Task Setup ( )
38+ {
39+ await DatabaseSeeder . SeedDatabase ( SharedContextOptions ) ;
40+ _dbContext = new PathfinderContext ( SharedContextOptions ) ;
41+
42+ _pathfinderServiceMock = new Mock < IPathfinderService > ( ) ;
43+ _loggerMock = new Mock < ILogger < PathfindersController > > ( ) ;
44+ _controller = new PathfindersController ( _pathfinderServiceMock . Object , _loggerMock . Object ) ;
45+
46+ var user = new ClaimsPrincipal ( new ClaimsIdentity ( new Claim [ ]
47+ {
48+ new Claim ( "clubCode" , TestClubCode )
49+ } ) ) ;
50+ _controller . ControllerContext = new ControllerContext
51+ {
52+ HttpContext = new DefaultHttpContext { User = user }
53+ } ;
54+ }
55+
56+ [ Test ]
57+ public async Task GetAll_WithValidClubCode_ReturnsOkResult ( )
58+ {
59+ var expectedPathfinders = new List < Outgoing . PathfinderDependantDto >
60+ {
61+ new Outgoing . PathfinderDependantDto
62+ {
63+ PathfinderID = Guid . NewGuid ( ) ,
64+ FirstName = "Test" ,
65+ LastName = "User" ,
66+ Grade = 5 ,
67+ IsActive = true
68+ }
69+ } ;
70+
71+ _pathfinderServiceMock
72+ . Setup ( x => x . GetAllAsync ( TestClubCode , It . IsAny < bool > ( ) , It . IsAny < CancellationToken > ( ) ) )
73+ . ReturnsAsync ( expectedPathfinders ) ;
74+
75+ var result = await _controller . GetAll ( new CancellationToken ( ) ) ;
76+
77+ Assert . That ( result , Is . Not . Null ) ;
78+ Assert . That ( result . Result , Is . InstanceOf < OkObjectResult > ( ) ) ;
79+ var okResult = result . Result as OkObjectResult ;
80+ Assert . That ( okResult . Value , Is . EqualTo ( expectedPathfinders ) ) ;
81+ }
82+
83+ [ Test ]
84+ public async Task GetAll_WithNoPathfinders_ReturnsNotFound ( )
85+ {
86+ _pathfinderServiceMock
87+ . Setup ( x => x . GetAllAsync ( TestClubCode , It . IsAny < bool > ( ) , It . IsAny < CancellationToken > ( ) ) )
88+ . ReturnsAsync ( ( List < Outgoing . PathfinderDependantDto > ) null ) ;
89+
90+ var result = await _controller . GetAll ( new CancellationToken ( ) ) ;
91+
92+ Assert . That ( result . Result , Is . InstanceOf < NotFoundResult > ( ) ) ;
93+ }
94+
95+ [ Test ]
96+ public async Task GetById_WithValidIds_ReturnsOkResult ( )
97+ {
98+ var pathfinderId = Guid . NewGuid ( ) ;
99+ var expectedPathfinder = new Outgoing . PathfinderDependantDto
100+ {
101+ PathfinderID = pathfinderId ,
102+ FirstName = "Test" ,
103+ LastName = "User" ,
104+ Grade = 5 ,
105+ IsActive = true
106+ } ;
107+
108+ _pathfinderServiceMock
109+ . Setup ( x => x . GetByIdAsync ( pathfinderId , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
110+ . ReturnsAsync ( expectedPathfinder ) ;
111+
112+ var result = await _controller . GetByIdAsync ( pathfinderId , new CancellationToken ( ) ) ;
113+
114+ Assert . That ( result , Is . Not . Null ) ;
115+ Assert . That ( result , Is . InstanceOf < OkObjectResult > ( ) ) ;
116+ var okResult = result as OkObjectResult ;
117+ Assert . That ( okResult . Value , Is . EqualTo ( expectedPathfinder ) ) ;
118+ }
119+
120+ [ Test ]
121+ public async Task GetById_WithInvalidIds_ReturnsNotFound ( )
122+ {
123+ var pathfinderId = Guid . NewGuid ( ) ;
124+
125+ _pathfinderServiceMock
126+ . Setup ( x => x . GetByIdAsync ( pathfinderId , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
127+ . ReturnsAsync ( ( Outgoing . PathfinderDependantDto ) null ) ;
128+
129+ var result = await _controller . GetByIdAsync ( pathfinderId , new CancellationToken ( ) ) ;
130+
131+ Assert . That ( result , Is . InstanceOf < NotFoundResult > ( ) ) ;
132+ }
133+
134+ [ Test ]
135+ public async Task Post_WithValidData_ReturnsCreatedResult ( )
136+ {
137+ var newPathfinder = new Incoming . PathfinderDto
138+ {
139+ FirstName = "Test" ,
140+ LastName = "User" ,
141+ Grade = 5 ,
142+ IsActive = true
143+ } ;
144+
145+ var createdPathfinder = new Outgoing . PathfinderDto
146+ {
147+ PathfinderID = Guid . NewGuid ( ) ,
148+ FirstName = "Test" ,
149+ LastName = "User" ,
150+ Grade = 5 ,
151+ IsActive = true
152+ } ;
153+
154+ _pathfinderServiceMock
155+ . Setup ( x => x . AddAsync ( newPathfinder , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
156+ . ReturnsAsync ( createdPathfinder ) ;
157+
158+ var result = await _controller . PostAsync ( newPathfinder , new CancellationToken ( ) ) ;
159+
160+ Assert . That ( result , Is . Not . Null ) ;
161+ Assert . That ( result , Is . InstanceOf < CreatedAtRouteResult > ( ) ) ;
162+ var createdResult = result as CreatedAtRouteResult ;
163+ Assert . That ( createdResult . Value , Is . EqualTo ( createdPathfinder ) ) ;
164+ }
165+
166+ [ Test ]
167+ public async Task Post_WithValidationError_ReturnsValidationProblem ( )
168+ {
169+ var newPathfinder = new Incoming . PathfinderDto
170+ {
171+ FirstName = "Test" ,
172+ LastName = "User" ,
173+ Grade = 0 ,
174+ IsActive = true
175+ } ;
176+
177+ _pathfinderServiceMock
178+ . Setup ( x => x . AddAsync ( newPathfinder , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
179+ . ThrowsAsync ( new ValidationException ( "Validation failed" ) ) ;
180+
181+ var result = await _controller . PostAsync ( newPathfinder , new CancellationToken ( ) ) ;
182+
183+ Assert . That ( result , Is . InstanceOf < ObjectResult > ( ) ) ;
184+ var badRequestResult = result as ObjectResult ;
185+ Assert . That ( badRequestResult . Value , Is . InstanceOf < ValidationProblemDetails > ( ) ) ;
186+ }
187+
188+ [ Test ]
189+ public async Task Post_WithDbError_ReturnsValidationProblem ( )
190+ {
191+ var newPathfinder = new Incoming . PathfinderDto
192+ {
193+ FirstName = "Test" ,
194+ LastName = "User" ,
195+ Grade = 5 ,
196+ IsActive = true
197+ } ;
198+
199+ _pathfinderServiceMock
200+ . Setup ( x => x . AddAsync ( newPathfinder , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
201+ . ThrowsAsync ( new DbUpdateException ( "Database error" ) ) ;
202+
203+ var result = await _controller . PostAsync ( newPathfinder , new CancellationToken ( ) ) ;
204+
205+ Assert . That ( result , Is . InstanceOf < ObjectResult > ( ) ) ;
206+ var badRequestResult = result as ObjectResult ;
207+ Assert . That ( badRequestResult . Value , Is . InstanceOf < ValidationProblemDetails > ( ) ) ;
208+ }
209+
210+ [ Test ]
211+ public async Task Put_WithValidData_ReturnsOkResult ( )
212+ {
213+ var pathfinderId = Guid . NewGuid ( ) ;
214+ var updatePathfinder = new Incoming . PutPathfinderDto
215+ {
216+ Grade = 6 ,
217+ IsActive = true
218+ } ;
219+
220+ var updatedPathfinder = new Outgoing . PathfinderDto
221+ {
222+ PathfinderID = pathfinderId ,
223+ FirstName = "Test" ,
224+ LastName = "User" ,
225+ Grade = 6 ,
226+ IsActive = true
227+ } ;
228+
229+ _pathfinderServiceMock
230+ . Setup ( x => x . UpdateAsync ( pathfinderId , updatePathfinder , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
231+ . ReturnsAsync ( updatedPathfinder ) ;
232+
233+ var result = await _controller . PutAsync ( pathfinderId , updatePathfinder , new CancellationToken ( ) ) ;
234+
235+ Assert . That ( result , Is . Not . Null ) ;
236+ Assert . That ( result , Is . InstanceOf < OkObjectResult > ( ) ) ;
237+ var okResult = result as OkObjectResult ;
238+ Assert . That ( okResult . Value , Is . EqualTo ( updatedPathfinder ) ) ;
239+ }
240+
241+ [ Test ]
242+ public async Task Put_WithInvalidIds_ReturnsNotFound ( )
243+ {
244+ var pathfinderId = Guid . NewGuid ( ) ;
245+ var updatePathfinder = new Incoming . PutPathfinderDto
246+ {
247+ Grade = 6 ,
248+ IsActive = true
249+ } ;
250+
251+ _pathfinderServiceMock
252+ . Setup ( x => x . UpdateAsync ( pathfinderId , updatePathfinder , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
253+ . ReturnsAsync ( ( Outgoing . PathfinderDto ) null ) ;
254+
255+ var result = await _controller . PutAsync ( pathfinderId , updatePathfinder , new CancellationToken ( ) ) ;
256+
257+ Assert . That ( result , Is . InstanceOf < NotFoundResult > ( ) ) ;
258+ }
259+
260+ [ Test ]
261+ public async Task Put_WithValidationError_ReturnsValidationProblem ( )
262+ {
263+ var pathfinderId = Guid . NewGuid ( ) ;
264+ var updatePathfinder = new Incoming . PutPathfinderDto
265+ {
266+ Grade = 0 ,
267+ IsActive = true
268+ } ;
269+
270+ _pathfinderServiceMock
271+ . Setup ( x => x . UpdateAsync ( pathfinderId , updatePathfinder , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
272+ . ThrowsAsync ( new ValidationException ( "Validation failed" ) ) ;
273+
274+ var result = await _controller . PutAsync ( pathfinderId , updatePathfinder , new CancellationToken ( ) ) ;
275+
276+ Assert . That ( result , Is . InstanceOf < ObjectResult > ( ) ) ;
277+ var badRequestResult = result as ObjectResult ;
278+ Assert . That ( badRequestResult . Value , Is . InstanceOf < ValidationProblemDetails > ( ) ) ;
279+ }
280+
281+ [ Test ]
282+ public async Task BulkPut_WithValidData_ReturnsMultiStatus ( )
283+ {
284+ var pathfinderId = Guid . NewGuid ( ) ;
285+ var bulkData = new List < Incoming . BulkPutPathfinderDto >
286+ {
287+ new Incoming . BulkPutPathfinderDto
288+ {
289+ Items = new List < Incoming . BulkPutPathfinderItemDto >
290+ {
291+ new Incoming . BulkPutPathfinderItemDto
292+ {
293+ PathfinderId = pathfinderId ,
294+ Grade = 6 ,
295+ IsActive = true
296+ }
297+ }
298+ }
299+ } ;
300+
301+ var updatedPathfinder = new Outgoing . PathfinderDto
302+ {
303+ PathfinderID = pathfinderId ,
304+ FirstName = "Test" ,
305+ LastName = "User" ,
306+ Grade = 6 ,
307+ IsActive = true
308+ } ;
309+
310+ _pathfinderServiceMock
311+ . Setup ( x => x . BulkUpdateAsync ( bulkData , TestClubCode , It . IsAny < CancellationToken > ( ) ) )
312+ . ReturnsAsync ( new List < Outgoing . PathfinderDto > { updatedPathfinder } ) ;
313+
314+ var result = await _controller . BulkPutPathfindersAsync ( bulkData , new CancellationToken ( ) ) ;
315+
316+ Assert . That ( result , Is . Not . Null ) ;
317+ Assert . That ( result , Is . InstanceOf < ObjectResult > ( ) ) ;
318+ var multiStatusResult = result as ObjectResult ;
319+ Assert . That ( multiStatusResult . StatusCode , Is . EqualTo ( 207 ) ) ;
320+ }
321+
322+ [ TearDown ]
323+ public async Task TearDown ( )
324+ {
325+ await DatabaseCleaner . CleanDatabase ( _dbContext ) ;
326+ _dbContext . Dispose ( ) ;
327+ }
328+ }
329+ }
0 commit comments