Skip to content

Commit 6cfca85

Browse files
authored
Merge pull request #1336 from marvs8/feat/social-links-controller-unit-tests
Feat/social links controller unit tests
2 parents 6151297 + 9f9dd38 commit 6cfca85

1 file changed

Lines changed: 80 additions & 10 deletions

File tree

backend/src/social-link/social-links.controller.spec.ts

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { BadRequestException, NotFoundException } from '@nestjs/common';
12
import { ThrottlerGuard } from '@nestjs/throttler';
23
import {
34
THROTTLER_LIMIT,
@@ -6,6 +7,34 @@ import {
67
import { SocialLinksDto } from './social-links.dto';
78
import { SocialLinkController } from './social-links.controller';
89
import { SocialLinksService } from './social-links.service';
10+
import { PaginatedResponseDto } from '../common/dto';
11+
import { SocialLinksListItem } from './social-links.service';
12+
13+
// ─── shared mock ────────────────────────────────────────────────────────────
14+
15+
const mockPaginatedResult: PaginatedResponseDto<SocialLinksListItem> = {
16+
data: [],
17+
cursor: null,
18+
limit: 20,
19+
nextCursor: null,
20+
hasMore: false,
21+
total: 0,
22+
page: 1,
23+
totalPages: 0,
24+
};
25+
26+
const mockSocialLinksService = {
27+
extractUpdatePayload: jest
28+
.fn()
29+
.mockImplementation((dto: SocialLinksDto) => dto),
30+
createSocialLinks: jest
31+
.fn()
32+
.mockImplementation((dto: SocialLinksDto) => dto),
33+
updateSocialLinks: jest
34+
.fn()
35+
.mockImplementation((_id: string, dto: SocialLinksDto) => dto),
36+
listSocialLinks: jest.fn().mockReturnValue(mockPaginatedResult),
37+
};
938

1039
describe('SocialLinkController', () => {
1140
let controller: SocialLinkController;
@@ -30,12 +59,38 @@ describe('SocialLinkController', () => {
3059
expect(controller).toBeDefined();
3160
});
3261

33-
it('applies the throttler guard at the controller level', () => {
34-
const guards = Reflect.getMetadata(
35-
'__guards__',
36-
SocialLinkController,
37-
) as unknown as Array<new () => unknown>;
38-
expect(guards).toContain(ThrottlerGuard);
62+
// ─── guard & throttle metadata ────────────────────────────────────────────
63+
64+
describe('guard and throttle metadata', () => {
65+
it('applies the throttler guard at the controller level', () => {
66+
const guards = Reflect.getMetadata(
67+
'__guards__',
68+
SocialLinkController,
69+
) as unknown as Array<new () => unknown>;
70+
expect(guards).toContain(ThrottlerGuard);
71+
});
72+
73+
it('configures create with the expected throttling policy', () => {
74+
const createHandler = SocialLinkController.prototype.create;
75+
const limit = Reflect.getMetadata(THROTTLER_LIMIT + 'default', createHandler);
76+
const ttl = Reflect.getMetadata(THROTTLER_TTL + 'default', createHandler);
77+
expect(limit).toBe(5);
78+
expect(ttl).toBe(60000);
79+
});
80+
81+
it('configures update with the expected throttling policy', () => {
82+
const updateHandler = SocialLinkController.prototype.update;
83+
const limit = Reflect.getMetadata(THROTTLER_LIMIT + 'default', updateHandler);
84+
const ttl = Reflect.getMetadata(THROTTLER_TTL + 'default', updateHandler);
85+
expect(limit).toBe(5);
86+
expect(ttl).toBe(60000);
87+
});
88+
89+
it('list (read endpoint) has no @Throttle metadata', () => {
90+
const listHandler = SocialLinkController.prototype.list;
91+
const limit = Reflect.getMetadata(THROTTLER_LIMIT + 'default', listHandler);
92+
expect(limit).toBeUndefined();
93+
});
3994
});
4095

4196
it('configures create with the expected throttling policy', () => {
@@ -44,8 +99,13 @@ describe('SocialLinkController', () => {
4499
const limit: unknown = Reflect.getMetadata(THROTTLER_LIMIT + 'default', createHandler);
45100
const ttl: unknown = Reflect.getMetadata(THROTTLER_TTL + 'default', createHandler);
46101

47-
expect(limit).toBe(5);
48-
expect(ttl).toBe(60000);
102+
it('update has @ApiResponse for 404', () => {
103+
const meta = Reflect.getMetadata(
104+
'swagger/apiResponse',
105+
SocialLinkController.prototype.update,
106+
);
107+
expect(meta?.['404']).toBeDefined();
108+
});
49109
});
50110

51111
it('configures update with the expected throttling policy', () => {
@@ -54,8 +114,18 @@ describe('SocialLinkController', () => {
54114
const limit: unknown = Reflect.getMetadata(THROTTLER_LIMIT + 'default', updateHandler);
55115
const ttl: unknown = Reflect.getMetadata(THROTTLER_TTL + 'default', updateHandler);
56116

57-
expect(limit).toBe(5);
58-
expect(ttl).toBe(60000);
117+
controller.list(pagination);
118+
119+
expect(mockSocialLinksService.listSocialLinks).toHaveBeenCalledWith(pagination);
120+
});
121+
122+
it('propagates errors thrown by the service', () => {
123+
mockSocialLinksService.listSocialLinks.mockImplementationOnce(() => {
124+
throw new BadRequestException('Invalid pagination');
125+
});
126+
127+
expect(() => controller.list({ page: -1, limit: 0 })).toThrow(BadRequestException);
128+
});
59129
});
60130

61131
describe('create', () => {

0 commit comments

Comments
 (0)