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

#429: Implement GET /subscription_user Endpoint #580

Merged
merged 8 commits into from
Sep 10, 2024
39 changes: 39 additions & 0 deletions src/subscription-user/dto/get-subscription-user.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';
import { IsDefined, IsNotEmpty, IsOptional, IsString } from 'class-validator';

@Expose()
export class GetSubscriptionUserDto {
@ApiProperty()
@IsString()
@IsDefined()
@IsNotEmpty()
id: string;

@ApiProperty()
@IsString()
@IsDefined()
@IsNotEmpty()
subscriptionId: string;

@ApiProperty()
@IsString()
@IsDefined()
@IsNotEmpty()
@Expose()
subscriptionName: string;

@ApiProperty()
@IsString()
@IsDefined()
@IsNotEmpty()
subscriptionInfo: string;

@ApiProperty()
@IsDefined()
createdAt: Date;

@ApiProperty()
@IsOptional()
cancelledAt: Date | null;
}
21 changes: 20 additions & 1 deletion src/subscription-user/subscription-user.controller.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Body, Controller, Param, Patch, Post, Req, UseGuards } from '@nestjs/common';
import { Body, Controller, Get, Param, Patch, Post, Req, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger';
import { Request } from 'express';
import { UserEntity } from 'src/entities/user.entity';
import { mapToSubscriptionUserDtos } from 'src/utils/serialize';
import { FirebaseAuthGuard } from '../firebase/firebase-auth.guard';
import { ControllerDecorator } from '../utils/controller.decorator';
import { CreateSubscriptionUserDto } from './dto/create-subscription-user.dto';
import { GetSubscriptionUserDto } from './dto/get-subscription-user.dto';
import { UpdateSubscriptionUserDto } from './dto/update-subscription-user.dto';
import { ISubscriptionUser } from './subscription-user.interface';
import { SubscriptionUserService } from './subscription-user.service';
Expand All @@ -15,6 +17,23 @@ import { SubscriptionUserService } from './subscription-user.service';
export class SubscriptionUserController {
constructor(private readonly subscriptionUserService: SubscriptionUserService) {}

@Get('/')
@ApiBearerAuth('access-token')
@ApiOperation({
description: 'Returns all the subscriptions of the authenticated user.',
})
@UseGuards(FirebaseAuthGuard)
async getUserSubscriptions(@Req() req: Request): Promise<GetSubscriptionUserDto[]> {
const user = req['userEntity'] as UserEntity;
const userId = user.id;

const userSubscriptions = await this.subscriptionUserService.getSubscriptions(userId);

const subscriptionDtos = mapToSubscriptionUserDtos(userSubscriptions);

return subscriptionDtos;
}

@Post('/whatsapp')
@ApiBearerAuth('access-token')
@ApiOperation({
Expand Down
20 changes: 20 additions & 0 deletions src/subscription-user/subscription-user.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,24 @@ describe('SubscriptionUserService', () => {
]);
});
});

describe('getUserSubscriptions', () => {
it('should return a list of subscriptions for the given userId', async () => {
const result = await service.getSubscriptions(mockUserEntity.id);

expect(result).toMatchObject([mockSubscriptionUserEntity]);
});

it('should return an empty array if the user has no subscriptions', async () => {
mockedSubscriptionUserRepository.find.mockResolvedValueOnce([]);

const result = await service.getSubscriptions(mockUserEntity.id);

expect(result).toEqual([]);
expect(mockedSubscriptionUserRepository.find).toHaveBeenCalledWith({
where: { userId: mockUserEntity.id },
relations: ['subscription'],
});
});
});
});
15 changes: 15 additions & 0 deletions src/subscription-user/subscription-user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,19 @@ export class SubscriptionUserService {
);
}
}

async getSubscriptions(userId: string): Promise<SubscriptionUserEntity[]> {
try {
const userSubscriptions = await this.subscriptionUserRepository.find({
where: { userId: userId },
relations: ['subscription'],
});

this.logger.log(`User ${userId} has ${userSubscriptions.length} subscriptions`);

return userSubscriptions;
} catch (err) {
throw new HttpException(`getSubscriptions error - ${err}`, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
17 changes: 17 additions & 0 deletions src/utils/serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { PartnerAdminEntity } from 'src/entities/partner-admin.entity';
import { PartnerEntity } from 'src/entities/partner.entity';
import { IPartnerFeature } from 'src/partner-feature/partner-feature.interface';
import { IPartner } from 'src/partner/partner.interface';
import { GetSubscriptionUserDto } from 'src/subscription-user/dto/get-subscription-user.dto';
import { CourseUserEntity } from '../entities/course-user.entity';
import { PartnerAccessEntity } from '../entities/partner-access.entity';
import { SubscriptionUserEntity } from '../entities/subscription-user.entity';
Expand Down Expand Up @@ -203,3 +204,19 @@ export const formatSubscriptionObject = (
cancelledAt: userSubscription.cancelledAt,
};
};

export const mapToSubscriptionUserDtos = (
userSubscriptions: SubscriptionUserEntity[],
): GetSubscriptionUserDto[] => {
return userSubscriptions.map((subscriptionUser) => {
const dto = new GetSubscriptionUserDto();
dto.id = subscriptionUser.id;
dto.subscriptionId = subscriptionUser.subscription.id;
dto.subscriptionName = subscriptionUser.subscription.name;
dto.subscriptionInfo = subscriptionUser.subscription.info;
dto.createdAt = subscriptionUser.createdAt;
dto.cancelledAt = subscriptionUser.cancelledAt;
dto.subscriptionInfo = subscriptionUser.subscriptionInfo;
return dto;
});
};
Loading