diff --git a/api/src/modules/users/users.controller.ts b/api/src/modules/users/users.controller.ts index dda9f334..1cae90d1 100644 --- a/api/src/modules/users/users.controller.ts +++ b/api/src/modules/users/users.controller.ts @@ -43,13 +43,13 @@ export class UsersController { }); } - // @TsRestHandler(c.updateMe) - // async update(@GetUser() user: User): Promise { - // return tsRestHandler(c.updateMe, async () => { - // const user = await this.usersService.update(user.id, dto); - // return { body: { data: user }, status: HttpStatus.CREATED }; - // }); - // } + @TsRestHandler(c.updateMe) + async update(@GetUser() user: User): Promise { + return tsRestHandler(c.updateMe, async ({ body }) => { + const updatedUser = await this.usersService.update(user.id, body); + return { body: { data: updatedUser }, status: HttpStatus.CREATED }; + }); + } @TsRestHandler(c.deleteMe) async deleteMe(@GetUser() user: User): Promise { diff --git a/api/test/integration/users/users-me.spec.ts b/api/test/integration/users/users-me.spec.ts index 649bc2e1..f1377605 100644 --- a/api/test/integration/users/users-me.spec.ts +++ b/api/test/integration/users/users-me.spec.ts @@ -6,8 +6,6 @@ import { usersContract } from '@shared/contracts/users.contract'; describe('Users ME (e2e)', () => { let testManager: TestManager; - let authToken: string; - let testUser: User; beforeAll(async () => { testManager = await TestManager.createTestManager(); @@ -15,10 +13,6 @@ describe('Users ME (e2e)', () => { beforeEach(async () => { await testManager.clearDatabase(); - - const { jwtToken, user } = await testManager.setUpTestUser(); - authToken = jwtToken; - testUser = user; }); afterAll(async () => { @@ -74,20 +68,21 @@ describe('Users ME (e2e)', () => { expect(newToken).toBeDefined(); }); - it('should update a user', async () => { + it('should update a user name', async () => { const user = await createUser(testManager.getDataSource(), { email: 'user@test.com', }); const { jwtToken } = await testManager.logUserIn(user); - const updatedUser = { email: 'new@mail.com' }; + const newName = 'newName'; const response = await testManager .request() - .patch('/users/' + user.id) - .send(updatedUser) + .patch(usersContract.updateMe.path) + .send({ name: newName }) .set('Authorization', `Bearer ${jwtToken}`); expect(response.status).toBe(201); - expect(response.body.data.email).toEqual(updatedUser.email); + expect(response.body.data.id).toEqual(user.id); + expect(response.body.data.name).toEqual(newName); // Previous token should work after updating the user's email const userMeResponse = await testManager @@ -96,6 +91,30 @@ describe('Users ME (e2e)', () => { .set('Authorization', `Bearer ${jwtToken}`); expect(userMeResponse.status).toBe(200); - expect(userMeResponse.body.data.email).toEqual(updatedUser.email); + expect(userMeResponse.body.data.name).toEqual(newName); + }); + + it('should delete my own user', async () => { + const users: User[] = []; + for (const n of Array(3).keys()) { + users.push( + await testManager.mocks().createUser({ email: `user${n}@test.com` }), + ); + } + const user = users[0]; + const { jwtToken } = await testManager.logUserIn(user); + const response = await testManager + .request() + .delete(usersContract.deleteMe.path) + .set('Authorization', `Bearer ${jwtToken}`); + + expect(response.status).toBe(HttpStatus.OK); + expect(response.body).toEqual({}); + const foundUser = await testManager + .getDataSource() + .getRepository(User) + .findOneBy({ id: user.id }); + + expect(foundUser).toBeNull(); }); }); diff --git a/shared/contracts/users.contract.ts b/shared/contracts/users.contract.ts index 3095aa10..078bfe05 100644 --- a/shared/contracts/users.contract.ts +++ b/shared/contracts/users.contract.ts @@ -47,12 +47,4 @@ export const usersContract = contract.router({ }, body: null, }, - resetPassword: { - method: "POST", - path: "/users/me/password/reset", - responses: { - 200: contract.type(), - }, - body: PasswordSchema, - }, }); diff --git a/shared/dtos/users/update-user.dto.ts b/shared/dtos/users/update-user.dto.ts index 2304f881..caa93e8f 100644 --- a/shared/dtos/users/update-user.dto.ts +++ b/shared/dtos/users/update-user.dto.ts @@ -1,7 +1,4 @@ -import { IsEmail, IsNotEmpty } from 'class-validator'; +import { z } from "zod"; +import { UpdateUserSchema } from "@shared/schemas/users/update-user.schema"; -export class UpdateUserDto { - @IsEmail() - @IsNotEmpty() - email: string; -} \ No newline at end of file +export type UpdateUserDto = z.infer; diff --git a/shared/schemas/users/create-user.schema.ts b/shared/schemas/users/create-user.schema.ts index d2274a7f..15c68fa6 100644 --- a/shared/schemas/users/create-user.schema.ts +++ b/shared/schemas/users/create-user.schema.ts @@ -5,5 +5,3 @@ export const CreateUserSchema = z.object({ name: z.string().optional(), partnerName: z.string(), }); - -export type CreateUserDto = z.infer; diff --git a/shared/schemas/users/update-user.schema.ts b/shared/schemas/users/update-user.schema.ts new file mode 100644 index 00000000..13cfd6a9 --- /dev/null +++ b/shared/schemas/users/update-user.schema.ts @@ -0,0 +1,5 @@ +import { z } from "zod"; + +export const UpdateUserSchema = z.object({ + name: z.string().optional(), +});