Skip to content

Commit 6a0998e

Browse files
Merge pull request #182 from CollActionteam/feature/paginated-commitments-api
Implement getAllCommitments Query to get paginated commitments
2 parents 980825b + bf6f7f1 commit 6a0998e

4 files changed

Lines changed: 112 additions & 4 deletions

File tree

src/api/rest/commitments/v1/controller/commitment.controller.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
import { Body, Controller, Delete, Param, Patch, Post } from '@nestjs/common';
2-
import { ApiBody, ApiTags } from '@nestjs/swagger';
1+
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from '@nestjs/common';
2+
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
33
import { ICQRSHandler } from '@common/cqrs';
44
import { CreateCommitmentCommand, DeleteCommitmentCommand, UpdateCommitmentCommand } from '@modules/commitment';
5-
import { Identifiable } from '@domain/core';
6-
import { CreateCommitmentDto, UpdateCommitmentDto } from '@infrastructure/commitment';
5+
import { Identifiable, IPaginatedList } from '@domain/core';
6+
import { CreateCommitmentDto, PaginatedCommitmentResponse, UpdateCommitmentDto } from '@infrastructure/commitment';
77
import { FirebaseGuard } from '@modules/auth/decorators';
88
import { UserRole } from '@domain/auth/enum';
9+
import { PaginationDto } from '@infrastructure/pagination';
10+
import { ListCommitmentsQuery } from '@modules/commitment/cqrs/query/list-commitments.query';
11+
import { ICommitment } from '@domain/commitment';
912

1013
@Controller('v1/commitments')
1114
@ApiTags('Commitment')
@@ -31,4 +34,15 @@ export class CommitmentController {
3134
async updateCommitment(@Param('id') id: string, @Body() updateDto: UpdateCommitmentDto): Promise<Identifiable> {
3235
return await this.cqrsHandler.execute(UpdateCommitmentCommand, { id, updateDto });
3336
}
37+
@Get()
38+
@ApiOperation({ summary: 'Retrieve a paginated list of Commitments' })
39+
@ApiResponse({
40+
status: 200,
41+
description: 'Returns the found Commitments if any',
42+
type: PaginatedCommitmentResponse,
43+
})
44+
@FirebaseGuard(UserRole.MODERATOR, UserRole.ADMIN)
45+
async getAllCommitments(@Query() pagination: PaginationDto, @Query('tags') tags: string[]): Promise<IPaginatedList<ICommitment>> {
46+
return this.cqrsHandler.fetch(ListCommitmentsQuery, { ...pagination, filter: { tags } });
47+
}
3448
}

src/infrastructure/commitment/dto/commitment.dto.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,19 @@ export class CrowdActionCommitmentDto implements Omit<ICommitment, 'id' | 'creat
102102
@ApiProperty({ name: 'blocks', required: false })
103103
readonly blocks?: string[] | undefined;
104104
}
105+
export class PaginatedCommitmentResponse {
106+
@ApiProperty({ type: [GetCommitmentDto] })
107+
readonly items: GetCommitmentDto[];
108+
109+
@ApiProperty({ example: 1 })
110+
readonly page: number;
111+
112+
@ApiProperty({ example: 10 })
113+
readonly pageSize: number;
114+
115+
@ApiProperty({ example: 1 })
116+
readonly totalPages: number;
117+
118+
@ApiProperty({ example: 1 })
119+
readonly totalItems: number;
120+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { IPaginationQueryArgs, IQuery, paginate } from '@common/cqrs';
3+
import { FindCriteria } from '@core/repository.interface';
4+
import { ICommitment, ICommitmentRepository, QueryCommitment } from '@domain/commitment';
5+
import { IPaginatedList } from '@domain/core';
6+
7+
@Injectable()
8+
export class ListCommitmentsQuery implements IQuery<IPaginationQueryArgs<FindCriteria<QueryCommitment>>> {
9+
constructor(private readonly commitmentRepository: ICommitmentRepository) {}
10+
11+
async handle(filter: IPaginationQueryArgs<FindCriteria<QueryCommitment>>): Promise<IPaginatedList<ICommitment>> {
12+
return paginate(filter, this.commitmentRepository);
13+
}
14+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { connect, Connection, Model } from 'mongoose';
2+
import { getModelToken } from '@nestjs/mongoose';
3+
import { MongoMemoryServer } from 'mongodb-memory-server';
4+
import { Test } from '@nestjs/testing';
5+
import { ListCommitmentsQuery } from '@modules/commitment/cqrs/query/list-commitments.query';
6+
import { CommitmentPersistence, CommitmentRepository, CommitmentSchema } from '@infrastructure/mongo';
7+
import { CQRSHandler, CQRSModule, ICQRSHandler } from '@common/cqrs';
8+
import { CreateCommitmentStub } from '@modules/commitment/cqrs/tests/create-commitment.command.spec';
9+
import { CreateCommitmentCommand } from '@modules/commitment';
10+
import { ICommitmentRepository } from '@domain/commitment';
11+
12+
describe('ListCommitmentsQuery', () => {
13+
let listCommitmentsQuery: ListCommitmentsQuery;
14+
let commitmentCommand: CreateCommitmentCommand;
15+
let CommitmentModel: Model<CommitmentPersistence>;
16+
let mongod: MongoMemoryServer;
17+
let mongoConnection: Connection;
18+
beforeAll(async () => {
19+
mongod = await MongoMemoryServer.create();
20+
const uri = mongod.getUri();
21+
mongoConnection = (await connect(uri)).connection;
22+
CommitmentModel = mongoConnection.model(CommitmentPersistence.name, CommitmentSchema);
23+
const moduleRef = await Test.createTestingModule({
24+
imports: [CQRSModule],
25+
providers: [
26+
ListCommitmentsQuery,
27+
CreateCommitmentCommand,
28+
{ provide: ICQRSHandler, useClass: CQRSHandler },
29+
{ provide: ICommitmentRepository, useClass: CommitmentRepository },
30+
{ provide: getModelToken(CommitmentPersistence.name), useValue: CommitmentModel },
31+
],
32+
}).compile();
33+
listCommitmentsQuery = moduleRef.get<ListCommitmentsQuery>(ListCommitmentsQuery);
34+
commitmentCommand = moduleRef.get<CreateCommitmentCommand>(CreateCommitmentCommand);
35+
});
36+
afterAll(async () => {
37+
await mongoConnection.dropDatabase();
38+
await mongoConnection.close();
39+
await mongod.stop();
40+
});
41+
afterEach(async () => {
42+
const collections = mongoConnection.collections;
43+
for (const key in collections) {
44+
const collection = collections[key];
45+
await collection.deleteMany({});
46+
}
47+
});
48+
describe('getAllCommitmentsQuery', () => {
49+
it('should find all commitments', async () => {
50+
const commitment = CreateCommitmentStub();
51+
await commitmentCommand.execute(commitment);
52+
const result = await listCommitmentsQuery.handle({
53+
filter: { tags: ['FOOD'] },
54+
page: 1,
55+
pageSize: 1,
56+
});
57+
expect(result).toBeDefined();
58+
expect(result?.items?.length).toEqual(1);
59+
expect(result?.pageInfo?.pageSize).toEqual(1);
60+
expect(result?.pageInfo?.totalPages).toEqual(1);
61+
expect(result?.pageInfo?.totalItems).toEqual(1);
62+
});
63+
});
64+
});

0 commit comments

Comments
 (0)