Skip to content

Commit

Permalink
Implement getUserProfile (#25)
Browse files Browse the repository at this point in the history
* Implement getUserProfile

* Fix test suit

* Check role before findSportArea
  • Loading branch information
Arnan-Dee authored Nov 14, 2023
1 parent 2fe473f commit 5837e9f
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 7 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
proto:
protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto -I=./src/proto --ts_proto_out=./src/auth src/proto/auth.proto --ts_proto_opt=nestJs=true --ts_proto_opt=fileSuffix=.pb
protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto -I=./src/proto --ts_proto_out=./src/user src/proto/user.proto --ts_proto_opt=nestJs=true --ts_proto_opt=fileSuffix=.pb

server:
yarn start:dev
Expand Down
12 changes: 12 additions & 0 deletions src/file/file.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { ClientGrpc } from '@nestjs/microservices';
import { catchError, firstValueFrom } from 'rxjs';
import {
FileServiceClient,
GetSignedURLRequest,
GetSignedURLResponse,
UploadFileRequest,
UploadFileResponse,
} from './file.pb';
Expand All @@ -26,4 +28,14 @@ export class FileService {
),
);
}
async getSignedUrl(request: GetSignedURLRequest): Promise<GetSignedURLResponse> {
return await firstValueFrom(
this.fileClient.getSignedUrl(request).pipe(
catchError((error) => {
this.logger.error(error);
throw error;
}),
),
);
}
}
15 changes: 15 additions & 0 deletions src/proto/user.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package user;

service UserService {
rpc GetUserSportArea(GetUserSportAreaRequest) returns (GetUserSportAreaResponse) {}
rpc GetUserProfile(GetUserProfileRequest) returns (GetUserProfileResponse) {}
}

message GetUserSportAreaRequest {
Expand All @@ -13,4 +14,18 @@ message GetUserSportAreaRequest {
message GetUserSportAreaResponse {
string userId = 1;
string sportAreaId =2;
}

message GetUserProfileRequest {
string userId = 1;
}

message GetUserProfileResponse {
string id = 1;
string firstName = 2;
string lastName = 3;
string email = 4;
string profileUrl = 5;
string role = 6;
string sportAreaId = 7;
}
10 changes: 9 additions & 1 deletion src/repository/sportAreaList.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { UserRepository } from './user.repository';

@Injectable()
export class SportAreaListRepository {
constructor(private db: PrismaService) {}
constructor(private db: PrismaService) { }

async addSportArea(
updateInfo: UpdateUserSportAreaRequest,
Expand All @@ -25,4 +25,12 @@ export class SportAreaListRepository {
where: { SportAreaId: sportAreaId },
});
}

async findSportAreaByUser(userId: string): Promise<SportArea> {
return await this.db.sportArea.findFirst({
where: {
userId: userId
}
})
}
}
2 changes: 2 additions & 0 deletions src/user/user.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ describe('UserController', () => {
findAllUsers: jest.fn(),
banUser: jest.fn(),
unbanUser: jest.fn(),
getUserProfile: jest.fn(),

};

beforeEach(async () => {
Expand Down
13 changes: 11 additions & 2 deletions src/user/user.controller.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
import { UserService } from './user.service';
import { User } from 'src/model/user.dto';
import { GetUserSportAreaRequest, GetUserSportAreaResponse } from './user.pb';
import { GetUserProfileRequest, GetUserProfileResponse, GetUserSportAreaRequest, GetUserSportAreaResponse } from './user.pb';
import { GrpcMethod } from '@nestjs/microservices';

@Controller('user')
export class UserController {
constructor(private userService: UserService) {}
constructor(private userService: UserService) { }

@Get()
findAllUsers() {
Expand All @@ -29,4 +29,13 @@ export class UserController {
): Promise<GetUserSportAreaResponse> {
return this.userService.getUserSportArea(request);
}

@GrpcMethod('UserService', 'GetUserProfile')
getUserProfile(
request: GetUserProfileRequest,
): Promise<GetUserProfileResponse> {
return this.userService.getUserProfile(request);
}


}
5 changes: 3 additions & 2 deletions src/user/user.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { UserService } from './user.service';
import { UserRepository } from 'src/repository/user.repository';
import { PrismaModule } from 'src/prisma/prisma.module';
import { SportAreaListRepository } from '../repository/sportAreaList.repository';
import { FileModule } from 'src/file/file.module';

@Module({
imports: [PrismaModule],
imports: [PrismaModule, FileModule],
controllers: [UserController],
providers: [UserService, UserRepository, SportAreaListRepository],
})
export class UserModule {}
export class UserModule { }
22 changes: 21 additions & 1 deletion src/user/user.pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,41 @@ export interface GetUserSportAreaResponse {
sportAreaId: string;
}

export interface GetUserProfileRequest {
userId: string;
}

export interface GetUserProfileResponse {
id: string;
firstName: string;
lastName: string;
email: string;
profileUrl: string;
role: string;
sportAreaId: string;
}

export const USER_PACKAGE_NAME = "user";

export interface UserServiceClient {
getUserSportArea(request: GetUserSportAreaRequest): Observable<GetUserSportAreaResponse>;

getUserProfile(request: GetUserProfileRequest): Observable<GetUserProfileResponse>;
}

export interface UserServiceController {
getUserSportArea(
request: GetUserSportAreaRequest,
): Promise<GetUserSportAreaResponse> | Observable<GetUserSportAreaResponse> | GetUserSportAreaResponse;

getUserProfile(
request: GetUserProfileRequest,
): Promise<GetUserProfileResponse> | Observable<GetUserProfileResponse> | GetUserProfileResponse;
}

export function UserServiceControllerMethods() {
return function (constructor: Function) {
const grpcMethods: string[] = ["getUserSportArea"];
const grpcMethods: string[] = ["getUserSportArea", "getUserProfile"];
for (const method of grpcMethods) {
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
GrpcMethod("UserService", method)(constructor.prototype[method], method, descriptor);
Expand Down
10 changes: 10 additions & 0 deletions src/user/user.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ import { Test, TestingModule } from '@nestjs/testing';
import { UserService } from './user.service';
import { UserRepository } from '../repository/user.repository';
import { SportAreaListRepository } from '../repository/sportAreaList.repository';
import { FileService } from '../file/file.service';

describe('UserService', () => {
let service: UserService;
const mockUserRepository = {
findUserById: jest.fn(),
update: jest.fn(),
exclude: jest.fn(),

};
const mockFileService = {

}

const mockSportAreaListRepo = {};

Expand All @@ -25,6 +30,11 @@ describe('UserService', () => {
provide: SportAreaListRepository,
useValue: mockSportAreaListRepo,
},
{
provide: FileService,
useValue: mockFileService,

}
],
}).compile();

Expand Down
35 changes: 34 additions & 1 deletion src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@ import {
UserServiceController,
GetUserSportAreaRequest,
GetUserSportAreaResponse,
GetUserProfileRequest,
GetUserProfileResponse,
} from './user.pb';
import { SportAreaListRepository } from '../repository/sportAreaList.repository';
import { status } from '@grpc/grpc-js';
import { RpcException } from '@nestjs/microservices';
import { FileService } from '../file/file.service';
import { use } from 'passport';

@Injectable()
export class UserService implements UserServiceController {
constructor(
private userRepo: UserRepository,
private sportAreaListRepo: SportAreaListRepository,
) {}
private fileService: FileService,
) { }

findAllUsers() {
try {
Expand Down Expand Up @@ -97,4 +102,32 @@ export class UserService implements UserServiceController {
throw err;
}
}

async getUserProfile(request: GetUserProfileRequest): Promise<GetUserProfileResponse> {
try {
const userId = request.userId
let user = await this.userRepo.findUserById(userId);
let userSportArea = ((user.role === 'USER') ? null : await this.sportAreaListRepo.findSportAreaByUser(userId))
const photoURL = ((user.photoURL == null) ? (await this.fileService.getSignedUrl({ filename: user.photoFileName, userId: userId })).url : user.photoURL)
return {
id: user.id,
firstName: user.firstName,
lastName: user.lastName,
email: user.email,
profileUrl: photoURL,
role: user.role,
sportAreaId: ((userSportArea == null) ? null : userSportArea.SportAreaId),
}

} catch (err: any) {
console.log(err);
if (!(err instanceof RpcException)) {
throw new RpcException({
code: status.INTERNAL,
message: 'internal server error cant get user profile',
});
}
throw err;
}
}
}

0 comments on commit 5837e9f

Please sign in to comment.