Skip to content

Commit 2f1db47

Browse files
committed
feat(backend): social-links service tests, DTO validation, e2e coverage, pagination
1 parent 934bbe0 commit 2f1db47

10 files changed

Lines changed: 704 additions & 92 deletions

backend/src/creators/creators.controller.spec.ts

Lines changed: 166 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Test, TestingModule } from '@nestjs/testing';
2+
import { ThrottlerModule } from '@nestjs/throttler';
23
import { CreatorsController } from './creators.controller';
34
import { CreatorsService } from './creators.service';
45
import { CreatorDashboardService } from './creator-dashboard.service';
@@ -31,6 +32,9 @@ describe('CreatorsController', () => {
3132
mockDashboardService = mockDashboardServiceFactory();
3233

3334
const module: TestingModule = await Test.createTestingModule({
35+
imports: [
36+
ThrottlerModule.forRoot([{ name: 'default', ttl: 60000, limit: 100 }]),
37+
],
3438
controllers: [CreatorsController],
3539
providers: [
3640
{
@@ -73,8 +77,20 @@ describe('CreatorsController', () => {
7377

7478
it('should return array of plans', async () => {
7579
const mockPlans = [
76-
{ id: 1, creator: 'user1', asset: 'native', amount: '100', intervalDays: 30 },
77-
{ id: 2, creator: 'user2', asset: 'native', amount: '50', intervalDays: 7 },
80+
{
81+
id: 1,
82+
creator: 'user1',
83+
asset: 'native',
84+
amount: '100',
85+
intervalDays: 30,
86+
},
87+
{
88+
id: 2,
89+
creator: 'user2',
90+
asset: 'native',
91+
amount: '50',
92+
intervalDays: 7,
93+
},
7894
];
7995
mockCreatorsService.listCreators.mockResolvedValue(mockPlans);
8096

@@ -157,7 +173,13 @@ describe('CreatorsController', () => {
157173
it('should return paginated plans', async () => {
158174
const pagination = { page: 1, limit: 20 };
159175
const mockPlans = [
160-
{ id: 1, creator: 'user1', asset: 'native', amount: '100', intervalDays: 30 },
176+
{
177+
id: 1,
178+
creator: 'user1',
179+
asset: 'native',
180+
amount: '100',
181+
intervalDays: 30,
182+
},
161183
];
162184
const mockResponse = new PaginatedResponseDto(mockPlans, 20, null, false);
163185
mockCreatorsService.findAllPlans.mockReturnValue(mockResponse);
@@ -188,7 +210,13 @@ describe('CreatorsController', () => {
188210
const address = 'GBCQ6C7OXWTKJ7APCIQPKK6X4CQBFGWJKW35GD7H5GMVVDANQCXLSV7';
189211
const pagination = { page: 1, limit: 20 };
190212
const mockPlans = [
191-
{ id: 1, creator: address, asset: 'native', amount: '100', intervalDays: 30 },
213+
{
214+
id: 1,
215+
creator: address,
216+
asset: 'native',
217+
amount: '100',
218+
intervalDays: 30,
219+
},
192220
];
193221
const mockResponse = new PaginatedResponseDto(mockPlans, 20, null, false);
194222
mockCreatorsService.findCreatorPlans.mockReturnValue(mockResponse);
@@ -209,15 +237,19 @@ describe('CreatorsController', () => {
209237
subscriberCount: 10,
210238
};
211239
const mockDashboardService = controller['dashboardService'];
212-
jest.spyOn(mockDashboardService, 'getDashboard').mockReturnValue(mockDashboard as any);
240+
jest
241+
.spyOn(mockDashboardService, 'getDashboard')
242+
.mockReturnValue(mockDashboard as any);
213243

214244
await controller.getDashboard(address, query as any);
215245

216-
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith(address, query);
246+
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith(
247+
address,
248+
query,
249+
);
217250
});
218251
});
219252

220-
221253
describe('searchCreators', () => {
222254
describe('GET /creators endpoint exists and is accessible', () => {
223255
it('should have searchCreators method', () => {
@@ -246,7 +278,11 @@ describe('CreatorsController', () => {
246278
});
247279

248280
it('should accept query parameter cursor', async () => {
249-
const searchDto: SearchCreatorsDto = { q: '', cursor: 'alice', limit: 10 };
281+
const searchDto: SearchCreatorsDto = {
282+
q: '',
283+
cursor: 'alice',
284+
limit: 10,
285+
};
250286
const mockResponse = new PaginatedResponseDto([], 10, null, false);
251287
mockCreatorsService.searchCreators.mockResolvedValue(mockResponse);
252288

@@ -274,7 +310,11 @@ describe('CreatorsController', () => {
274310

275311
it('should accept all query parameters together', async () => {
276312
// Arrange
277-
const searchDto: SearchCreatorsDto = { q: 'alice', cursor: 'bob', limit: 15 };
313+
const searchDto: SearchCreatorsDto = {
314+
q: 'alice',
315+
cursor: 'bob',
316+
limit: 15,
317+
};
278318
const mockResponse = new PaginatedResponseDto([], 15, null, false);
279319
mockCreatorsService.searchCreators.mockResolvedValue(mockResponse);
280320

@@ -301,7 +341,12 @@ describe('CreatorsController', () => {
301341
bio: 'Test bio',
302342
},
303343
];
304-
const mockResponse = new PaginatedResponseDto(mockData, 10, 'testuser', false);
344+
const mockResponse = new PaginatedResponseDto(
345+
mockData,
346+
10,
347+
'testuser',
348+
false,
349+
);
305350
mockCreatorsService.searchCreators.mockResolvedValue(mockResponse);
306351

307352
// Act
@@ -326,7 +371,12 @@ describe('CreatorsController', () => {
326371
bio: 'Test bio',
327372
},
328373
];
329-
const mockResponse = new PaginatedResponseDto(mockData, 10, 'testuser', false);
374+
const mockResponse = new PaginatedResponseDto(
375+
mockData,
376+
10,
377+
'testuser',
378+
false,
379+
);
330380
mockCreatorsService.searchCreators.mockResolvedValue(mockResponse);
331381

332382
// Act
@@ -505,7 +555,11 @@ describe('CreatorsController', () => {
505555
describe('CreatorsService.searchCreators method is called', () => {
506556
it('should call service.searchCreators with correct parameters', async () => {
507557
// Arrange
508-
const searchDto: SearchCreatorsDto = { q: 'alice', cursor: 'bob', limit: 15 };
558+
const searchDto: SearchCreatorsDto = {
559+
q: 'alice',
560+
cursor: 'bob',
561+
limit: 15,
562+
};
509563
const mockResponse = new PaginatedResponseDto([], 15, null, false);
510564
mockCreatorsService.searchCreators.mockResolvedValue(mockResponse);
511565

@@ -544,7 +598,12 @@ describe('CreatorsController', () => {
544598
bio: 'Test bio',
545599
},
546600
];
547-
const mockResponse = new PaginatedResponseDto(mockData, 10, 'testuser', false);
601+
const mockResponse = new PaginatedResponseDto(
602+
mockData,
603+
10,
604+
'testuser',
605+
false,
606+
);
548607
mockCreatorsService.searchCreators.mockResolvedValue(mockResponse);
549608

550609
// Act
@@ -560,7 +619,13 @@ describe('CreatorsController', () => {
560619

561620
describe('createPlan', () => {
562621
it('should call service.createPlan with correct parameters', () => {
563-
const mockPlan = { id: 1, creator: 'creator1', asset: 'USDC', amount: '100', intervalDays: 30 };
622+
const mockPlan = {
623+
id: 1,
624+
creator: 'creator1',
625+
asset: 'USDC',
626+
amount: '100',
627+
intervalDays: 30,
628+
};
564629
mockCreatorsService.createPlan.mockReturnValue(mockPlan);
565630

566631
const result = controller.createPlan({
@@ -580,7 +645,13 @@ describe('CreatorsController', () => {
580645
});
581646

582647
it('should create plan with valid input', () => {
583-
const mockPlan = { id: 2, creator: 'creator2', asset: 'EURC', amount: '50', intervalDays: 7 };
648+
const mockPlan = {
649+
id: 2,
650+
creator: 'creator2',
651+
asset: 'EURC',
652+
amount: '50',
653+
intervalDays: 7,
654+
};
584655
mockCreatorsService.createPlan.mockReturnValue(mockPlan);
585656

586657
const result = controller.createPlan({
@@ -615,7 +686,13 @@ describe('CreatorsController', () => {
615686
it('should call service.findAllPlans with pagination', () => {
616687
const mockPlans = new PaginatedResponseDto(
617688
[
618-
{ id: 1, creator: 'creator1', asset: 'USDC', amount: '100', intervalDays: 30 },
689+
{
690+
id: 1,
691+
creator: 'creator1',
692+
asset: 'USDC',
693+
amount: '100',
694+
intervalDays: 30,
695+
},
619696
],
620697
20,
621698
'1',
@@ -625,15 +702,29 @@ describe('CreatorsController', () => {
625702

626703
const result = controller.getAllPlans({ limit: 20 });
627704

628-
expect(mockCreatorsService.findAllPlans).toHaveBeenCalledWith({ limit: 20 });
705+
expect(mockCreatorsService.findAllPlans).toHaveBeenCalledWith({
706+
limit: 20,
707+
});
629708
expect(result).toEqual(mockPlans);
630709
});
631710

632711
it('should return paginated plans', () => {
633712
const mockPlans = new PaginatedResponseDto(
634713
[
635-
{ id: 1, creator: 'creator1', asset: 'USDC', amount: '100', intervalDays: 30 },
636-
{ id: 2, creator: 'creator2', asset: 'EURC', amount: '50', intervalDays: 7 },
714+
{
715+
id: 1,
716+
creator: 'creator1',
717+
asset: 'USDC',
718+
amount: '100',
719+
intervalDays: 30,
720+
},
721+
{
722+
id: 2,
723+
creator: 'creator2',
724+
asset: 'EURC',
725+
amount: '50',
726+
intervalDays: 7,
727+
},
637728
],
638729
20,
639730
'2',
@@ -662,7 +753,15 @@ describe('CreatorsController', () => {
662753
describe('getPlans', () => {
663754
it('should call service.findCreatorPlans with creator and pagination', () => {
664755
const mockPlans = new PaginatedResponseDto(
665-
[{ id: 1, creator: 'creator1', asset: 'USDC', amount: '100', intervalDays: 30 }],
756+
[
757+
{
758+
id: 1,
759+
creator: 'creator1',
760+
asset: 'USDC',
761+
amount: '100',
762+
intervalDays: 30,
763+
},
764+
],
666765
20,
667766
'1',
668767
false,
@@ -671,17 +770,32 @@ describe('CreatorsController', () => {
671770

672771
const result = controller.getPlans('creator1', { limit: 20 });
673772

674-
expect(mockCreatorsService.findCreatorPlans).toHaveBeenCalledWith('creator1', {
675-
limit: 20,
676-
});
773+
expect(mockCreatorsService.findCreatorPlans).toHaveBeenCalledWith(
774+
'creator1',
775+
{
776+
limit: 20,
777+
},
778+
);
677779
expect(result).toEqual(mockPlans);
678780
});
679781

680782
it('should return creator plans when creator has plans', () => {
681783
const mockPlans = new PaginatedResponseDto(
682784
[
683-
{ id: 1, creator: 'creator1', asset: 'USDC', amount: '100', intervalDays: 30 },
684-
{ id: 2, creator: 'creator1', asset: 'EURC', amount: '50', intervalDays: 7 },
785+
{
786+
id: 1,
787+
creator: 'creator1',
788+
asset: 'USDC',
789+
amount: '100',
790+
intervalDays: 30,
791+
},
792+
{
793+
id: 2,
794+
creator: 'creator1',
795+
asset: 'EURC',
796+
amount: '50',
797+
intervalDays: 7,
798+
},
685799
],
686800
20,
687801
'2',
@@ -703,9 +817,12 @@ describe('CreatorsController', () => {
703817
const result = controller.getPlans('nonexistent', { limit: 20 });
704818

705819
expect(result.data.length).toBe(0);
706-
expect(mockCreatorsService.findCreatorPlans).toHaveBeenCalledWith('nonexistent', {
707-
limit: 20,
708-
});
820+
expect(mockCreatorsService.findCreatorPlans).toHaveBeenCalledWith(
821+
'nonexistent',
822+
{
823+
limit: 20,
824+
},
825+
);
709826
});
710827
});
711828

@@ -716,21 +833,31 @@ describe('CreatorsController', () => {
716833

717834
const result = controller.getDashboard('creator1', {});
718835

719-
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith('creator1', {});
836+
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith(
837+
'creator1',
838+
{},
839+
);
720840
expect(result).toEqual(mockDashboard);
721841
});
722842

723843
it('should return dashboard metrics for creator', () => {
724-
const mockDashboard = { totalEarnings: 5000, subscribers: 150, activeSubscriptions: 120 };
844+
const mockDashboard = {
845+
totalEarnings: 5000,
846+
subscribers: 150,
847+
activeSubscriptions: 120,
848+
};
725849
mockDashboardService.getDashboard.mockReturnValue(mockDashboard);
726850

727851
const result = controller.getDashboard('creator1', { days: '30' });
728852

729853
expect(result.totalEarnings).toBe(5000);
730854
expect(result.subscribers).toBe(150);
731-
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith('creator1', {
732-
days: '30',
733-
});
855+
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith(
856+
'creator1',
857+
{
858+
days: '30',
859+
},
860+
);
734861
});
735862

736863
it('should pass query parameters to dashboard service', async () => {
@@ -739,9 +866,12 @@ describe('CreatorsController', () => {
739866

740867
const result = await controller.getDashboard('creator1', { days: '90' });
741868

742-
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith('creator1', {
743-
days: '90',
744-
});
869+
expect(mockDashboardService.getDashboard).toHaveBeenCalledWith(
870+
'creator1',
871+
{
872+
days: '90',
873+
},
874+
);
745875
});
746876

747877
it('should handle dashboard not found error', () => {

0 commit comments

Comments
 (0)