fix update username
This commit is contained in:
parent
72801c5cf6
commit
5e4b777ab8
|
@ -14,25 +14,26 @@ export class AuthMessagerController {
|
||||||
@RabbitSubscribe({
|
@RabbitSubscribe({
|
||||||
exchange: 'user',
|
exchange: 'user',
|
||||||
routingKey: 'user.update',
|
routingKey: 'user.update',
|
||||||
|
queue: 'auth-user-update',
|
||||||
})
|
})
|
||||||
public async userUpdatedHandler(message: string) {
|
public async userUpdatedHandler(message: string) {
|
||||||
const updatedUser = JSON.parse(message);
|
const updatedUser = JSON.parse(message);
|
||||||
if (!updatedUser.hasOwnProperty('uuid')) throw new Error();
|
if (!updatedUser.hasOwnProperty('uuid')) throw new Error();
|
||||||
if (updatedUser.hasOwnProperty('email')) {
|
if (updatedUser.hasOwnProperty('email') && updatedUser.email) {
|
||||||
const updateUsernameRequest = new UpdateUsernameRequest();
|
const updateUsernameRequest = new UpdateUsernameRequest();
|
||||||
updateUsernameRequest.uuid = updatedUser.uuid;
|
updateUsernameRequest.uuid = updatedUser.uuid;
|
||||||
updateUsernameRequest.username = updatedUser.email;
|
updateUsernameRequest.username = updatedUser.email;
|
||||||
updateUsernameRequest.type = Type.EMAIL;
|
updateUsernameRequest.type = Type.EMAIL;
|
||||||
this._commandBus.execute(
|
await this._commandBus.execute(
|
||||||
new UpdateUsernameCommand(updateUsernameRequest),
|
new UpdateUsernameCommand(updateUsernameRequest),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (updatedUser.hasOwnProperty('phone')) {
|
if (updatedUser.hasOwnProperty('phone') && updatedUser.phone) {
|
||||||
const updateUsernameRequest = new UpdateUsernameRequest();
|
const updateUsernameRequest = new UpdateUsernameRequest();
|
||||||
updateUsernameRequest.uuid = updatedUser.uuid;
|
updateUsernameRequest.uuid = updatedUser.uuid;
|
||||||
updateUsernameRequest.username = updatedUser.phone;
|
updateUsernameRequest.username = updatedUser.phone;
|
||||||
updateUsernameRequest.type = Type.PHONE;
|
updateUsernameRequest.type = Type.PHONE;
|
||||||
this._commandBus.execute(
|
await this._commandBus.execute(
|
||||||
new UpdateUsernameCommand(updateUsernameRequest),
|
new UpdateUsernameCommand(updateUsernameRequest),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -41,12 +42,13 @@ export class AuthMessagerController {
|
||||||
@RabbitSubscribe({
|
@RabbitSubscribe({
|
||||||
exchange: 'user',
|
exchange: 'user',
|
||||||
routingKey: 'user.delete',
|
routingKey: 'user.delete',
|
||||||
|
queue: 'auth-user-delete',
|
||||||
})
|
})
|
||||||
public async userDeletedHandler(message: string) {
|
public async userDeletedHandler(message: string) {
|
||||||
const deletedUser = JSON.parse(message);
|
const deletedUser = JSON.parse(message);
|
||||||
if (!deletedUser.hasOwnProperty('uuid')) throw new Error();
|
if (!deletedUser.hasOwnProperty('uuid')) throw new Error();
|
||||||
const deleteAuthRequest = new DeleteAuthRequest();
|
const deleteAuthRequest = new DeleteAuthRequest();
|
||||||
deleteAuthRequest.uuid = deletedUser.uuid;
|
deleteAuthRequest.uuid = deletedUser.uuid;
|
||||||
this._commandBus.execute(new DeleteAuthCommand(deleteAuthRequest));
|
await this._commandBus.execute(new DeleteAuthCommand(deleteAuthRequest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,31 @@
|
||||||
import { CommandHandler } from '@nestjs/cqrs';
|
import { Mapper } from '@automapper/core';
|
||||||
|
import { InjectMapper } from '@automapper/nestjs';
|
||||||
|
import { BadRequestException } from '@nestjs/common';
|
||||||
|
import { CommandBus, CommandHandler } from '@nestjs/cqrs';
|
||||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||||
|
import { AddUsernameCommand } from '../../commands/add-username.command';
|
||||||
import { UpdateUsernameCommand } from '../../commands/update-username.command';
|
import { UpdateUsernameCommand } from '../../commands/update-username.command';
|
||||||
|
import { AddUsernameRequest } from '../dtos/add-username.request';
|
||||||
|
import { UpdateUsernameRequest } from '../dtos/update-username.request';
|
||||||
import { Username } from '../entities/username';
|
import { Username } from '../entities/username';
|
||||||
|
|
||||||
@CommandHandler(UpdateUsernameCommand)
|
@CommandHandler(UpdateUsernameCommand)
|
||||||
export class UpdateUsernameUseCase {
|
export class UpdateUsernameUseCase {
|
||||||
constructor(private readonly _usernameRepository: UsernameRepository) {}
|
constructor(
|
||||||
|
private readonly _usernameRepository: UsernameRepository,
|
||||||
|
private readonly _commandBus: CommandBus,
|
||||||
|
@InjectMapper() private readonly _mapper: Mapper,
|
||||||
|
) {}
|
||||||
|
|
||||||
async execute(command: UpdateUsernameCommand): Promise<Username> {
|
async execute(command: UpdateUsernameCommand): Promise<Username> {
|
||||||
const { uuid, username, type } = command.updateUsernameRequest;
|
const { uuid, username, type } = command.updateUsernameRequest;
|
||||||
|
if (!username) throw new BadRequestException();
|
||||||
|
// update username if it exists, otherwise create it
|
||||||
|
const existingUsername = await this._usernameRepository.findOne({
|
||||||
|
uuid,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
if (existingUsername) {
|
||||||
try {
|
try {
|
||||||
return await this._usernameRepository.updateWhere(
|
return await this._usernameRepository.updateWhere(
|
||||||
{
|
{
|
||||||
|
@ -25,4 +42,17 @@ export class UpdateUsernameUseCase {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const addUsernameRequest = this._mapper.map(
|
||||||
|
command.updateUsernameRequest,
|
||||||
|
UpdateUsernameRequest,
|
||||||
|
AddUsernameRequest,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
return await this._commandBus.execute(
|
||||||
|
new AddUsernameCommand(addUsernameRequest),
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { createMap, Mapper } from '@automapper/core';
|
||||||
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
|
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
|
||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { UsernamePresenter } from '../adapters/primaries/username.presenter';
|
import { UsernamePresenter } from '../adapters/primaries/username.presenter';
|
||||||
|
import { AddUsernameRequest } from '../domain/dtos/add-username.request';
|
||||||
|
import { UpdateUsernameRequest } from '../domain/dtos/update-username.request';
|
||||||
import { Username } from '../domain/entities/username';
|
import { Username } from '../domain/entities/username';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
|
@ -13,6 +15,7 @@ export class UsernameProfile extends AutomapperProfile {
|
||||||
override get profile() {
|
override get profile() {
|
||||||
return (mapper: any) => {
|
return (mapper: any) => {
|
||||||
createMap(mapper, Username, UsernamePresenter);
|
createMap(mapper, Username, UsernamePresenter);
|
||||||
|
createMap(mapper, UpdateUsernameRequest, AddUsernameRequest);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,56 @@ import { UpdateUsernameRequest } from '../../domain/dtos/update-username.request
|
||||||
import { UpdateUsernameCommand } from '../../commands/update-username.command';
|
import { UpdateUsernameCommand } from '../../commands/update-username.command';
|
||||||
import { Type } from '../../domain/dtos/type.enum';
|
import { Type } from '../../domain/dtos/type.enum';
|
||||||
import { UpdateUsernameUseCase } from '../../domain/usecases/update-username.usecase';
|
import { UpdateUsernameUseCase } from '../../domain/usecases/update-username.usecase';
|
||||||
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
import { UsernameProfile } from '../../mappers/username.profile';
|
||||||
|
import { BadRequestException } from '@nestjs/common';
|
||||||
|
|
||||||
|
const existingUsername = {
|
||||||
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
|
username: 'john.doe@email.com',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
};
|
||||||
|
|
||||||
const updateUsernameRequest: UpdateUsernameRequest = {
|
const updateUsernameRequest: UpdateUsernameRequest = {
|
||||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
username: 'johnny.doe@email.com',
|
username: 'johnny.doe@email.com',
|
||||||
type: Type.EMAIL,
|
type: Type.EMAIL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const newUsernameRequest: UpdateUsernameRequest = {
|
||||||
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
|
username: '+33611223344',
|
||||||
|
type: Type.PHONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
const invalidUpdateUsernameRequest: UpdateUsernameRequest = {
|
||||||
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
|
username: '',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
};
|
||||||
|
|
||||||
const updateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand(
|
const updateUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand(
|
||||||
updateUsernameRequest,
|
updateUsernameRequest,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const newUsernameCommand: UpdateUsernameCommand = new UpdateUsernameCommand(
|
||||||
|
newUsernameRequest,
|
||||||
|
);
|
||||||
|
|
||||||
|
const invalidUpdateUsernameCommand: UpdateUsernameCommand =
|
||||||
|
new UpdateUsernameCommand(invalidUpdateUsernameRequest);
|
||||||
|
|
||||||
const mockUsernameRepository = {
|
const mockUsernameRepository = {
|
||||||
updateWhere: jest.fn().mockResolvedValue(updateUsernameRequest),
|
findOne: jest.fn().mockResolvedValue(existingUsername),
|
||||||
|
updateWhere: jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValueOnce(updateUsernameRequest)
|
||||||
|
.mockResolvedValueOnce(newUsernameRequest)
|
||||||
|
.mockResolvedValueOnce(invalidUpdateUsernameRequest),
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockAddUsernameCommand = {
|
||||||
|
execute: jest.fn().mockResolvedValue(newUsernameRequest),
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('UpdateUsernameUseCase', () => {
|
describe('UpdateUsernameUseCase', () => {
|
||||||
|
@ -32,7 +70,12 @@ describe('UpdateUsernameUseCase', () => {
|
||||||
provide: UsernameRepository,
|
provide: UsernameRepository,
|
||||||
useValue: mockUsernameRepository,
|
useValue: mockUsernameRepository,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: CommandBus,
|
||||||
|
useValue: mockAddUsernameCommand,
|
||||||
|
},
|
||||||
UpdateUsernameUseCase,
|
UpdateUsernameUseCase,
|
||||||
|
UsernameProfile,
|
||||||
],
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
|
@ -54,5 +97,20 @@ describe('UpdateUsernameUseCase', () => {
|
||||||
expect(updatedUsername.username).toBe(updateUsernameRequest.username);
|
expect(updatedUsername.username).toBe(updateUsernameRequest.username);
|
||||||
expect(updatedUsername.type).toBe(updateUsernameRequest.type);
|
expect(updatedUsername.type).toBe(updateUsernameRequest.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create a new username', async () => {
|
||||||
|
const newUsername: Username = await updateUsernameUseCase.execute(
|
||||||
|
newUsernameCommand,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(newUsername.username).toBe(newUsernameRequest.username);
|
||||||
|
expect(newUsername.type).toBe(newUsernameRequest.type);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an exception if username is invalid', async () => {
|
||||||
|
await expect(
|
||||||
|
updateUsernameUseCase.execute(invalidUpdateUsernameCommand),
|
||||||
|
).rejects.toBeInstanceOf(BadRequestException);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -131,6 +131,7 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
|
||||||
|
|
||||||
return updatedEntity;
|
return updatedEntity;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
console.log('error', e);
|
||||||
if (e instanceof PrismaClientKnownRequestError) {
|
if (e instanceof PrismaClientKnownRequestError) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
PrismaClientKnownRequestError.name,
|
PrismaClientKnownRequestError.name,
|
||||||
|
|
Loading…
Reference in New Issue