Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implemented pagination to getAllBilling Plans Endpoint #1316

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from
4 changes: 0 additions & 4 deletions .husky/pre-commit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has been deleted

This file was deleted.

10 changes: 8 additions & 2 deletions src/modules/billing-plans/billing-plan.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Delete,
HttpCode,
HttpStatus,
Query
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { SuperAdminGuard } from '../../guards/super-admin.guard';
Expand Down Expand Up @@ -40,8 +41,13 @@ export class BillingPlanController {
@skipAuth()
@getAllBillingPlansDocs()
@Get('/')
async getAllBillingPlans() {
return this.billingPlanService.getAllBillingPlans();
async getAllBillingPlans(
@Query('page') page: string,
@Query('limit') limit: string, )
{
const pageNumber = page ? parseInt(page, 10) : 1;
const limitNumber = limit ? parseInt(limit, 10) : 10;
return this.billingPlanService.getAllBillingPlans(pageNumber, limitNumber);
}

@skipAuth()
Expand Down
16 changes: 13 additions & 3 deletions src/modules/billing-plans/billing-plan.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,26 @@ export class BillingPlanService {
};
}

async getAllBillingPlans() {
const allPlans = await this.billingPlanRepository.find();
async getAllBillingPlans(page: number = 1, limit: number = 10) {
const skip = (page - 1) * limit;
const take = limit;

const [allPlans, total] = await this.billingPlanRepository.findAndCount({
skip,
take,
});

if (allPlans.length === 0) {
throw new NotFoundException('No billing plans found');
}
const plans = allPlans.map(plan => BillingPlanMapper.mapToResponseFormat(plan));

return {
message: 'Billing plans retrieved successfully',
data: plans,
data: {
plans,
total,
},
};
}

Expand Down
27 changes: 24 additions & 3 deletions src/modules/billing-plans/docs/billing-plan-docs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { applyDecorators } from '@nestjs/common';
import { BillingPlanDto } from '../dto/billing-plan.dto';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiQuery} from '@nestjs/swagger';
import { BillingPlan } from '../entities/billing-plan.entity';

export function createBillingPlanDocs() {
Expand All @@ -15,8 +15,29 @@ export function createBillingPlanDocs() {

export function getAllBillingPlansDocs() {
return applyDecorators(
ApiOperation({ summary: 'Get all billing plans' }),
ApiResponse({ status: 200, description: 'Billing plans retrieved successfully.', type: [BillingPlanDto] }),
ApiOperation({ summary: 'Get all billing plans (paginated)' }),
ApiQuery({ name: 'page', required: false, description: 'Page number (default: 1)' }),
ApiQuery({ name: 'limit', required: false, description: 'Number of items per page (default: 10)' }),
ApiResponse({
status: 200,
description: 'Billing plans retrieved successfully.',
schema: {
type: 'object',
properties: {
message: { type: 'string', example: 'Billing plans retrieved successfully' },
data: {
type: 'object',
properties: {
plans: {
type: 'array',
items: { type: 'object', $ref: '#/components/schemas/BillingPlanDto' }, // Use a $ref to your BillingPlanDto schema
},
total: { type: 'number', example: 123 },
},
},
},
},
}),
ApiResponse({ status: 404, description: 'No billing plans found.' })
);
}
Expand Down
39 changes: 27 additions & 12 deletions src/modules/billing-plans/tests/billing-plan.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ describe('BillingPlanService', () => {
});

describe('getAllBillingPlans', () => {
it('should return all billing plans', async () => {
it('should return paginated billing plans', async () => {
const billingPlans = [
{
id: '1',
Expand Down Expand Up @@ -105,25 +105,40 @@ describe('BillingPlanService', () => {
expirationDate: new Date(),
email: '[email protected]',
},
];

jest.spyOn(repository, 'find').mockResolvedValue(billingPlans as BillingPlan[]);

const result = await service.getAllBillingPlans();

];

const total = 2; // Total number of billing plans in the database

// Mock findAndCount to return paginated results
jest.spyOn(repository, 'findAndCount').mockResolvedValue([billingPlans as BillingPlan[], total]);

const result = await service.getAllBillingPlans(1, 10);

// Verify the response structure
expect(result).toEqual({
message: 'Billing plans retrieved successfully',
data: billingPlans.map(plan => BillingPlanMapper.mapToResponseFormat(plan)),
data: {
plans: billingPlans.map(plan => BillingPlanMapper.mapToResponseFormat(plan)),
total,
},
});

// Verify that findAndCount was called with the correct pagination parameters
expect(repository.findAndCount).toHaveBeenCalledWith({
skip: 0, // (page - 1) * limit = (1 - 1) * 10 = 0
take: 10, // limit = 10
});
});

it('should throw a NotFoundException if no billing plans are found', async () => {
jest.spyOn(repository, 'find').mockResolvedValue([]);

await expect(service.getAllBillingPlans()).rejects.toThrow(NotFoundException);
// Mock findAndCount to return an empty array
jest.spyOn(repository, 'findAndCount').mockResolvedValue([[], 0]);

await expect(service.getAllBillingPlans(1, 10)).rejects.toThrow(NotFoundException);
});
});

describe('getSingleBillingPlan', () => {
it('should return a single billing plan', async () => {
const billingPlan = {
Expand Down