Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/backend/src/users/dtos/updateUserInfo.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { IsString, IsPhoneNumber, IsOptional } from 'class-validator';

export class updateUserInfo {
@IsOptional()
@IsString()

Choose a reason for hiding this comment

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

Can we add @IsNotEmpty and @MaxLength(255) to this and the last name?

firstName?: string;

@IsOptional()
@IsString()
lastName?: string;

@IsOptional()
@IsString()

Choose a reason for hiding this comment

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

Can we also add @IsNotEmpty here too?

@IsPhoneNumber('US', {
message:
'phone must be a valid phone number (make sure all the digits are correct)',
})
phone?: string;
}
33 changes: 33 additions & 0 deletions apps/backend/src/users/users.controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { userSchemaDto } from './dtos/userSchema.dto';

import { Test, TestingModule } from '@nestjs/testing';
import { mock } from 'jest-mock-extended';
import { updateUserInfo } from './dtos/updateUserInfo.dto';

const mockUserService = mock<UsersService>();

Expand Down Expand Up @@ -116,6 +117,38 @@ describe('UsersController', () => {
});
});

describe('PUT :id/info', () => {
it('should update user info with valid information', async () => {
const updatedUser = {

Choose a reason for hiding this comment

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

Can we type this? I would suggest moving the updateUserSchema to lin 122, and then making the value for each in the updatedUser `updateUserSchema.{firstName, lastName, phone}

...mockUser1,
firstName: 'UpdatedFirstName',
lastName: 'UpdatedLastName',
phone: '777-777-7777',
};
mockUserService.update.mockResolvedValue(updatedUser);

const updateUserSchema: updateUserInfo = {
firstName: 'UpdatedFirstName',
lastName: 'UpdatedLastName',
phone: '777-777-7777',
};
const result = await controller.updateInfo(1, updateUserSchema);

expect(result).toEqual(updatedUser);
expect(mockUserService.update).toHaveBeenCalledWith(1, updateUserSchema);
});

it('should update user info with defaults', async () => {
mockUserService.update.mockResolvedValue(mockUser1);

const updateUserSchema: Partial<updateUserInfo> = {};
const result = await controller.updateInfo(1, updateUserSchema);

expect(result).toEqual(mockUser1);
expect(mockUserService.update).toHaveBeenCalledWith(1, updateUserSchema);
});

Choose a reason for hiding this comment

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

Can we add one more test here where we just update with the first name and last name, to test that an actual Partial<updateUserInfo> works? I only ask this since our logic for creating the body we pass into the service is in the controller.

});

describe('POST /api/users', () => {
it('should create a new user with all required fields', async () => {
const createUserSchema: userSchemaDto = {
Expand Down
16 changes: 16 additions & 0 deletions apps/backend/src/users/users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { User } from './user.entity';
import { Role } from './types';
import { VOLUNTEER_ROLES } from './types';
import { userSchemaDto } from './dtos/userSchema.dto';
import { updateUserInfo } from './dtos/updateUserInfo.dto';
//import { CurrentUserInterceptor } from '../interceptors/current-user.interceptor';

@Controller('users')
Expand Down Expand Up @@ -51,6 +52,21 @@ export class UsersController {
return this.usersService.update(id, { role: role as Role });
}

@Put(':id/info')
async updateInfo(
@Param('id', ParseIntPipe) id: number,
@Body() updateUserInfo: updateUserInfo,
) {

Choose a reason for hiding this comment

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

Can we give this a Promise<User> return type?

const { firstName, lastName, phone } = updateUserInfo;

const updateData: Partial<User> = {};
if (firstName !== undefined) updateData.firstName = firstName;
if (lastName !== undefined) updateData.lastName = lastName;
if (phone !== undefined) updateData.phone = phone;

return this.usersService.update(id, updateData);
}

@Post('/')
async createUser(@Body() createUserDto: userSchemaDto): Promise<User> {
const { email, firstName, lastName, phone, role } = createUserDto;
Expand Down