Skip to content

Commit 1bcba09

Browse files
authored
Merge pull request #86 from KAMALDEEN333/Unit-Test-Auth
Unit test auth
2 parents ae5c4da + e018843 commit 1bcba09

113 files changed

Lines changed: 25859 additions & 526 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

coverage/clover.xml

Lines changed: 1747 additions & 38 deletions
Large diffs are not rendered by default.

coverage/coverage-final.json

Lines changed: 77 additions & 1 deletion
Large diffs are not rendered by default.

coverage/lcov-report/index.html

Lines changed: 451 additions & 16 deletions
Large diffs are not rendered by default.

coverage/lcov-report/src/app.controller.ts.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.con
106106
<div class='footer quiet pad2 space-top1 center small'>
107107
Code coverage generated by
108108
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
109-
at 2026-02-24T15:53:17.618Z
109+
at 2026-03-26T11:47:19.538Z
110110
</div>
111111
<script src="../prettify.js"></script>
112112
<script>

coverage/lcov-report/src/app.module.ts.html

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
2525
<div class='fl pad1y space-right2'>
2626
<span class="strong">0% </span>
2727
<span class="quiet">Statements</span>
28-
<span class='fraction'>0/14</span>
28+
<span class='fraction'>0/15</span>
2929
</div>
3030

3131

@@ -46,7 +46,7 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
4646
<div class='fl pad1y space-right2'>
4747
<span class="strong">0% </span>
4848
<span class="quiet">Lines</span>
49-
<span class='fraction'>0/12</span>
49+
<span class='fraction'>0/13</span>
5050
</div>
5151

5252

@@ -94,7 +94,9 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
9494
<a name='L29'></a><a href='#L29'>29</a>
9595
<a name='L30'></a><a href='#L30'>30</a>
9696
<a name='L31'></a><a href='#L31'>31</a>
97-
<a name='L32'></a><a href='#L32'>32</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
97+
<a name='L32'></a><a href='#L32'>32</a>
98+
<a name='L33'></a><a href='#L33'>33</a>
99+
<a name='L34'></a><a href='#L34'>34</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
98100
<span class="cline-any cline-no">&nbsp;</span>
99101
<span class="cline-any cline-no">&nbsp;</span>
100102
<span class="cline-any cline-no">&nbsp;</span>
@@ -105,6 +107,8 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
105107
<span class="cline-any cline-no">&nbsp;</span>
106108
<span class="cline-any cline-no">&nbsp;</span>
107109
<span class="cline-any cline-no">&nbsp;</span>
110+
<span class="cline-any cline-no">&nbsp;</span>
111+
<span class="cline-any cline-neutral">&nbsp;</span>
108112
<span class="cline-any cline-neutral">&nbsp;</span>
109113
<span class="cline-any cline-neutral">&nbsp;</span>
110114
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -132,10 +136,11 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
132136
<span class="cstat-no" title="statement not covered" >import { DatabaseModule } from './database/database.module';</span>
133137
<span class="cstat-no" title="statement not covered" >import { AuthModule } from './auth/auth.module';</span>
134138
<span class="cstat-no" title="statement not covered" >import { UsersModule } from './users/users.module';</span>
135-
<span class="cstat-no" title="statement not covered" >import { MailModule } from './modules/mail/mail.module';</span>
136139
<span class="cstat-no" title="statement not covered" >import configuration from './database/config';</span>
137140
<span class="cstat-no" title="statement not covered" >import { LoggerModule } from './logger/logger.module';</span>
138141
<span class="cstat-no" title="statement not covered" >import { ProjectsModule } from './projects/projects.module';</span>
142+
<span class="cstat-no" title="statement not covered" >import { MailModule } from './mail/mail.module';</span>
143+
<span class="cstat-no" title="statement not covered" >import { DonationsModule } from './donations/donations.module';</span>
139144
&nbsp;
140145
@Module({
141146
imports: [
@@ -151,6 +156,7 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
151156
// Users module provides user-facing endpoints such as change-password
152157
UsersModule,
153158
ProjectsModule,
159+
DonationsModule,
154160
],
155161
controllers: [AppController],
156162
providers: [AppService],
@@ -163,7 +169,7 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.mod
163169
<div class='footer quiet pad2 space-top1 center small'>
164170
Code coverage generated by
165171
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
166-
at 2026-02-24T15:53:17.618Z
172+
at 2026-03-26T11:47:19.538Z
167173
</div>
168174
<script src="../prettify.js"></script>
169175
<script>

coverage/lcov-report/src/app.service.ts.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ <h1><a href="../index.html">All files</a> / <a href="index.html">src</a> app.ser
9494
<div class='footer quiet pad2 space-top1 center small'>
9595
Code coverage generated by
9696
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
97-
at 2026-02-24T15:53:17.618Z
97+
at 2026-03-26T11:47:19.538Z
9898
</div>
9999
<script src="../prettify.js"></script>
100100
<script>

coverage/lcov-report/src/auth/auth.controller.ts.html

Lines changed: 119 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
2525
<div class='fl pad1y space-right2'>
2626
<span class="strong">0% </span>
2727
<span class="quiet">Statements</span>
28-
<span class='fraction'>0/25</span>
28+
<span class='fraction'>0/26</span>
2929
</div>
3030

3131

@@ -46,7 +46,7 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
4646
<div class='fl pad1y space-right2'>
4747
<span class="strong">0% </span>
4848
<span class="quiet">Lines</span>
49-
<span class='fraction'>0/23</span>
49+
<span class='fraction'>0/24</span>
5050
</div>
5151

5252

@@ -166,7 +166,35 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
166166
<a name='L101'></a><a href='#L101'>101</a>
167167
<a name='L102'></a><a href='#L102'>102</a>
168168
<a name='L103'></a><a href='#L103'>103</a>
169-
<a name='L104'></a><a href='#L104'>104</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
169+
<a name='L104'></a><a href='#L104'>104</a>
170+
<a name='L105'></a><a href='#L105'>105</a>
171+
<a name='L106'></a><a href='#L106'>106</a>
172+
<a name='L107'></a><a href='#L107'>107</a>
173+
<a name='L108'></a><a href='#L108'>108</a>
174+
<a name='L109'></a><a href='#L109'>109</a>
175+
<a name='L110'></a><a href='#L110'>110</a>
176+
<a name='L111'></a><a href='#L111'>111</a>
177+
<a name='L112'></a><a href='#L112'>112</a>
178+
<a name='L113'></a><a href='#L113'>113</a>
179+
<a name='L114'></a><a href='#L114'>114</a>
180+
<a name='L115'></a><a href='#L115'>115</a>
181+
<a name='L116'></a><a href='#L116'>116</a>
182+
<a name='L117'></a><a href='#L117'>117</a>
183+
<a name='L118'></a><a href='#L118'>118</a>
184+
<a name='L119'></a><a href='#L119'>119</a>
185+
<a name='L120'></a><a href='#L120'>120</a>
186+
<a name='L121'></a><a href='#L121'>121</a>
187+
<a name='L122'></a><a href='#L122'>122</a>
188+
<a name='L123'></a><a href='#L123'>123</a>
189+
<a name='L124'></a><a href='#L124'>124</a>
190+
<a name='L125'></a><a href='#L125'>125</a>
191+
<a name='L126'></a><a href='#L126'>126</a>
192+
<a name='L127'></a><a href='#L127'>127</a>
193+
<a name='L128'></a><a href='#L128'>128</a>
194+
<a name='L129'></a><a href='#L129'>129</a>
195+
<a name='L130'></a><a href='#L130'>130</a>
196+
<a name='L131'></a><a href='#L131'>131</a>
197+
<a name='L132'></a><a href='#L132'>132</a></td><td class="line-coverage quiet"><span class="cline-any cline-no">&nbsp;</span>
170198
<span class="cline-any cline-neutral">&nbsp;</span>
171199
<span class="cline-any cline-neutral">&nbsp;</span>
172200
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -183,6 +211,12 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
183211
<span class="cline-any cline-neutral">&nbsp;</span>
184212
<span class="cline-any cline-neutral">&nbsp;</span>
185213
<span class="cline-any cline-neutral">&nbsp;</span>
214+
<span class="cline-any cline-neutral">&nbsp;</span>
215+
<span class="cline-any cline-neutral">&nbsp;</span>
216+
<span class="cline-any cline-neutral">&nbsp;</span>
217+
<span class="cline-any cline-neutral">&nbsp;</span>
218+
<span class="cline-any cline-neutral">&nbsp;</span>
219+
<span class="cline-any cline-no">&nbsp;</span>
186220
<span class="cline-any cline-no">&nbsp;</span>
187221
<span class="cline-any cline-no">&nbsp;</span>
188222
<span class="cline-any cline-no">&nbsp;</span>
@@ -206,7 +240,6 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
206240
<span class="cline-any cline-neutral">&nbsp;</span>
207241
<span class="cline-any cline-neutral">&nbsp;</span>
208242
<span class="cline-any cline-neutral">&nbsp;</span>
209-
<span class="cline-any cline-neutral">&nbsp;</span>
210243
<span class="cline-any cline-no">&nbsp;</span>
211244
<span class="cline-any cline-no">&nbsp;</span>
212245
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -215,6 +248,12 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
215248
<span class="cline-any cline-neutral">&nbsp;</span>
216249
<span class="cline-any cline-neutral">&nbsp;</span>
217250
<span class="cline-any cline-neutral">&nbsp;</span>
251+
<span class="cline-any cline-neutral">&nbsp;</span>
252+
<span class="cline-any cline-neutral">&nbsp;</span>
253+
<span class="cline-any cline-neutral">&nbsp;</span>
254+
<span class="cline-any cline-neutral">&nbsp;</span>
255+
<span class="cline-any cline-neutral">&nbsp;</span>
256+
<span class="cline-any cline-neutral">&nbsp;</span>
218257
<span class="cline-any cline-no">&nbsp;</span>
219258
<span class="cline-any cline-neutral">&nbsp;</span>
220259
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -228,6 +267,11 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
228267
<span class="cline-any cline-neutral">&nbsp;</span>
229268
<span class="cline-any cline-neutral">&nbsp;</span>
230269
<span class="cline-any cline-neutral">&nbsp;</span>
270+
<span class="cline-any cline-neutral">&nbsp;</span>
271+
<span class="cline-any cline-neutral">&nbsp;</span>
272+
<span class="cline-any cline-neutral">&nbsp;</span>
273+
<span class="cline-any cline-neutral">&nbsp;</span>
274+
<span class="cline-any cline-neutral">&nbsp;</span>
231275
<span class="cline-any cline-no">&nbsp;</span>
232276
<span class="cline-any cline-no">&nbsp;</span>
233277
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -237,6 +281,11 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
237281
<span class="cline-any cline-neutral">&nbsp;</span>
238282
<span class="cline-any cline-neutral">&nbsp;</span>
239283
<span class="cline-any cline-neutral">&nbsp;</span>
284+
<span class="cline-any cline-neutral">&nbsp;</span>
285+
<span class="cline-any cline-neutral">&nbsp;</span>
286+
<span class="cline-any cline-neutral">&nbsp;</span>
287+
<span class="cline-any cline-neutral">&nbsp;</span>
288+
<span class="cline-any cline-neutral">&nbsp;</span>
240289
<span class="cline-any cline-no">&nbsp;</span>
241290
<span class="cline-any cline-neutral">&nbsp;</span>
242291
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -248,6 +297,11 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
248297
<span class="cline-any cline-neutral">&nbsp;</span>
249298
<span class="cline-any cline-neutral">&nbsp;</span>
250299
<span class="cline-any cline-neutral">&nbsp;</span>
300+
<span class="cline-any cline-neutral">&nbsp;</span>
301+
<span class="cline-any cline-neutral">&nbsp;</span>
302+
<span class="cline-any cline-neutral">&nbsp;</span>
303+
<span class="cline-any cline-neutral">&nbsp;</span>
304+
<span class="cline-any cline-neutral">&nbsp;</span>
251305
<span class="cline-any cline-no">&nbsp;</span>
252306
<span class="cline-any cline-neutral">&nbsp;</span>
253307
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -263,6 +317,8 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
263317
<span class="cline-any cline-neutral">&nbsp;</span>
264318
<span class="cline-any cline-neutral">&nbsp;</span>
265319
<span class="cline-any cline-neutral">&nbsp;</span>
320+
<span class="cline-any cline-neutral">&nbsp;</span>
321+
<span class="cline-any cline-neutral">&nbsp;</span>
266322
<span class="cline-any cline-no">&nbsp;</span>
267323
<span class="cline-any cline-neutral">&nbsp;</span>
268324
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -285,90 +341,118 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
285341
ApiOperation,
286342
ApiResponse,
287343
ApiBearerAuth,
344+
ApiOkResponse,
345+
ApiCreatedResponse,
346+
ApiBadRequestResponse,
347+
ApiUnauthorizedResponse,
348+
ApiNotFoundResponse,
288349
} from '@nestjs/swagger';
289-
<span class="cstat-no" title="statement not covered" >import { AuthService } from './auth.service';</span>
290-
<span class="cstat-no" title="statement not covered" >import { RegisterDto } from './dtos/register.dto';</span>
291-
<span class="cstat-no" title="statement not covered" >import { LoginDto } from './dtos/login.dto';</span>
292-
<span class="cstat-no" title="statement not covered" >import { VerifyEmailDto } from './dtos/verify-email.dto';</span>
293-
<span class="cstat-no" title="statement not covered" >import { ResendVerificationDto } from './dtos/resend-verification.dto';</span>
294-
<span class="cstat-no" title="statement not covered" >import { RefreshTokenDto } from './dtos/refresh-token.dto';</span>
295-
import { AuthResponse } from './interfaces/auth.interface';
350+
<span class="cstat-no" title="statement not covered" >import { RegisterDto } from './dto/register.dto';</span>
351+
<span class="cstat-no" title="statement not covered" >import { LoginDto } from './dto/login.dto';</span>
352+
<span class="cstat-no" title="statement not covered" >import { VerifyEmailDto } from './dto/verify-email.dto';</span>
353+
<span class="cstat-no" title="statement not covered" >import { ResendVerificationDto } from './dto/resend-verification.dto';</span>
354+
<span class="cstat-no" title="statement not covered" >import { RefreshTokenDto } from './dto/refresh-token.dto';</span>
355+
<span class="cstat-no" title="statement not covered" >import { AuthResponseDto } from './dto/auth-response.dto';</span>
356+
<span class="cstat-no" title="statement not covered" >import { AuthService } from './providers/auth.service';</span>
296357
&nbsp;
297-
@ApiTags('Auth')
358+
@ApiTags('auth')
359+
@ApiBearerAuth()
298360
@Controller('auth')
299361
export <span class="cstat-no" title="statement not covered" >class <span class="cstat-no" title="statement not covered" ><span class="cstat-no" title="statement not covered" >AuthController </span>{</span></span>
300362
<span class="fstat-no" title="function not covered" > constructor(private readonly <span class="cstat-no" title="statement not covered" >a</span>uthService: A</span>uthService) {}
301363
&nbsp;
364+
//_____________________Endpoint to register a new user
302365
@Post('register')
303366
@ApiOperation({ summary: 'Register a new user' })
304-
@ApiResponse({
305-
status: 201,
367+
@ApiCreatedResponse({
306368
description: 'User registered successfully',
307-
type: Object,
369+
type: AuthResponseDto,
308370
})
309-
@ApiResponse({
310-
status: 400,
371+
@ApiBadRequestResponse({
311372
description: 'Invalid input or user already exists',
312373
})
313-
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >register(</span>@Body() registerDto: RegisterDto): Promise&lt;AuthResponse&gt; {</span>
374+
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >register(</span>@Body() registerDto: RegisterDto): Promise&lt;AuthResponseDto&gt; {</span>
314375
<span class="cstat-no" title="statement not covered" > return this.authService.register(registerDto);</span>
315376
}
316377
&nbsp;
378+
//_________________________ Endpoint to login with email and password
317379
@Post('login')
318380
@ApiOperation({ summary: 'Login with email and password' })
319-
@ApiResponse({ status: 200, description: 'Login successful', type: Object })
320-
@ApiResponse({ status: 401, description: 'Invalid credentials' })
381+
@ApiOkResponse({
382+
description: 'Login successful',
383+
type: AuthResponseDto,
384+
})
385+
@ApiUnauthorizedResponse({
386+
description: 'Invalid credentials',
387+
})
321388
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >login(</span></span>
322389
@Body() loginDto: LoginDto,
323390
@Request() req,
324-
): Promise&lt;AuthResponse&gt; {
391+
): Promise&lt;AuthResponseDto&gt; {
325392
<span class="cstat-no" title="statement not covered" > return this.authService.login(loginDto, req);</span>
326393
}
327394
&nbsp;
328-
@UseGuards(AuthGuard('jwt'))
329-
@ApiBearerAuth('JWT-auth')
395+
//_________________________ Endpoint to get current user profile (JWT required)
330396
@Get('profile')
397+
@UseGuards(AuthGuard('jwt'))
331398
@ApiOperation({ summary: 'Get current user profile (JWT required)' })
332-
@ApiResponse({ status: 200, description: 'Profile retrieved successfully' })
333-
@ApiResponse({ status: 401, description: 'Unauthorized' })
399+
@ApiOkResponse({
400+
description: 'Profile retrieved successfully',
401+
type: Object,
402+
})
403+
@ApiUnauthorizedResponse({
404+
description: 'Unauthorized',
405+
})
334406
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >getProfile(</span>@Request() req) {</span>
335407
<span class="cstat-no" title="statement not covered" > return req.user;</span>
336408
}
337409
&nbsp;
410+
//_________________________ Endpoint to verify email with token
338411
@Post('verify-email')
339412
@HttpCode(HttpStatus.OK)
340413
@ApiOperation({ summary: 'Verify email with token' })
341-
@ApiResponse({ status: 200, description: 'Email verified successfully' })
342-
@ApiResponse({ status: 400, description: 'Invalid or expired token' })
414+
@ApiOkResponse({
415+
description: 'Email verified successfully',
416+
})
417+
@ApiBadRequestResponse({
418+
description: 'Invalid or expired token',
419+
})
343420
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >verifyEmail(</span></span>
344421
@Body() verifyEmailDto: VerifyEmailDto,
345422
): Promise&lt;{ message: string }&gt; {
346423
<span class="cstat-no" title="statement not covered" > return this.authService.verifyEmail(verifyEmailDto);</span>
347424
}
348425
&nbsp;
426+
//_________________________ Endpoint to resend email verification
349427
@Post('resend-verification')
350428
@HttpCode(HttpStatus.OK)
351429
@ApiOperation({ summary: 'Resend email verification' })
352-
@ApiResponse({ status: 200, description: 'Verification email sent' })
353-
@ApiResponse({ status: 404, description: 'User not found' })
430+
@ApiOkResponse({
431+
description: 'Verification email sent',
432+
})
433+
@ApiNotFoundResponse({
434+
description: 'User not found',
435+
})
354436
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >resendVerification(</span></span>
355437
@Body() resendVerificationDto: ResendVerificationDto,
356438
): Promise&lt;{ message: string }&gt; {
357439
<span class="cstat-no" title="statement not covered" > return this.authService.resendVerification(resendVerificationDto);</span>
358440
}
359441
&nbsp;
442+
//_________________________ Endpoint to refresh access token using refresh token (token rotation)
360443
@Post('refresh')
361444
@HttpCode(HttpStatus.OK)
362445
@ApiOperation({ summary: 'Refresh access token' })
363-
@ApiResponse({
364-
status: 200,
446+
@ApiOkResponse({
365447
description: 'Token refreshed successfully',
366-
type: Object,
448+
type: AuthResponseDto,
449+
})
450+
@ApiUnauthorizedResponse({
451+
description: 'Invalid refresh token',
367452
})
368-
@ApiResponse({ status: 401, description: 'Invalid refresh token' })
369453
async <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >refreshToken(</span></span>
370454
@Body() refreshTokenDto: RefreshTokenDto,
371-
): Promise&lt;AuthResponse&gt; {
455+
): Promise&lt;AuthResponseDto&gt; {
372456
<span class="cstat-no" title="statement not covered" > return this.authService.refreshToken(refreshTokenDto);</span>
373457
}
374458
}
@@ -379,7 +463,7 @@ <h1><a href="../../index.html">All files</a> / <a href="index.html">src/auth</a>
379463
<div class='footer quiet pad2 space-top1 center small'>
380464
Code coverage generated by
381465
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
382-
at 2026-02-24T15:53:17.618Z
466+
at 2026-03-26T11:47:19.538Z
383467
</div>
384468
<script src="../../prettify.js"></script>
385469
<script>

0 commit comments

Comments
 (0)