update username
This commit is contained in:
parent
28c6ca0f63
commit
805a7fe24d
|
@ -19,11 +19,14 @@ import { AddUsernameGrpcController } from './interface/grpc-controllers/add-user
|
||||||
import { AddUsernameService } from './core/application/commands/add-username/add-username.service';
|
import { AddUsernameService } from './core/application/commands/add-username/add-username.service';
|
||||||
import { DeleteUsernameGrpcController } from './interface/grpc-controllers/delete-username.grpc.controller';
|
import { DeleteUsernameGrpcController } from './interface/grpc-controllers/delete-username.grpc.controller';
|
||||||
import { DeleteUsernameService } from './core/application/commands/delete-username/delete-username.service';
|
import { DeleteUsernameService } from './core/application/commands/delete-username/delete-username.service';
|
||||||
|
import { UpdateUsernameGrpcController } from './interface/grpc-controllers/update-username.grpc.controller';
|
||||||
|
import { UpdateUsernameService } from './core/application/commands/update-username/update-username.service';
|
||||||
|
|
||||||
const grpcControllers = [
|
const grpcControllers = [
|
||||||
CreateAuthenticationGrpcController,
|
CreateAuthenticationGrpcController,
|
||||||
DeleteAuthenticationGrpcController,
|
DeleteAuthenticationGrpcController,
|
||||||
AddUsernameGrpcController,
|
AddUsernameGrpcController,
|
||||||
|
UpdateUsernameGrpcController,
|
||||||
DeleteUsernameGrpcController,
|
DeleteUsernameGrpcController,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -31,6 +34,7 @@ const commandHandlers: Provider[] = [
|
||||||
CreateAuthenticationService,
|
CreateAuthenticationService,
|
||||||
DeleteAuthenticationService,
|
DeleteAuthenticationService,
|
||||||
AddUsernameService,
|
AddUsernameService,
|
||||||
|
UpdateUsernameService,
|
||||||
DeleteUsernameService,
|
DeleteUsernameService,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { Command, CommandProps } from '@mobicoop/ddd-library';
|
||||||
|
import { Username } from '../../types/username';
|
||||||
|
|
||||||
|
export class UpdateUsernameCommand extends Command {
|
||||||
|
readonly userId: string;
|
||||||
|
readonly username: Username;
|
||||||
|
|
||||||
|
constructor(props: CommandProps<UpdateUsernameCommand>) {
|
||||||
|
super(props);
|
||||||
|
this.userId = props.userId;
|
||||||
|
this.username = props.username;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { CommandHandler, ICommandHandler } from '@nestjs/cqrs';
|
||||||
|
import { Inject } from '@nestjs/common';
|
||||||
|
import {
|
||||||
|
AggregateID,
|
||||||
|
ConflictException,
|
||||||
|
UniqueConstraintException,
|
||||||
|
} from '@mobicoop/ddd-library';
|
||||||
|
import { USERNAME_REPOSITORY } from '@modules/authentication/authentication.di-tokens';
|
||||||
|
import { UsernameAlreadyExistsException } from '@modules/authentication/core/domain/authentication.errors';
|
||||||
|
import { UpdateUsernameCommand } from './update-username.command';
|
||||||
|
import { UsernameRepositoryPort } from '../../ports/username.repository.port';
|
||||||
|
import { UsernameEntity } from '@modules/authentication/core/domain/username.entity';
|
||||||
|
|
||||||
|
@CommandHandler(UpdateUsernameCommand)
|
||||||
|
export class UpdateUsernameService implements ICommandHandler {
|
||||||
|
constructor(
|
||||||
|
@Inject(USERNAME_REPOSITORY)
|
||||||
|
private readonly usernameRepository: UsernameRepositoryPort,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async execute(command: UpdateUsernameCommand): Promise<AggregateID> {
|
||||||
|
try {
|
||||||
|
const username: UsernameEntity = await this.usernameRepository.findByType(
|
||||||
|
command.userId,
|
||||||
|
command.username.type,
|
||||||
|
);
|
||||||
|
const oldName: string = username.id;
|
||||||
|
username.update({
|
||||||
|
name: command.username.name,
|
||||||
|
});
|
||||||
|
await this.usernameRepository.updateUsername(oldName, username);
|
||||||
|
return username.getProps().name;
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error instanceof ConflictException) {
|
||||||
|
throw new UsernameAlreadyExistsException(error);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
error instanceof UniqueConstraintException &&
|
||||||
|
error.message.includes('username')
|
||||||
|
) {
|
||||||
|
throw new UsernameAlreadyExistsException(error);
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
import { RepositoryPort } from '@mobicoop/ddd-library';
|
import { RepositoryPort } from '@mobicoop/ddd-library';
|
||||||
import { UsernameEntity } from '../../domain/username.entity';
|
import { UsernameEntity } from '../../domain/username.entity';
|
||||||
|
import { Type } from '../../domain/username.types';
|
||||||
|
|
||||||
export type UsernameRepositoryPort = RepositoryPort<UsernameEntity>;
|
export type UsernameRepositoryPort = RepositoryPort<UsernameEntity> & {
|
||||||
|
findByType(userId: string, type: Type): Promise<UsernameEntity>;
|
||||||
|
updateUsername(oldName: string, entity: UsernameEntity): Promise<void>;
|
||||||
|
};
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { DomainEvent, DomainEventProps } from '@mobicoop/ddd-library';
|
||||||
|
|
||||||
|
export class UsernameUpdatedDomainEvent extends DomainEvent {
|
||||||
|
constructor(props: DomainEventProps<UsernameUpdatedDomainEvent>) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,12 @@
|
||||||
import { AggregateID, AggregateRoot } from '@mobicoop/ddd-library';
|
import { AggregateID, AggregateRoot } from '@mobicoop/ddd-library';
|
||||||
import { CreateUsernameProps, UsernameProps } from './username.types';
|
import {
|
||||||
|
CreateUsernameProps,
|
||||||
|
UpdateUsernameProps,
|
||||||
|
UsernameProps,
|
||||||
|
} from './username.types';
|
||||||
import { UsernameAddedDomainEvent } from './events/username-added.domain-event';
|
import { UsernameAddedDomainEvent } from './events/username-added.domain-event';
|
||||||
import { UsernameDeletedDomainEvent } from './events/username-deleted.domain-event';
|
import { UsernameDeletedDomainEvent } from './events/username-deleted.domain-event';
|
||||||
|
import { UsernameUpdatedDomainEvent } from './events/username-updated.domain-event';
|
||||||
|
|
||||||
export class UsernameEntity extends AggregateRoot<UsernameProps> {
|
export class UsernameEntity extends AggregateRoot<UsernameProps> {
|
||||||
protected readonly _id: AggregateID;
|
protected readonly _id: AggregateID;
|
||||||
|
@ -24,6 +29,15 @@ export class UsernameEntity extends AggregateRoot<UsernameProps> {
|
||||||
return username;
|
return username;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
update(props: UpdateUsernameProps): void {
|
||||||
|
this.props.name = props.name;
|
||||||
|
this.addEvent(
|
||||||
|
new UsernameUpdatedDomainEvent({
|
||||||
|
aggregateId: props.name,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
delete(): void {
|
delete(): void {
|
||||||
this.addEvent(
|
this.addEvent(
|
||||||
new UsernameDeletedDomainEvent({
|
new UsernameDeletedDomainEvent({
|
||||||
|
|
|
@ -10,6 +10,10 @@ export interface CreateUsernameProps {
|
||||||
type: Type;
|
type: Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface UpdateUsernameProps {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export enum Type {
|
export enum Type {
|
||||||
EMAIL = 'EMAIL',
|
EMAIL = 'EMAIL',
|
||||||
PHONE = 'PHONE',
|
PHONE = 'PHONE',
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { MESSAGE_PUBLISHER } from '@src/app.di-tokens';
|
||||||
import { UsernameEntity } from '../core/domain/username.entity';
|
import { UsernameEntity } from '../core/domain/username.entity';
|
||||||
import { UsernameRepositoryPort } from '../core/application/ports/username.repository.port';
|
import { UsernameRepositoryPort } from '../core/application/ports/username.repository.port';
|
||||||
import { UsernameMapper } from '../username.mapper';
|
import { UsernameMapper } from '../username.mapper';
|
||||||
|
import { Type } from '../core/domain/username.types';
|
||||||
|
|
||||||
export type UsernameModel = {
|
export type UsernameModel = {
|
||||||
username: string;
|
username: string;
|
||||||
|
@ -46,4 +47,21 @@ export class UsernameRepository
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findByType = async (userId: string, type: Type): Promise<UsernameEntity> =>
|
||||||
|
this.findOne({
|
||||||
|
authUuid: userId,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
|
||||||
|
updateUsername = async (
|
||||||
|
oldName: string,
|
||||||
|
entity: UsernameEntity,
|
||||||
|
): Promise<void> =>
|
||||||
|
this.updateWhere(
|
||||||
|
{
|
||||||
|
username: oldName,
|
||||||
|
},
|
||||||
|
entity,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
import { UsernameDto } from './username.dto';
|
||||||
|
|
||||||
|
export class UpdateUsernameRequestDto extends UsernameDto {
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
userId: string;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
import {
|
||||||
|
AggregateID,
|
||||||
|
IdResponse,
|
||||||
|
RpcExceptionCode,
|
||||||
|
RpcValidationPipe,
|
||||||
|
} from '@mobicoop/ddd-library';
|
||||||
|
import { Controller, UsePipes } from '@nestjs/common';
|
||||||
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
import { GrpcMethod, RpcException } from '@nestjs/microservices';
|
||||||
|
import { UsernameAlreadyExistsException } from '@modules/authentication/core/domain/authentication.errors';
|
||||||
|
import { UpdateUsernameRequestDto } from './dtos/update-username.request.dto';
|
||||||
|
import { UpdateUsernameCommand } from '@modules/authentication/core/application/commands/update-username/update-username.command';
|
||||||
|
|
||||||
|
@UsePipes(
|
||||||
|
new RpcValidationPipe({
|
||||||
|
whitelist: true,
|
||||||
|
forbidUnknownValues: false,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
@Controller()
|
||||||
|
export class UpdateUsernameGrpcController {
|
||||||
|
constructor(private readonly commandBus: CommandBus) {}
|
||||||
|
|
||||||
|
@GrpcMethod('AuthenticationService', 'UpdateUsername')
|
||||||
|
async updateUsername(data: UpdateUsernameRequestDto): Promise<IdResponse> {
|
||||||
|
try {
|
||||||
|
const aggregateID: AggregateID = await this.commandBus.execute(
|
||||||
|
new UpdateUsernameCommand({
|
||||||
|
userId: data.userId,
|
||||||
|
username: {
|
||||||
|
name: data.name,
|
||||||
|
type: data.type,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return new IdResponse(aggregateID);
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error instanceof UsernameAlreadyExistsException)
|
||||||
|
throw new RpcException({
|
||||||
|
code: RpcExceptionCode.ALREADY_EXISTS,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
throw new RpcException({
|
||||||
|
code: RpcExceptionCode.UNKNOWN,
|
||||||
|
message: error.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
import {
|
||||||
|
AggregateID,
|
||||||
|
ConflictException,
|
||||||
|
UniqueConstraintException,
|
||||||
|
} from '@mobicoop/ddd-library';
|
||||||
|
import { USERNAME_REPOSITORY } from '@modules/authentication/authentication.di-tokens';
|
||||||
|
import { UpdateUsernameCommand } from '@modules/authentication/core/application/commands/update-username/update-username.command';
|
||||||
|
import { UpdateUsernameService } from '@modules/authentication/core/application/commands/update-username/update-username.service';
|
||||||
|
import { UsernameAlreadyExistsException } from '@modules/authentication/core/domain/authentication.errors';
|
||||||
|
import { Type } from '@modules/authentication/core/domain/username.types';
|
||||||
|
import { UpdateUsernameRequestDto } from '@modules/authentication/interface/grpc-controllers/dtos/update-username.request.dto';
|
||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
const updateUsernameRequest: UpdateUsernameRequestDto = {
|
||||||
|
userId: '165192d4-398a-4469-a16b-98c02cc6f531',
|
||||||
|
name: 'new-john.doe@email.com',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockUsernameRepository = {
|
||||||
|
findByType: jest.fn().mockImplementation(() => ({
|
||||||
|
id: 'john.doe@email.com',
|
||||||
|
update: jest.fn(),
|
||||||
|
getProps: jest.fn().mockImplementation(() => ({
|
||||||
|
userId: '165192d4-398a-4469-a16b-98c02cc6f531',
|
||||||
|
name: 'new-john.doe@email.com',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
updateUsername: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementationOnce(() => ({}))
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new ConflictException('already exists');
|
||||||
|
})
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new UniqueConstraintException('username');
|
||||||
|
})
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error();
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Update Username Service', () => {
|
||||||
|
let updateUsernameService: UpdateUsernameService;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: USERNAME_REPOSITORY,
|
||||||
|
useValue: mockUsernameRepository,
|
||||||
|
},
|
||||||
|
UpdateUsernameService,
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
updateUsernameService = module.get<UpdateUsernameService>(
|
||||||
|
UpdateUsernameService,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(updateUsernameService).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('execution', () => {
|
||||||
|
const updateUsernameCommand = new UpdateUsernameCommand({
|
||||||
|
userId: updateUsernameRequest.userId,
|
||||||
|
username: {
|
||||||
|
name: updateUsernameRequest.name,
|
||||||
|
type: updateUsernameRequest.type,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
it('should update a username', async () => {
|
||||||
|
const result: AggregateID = await updateUsernameService.execute(
|
||||||
|
updateUsernameCommand,
|
||||||
|
);
|
||||||
|
expect(result).toBe('new-john.doe@email.com');
|
||||||
|
});
|
||||||
|
it('should throw a dedicated exception if username already exists for this type', async () => {
|
||||||
|
await expect(
|
||||||
|
updateUsernameService.execute(updateUsernameCommand),
|
||||||
|
).rejects.toBeInstanceOf(UsernameAlreadyExistsException);
|
||||||
|
});
|
||||||
|
it('should throw a dedicated exception if username already exists for this name', async () => {
|
||||||
|
await expect(
|
||||||
|
updateUsernameService.execute(updateUsernameCommand),
|
||||||
|
).rejects.toBeInstanceOf(UsernameAlreadyExistsException);
|
||||||
|
});
|
||||||
|
it('should throw an error if something bad happens', async () => {
|
||||||
|
await expect(
|
||||||
|
updateUsernameService.execute(updateUsernameCommand),
|
||||||
|
).rejects.toBeInstanceOf(Error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,4 +1,5 @@
|
||||||
import { UsernameDeletedDomainEvent } from '@modules/authentication/core/domain/events/username-deleted.domain-event';
|
import { UsernameDeletedDomainEvent } from '@modules/authentication/core/domain/events/username-deleted.domain-event';
|
||||||
|
import { UsernameUpdatedDomainEvent } from '@modules/authentication/core/domain/events/username-updated.domain-event';
|
||||||
import { UsernameEntity } from '@modules/authentication/core/domain/username.entity';
|
import { UsernameEntity } from '@modules/authentication/core/domain/username.entity';
|
||||||
import {
|
import {
|
||||||
CreateUsernameProps,
|
CreateUsernameProps,
|
||||||
|
@ -20,6 +21,21 @@ describe('Username entity create', () => {
|
||||||
expect(usernameEntity.domainEvents.length).toBe(1);
|
expect(usernameEntity.domainEvents.length).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Username entity update', () => {
|
||||||
|
it('should update a username entity', async () => {
|
||||||
|
const usernameEntity: UsernameEntity = await UsernameEntity.create(
|
||||||
|
createUsernameProps,
|
||||||
|
);
|
||||||
|
usernameEntity.update({
|
||||||
|
name: 'new-john.doe@email.com',
|
||||||
|
});
|
||||||
|
expect(usernameEntity.getProps().name).toBe('new-john.doe@email.com');
|
||||||
|
expect(usernameEntity.domainEvents.length).toBe(2);
|
||||||
|
expect(usernameEntity.domainEvents[1]).toBeInstanceOf(
|
||||||
|
UsernameUpdatedDomainEvent,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
describe('Username entity delete', () => {
|
describe('Username entity delete', () => {
|
||||||
it('should delete a username entity', async () => {
|
it('should delete a username entity', async () => {
|
||||||
const usernameEntity: UsernameEntity = await UsernameEntity.create(
|
const usernameEntity: UsernameEntity = await UsernameEntity.create(
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { IdResponse } from '@mobicoop/ddd-library';
|
||||||
|
import { RpcExceptionCode } from '@mobicoop/ddd-library';
|
||||||
|
import { UsernameAlreadyExistsException } from '@modules/authentication/core/domain/authentication.errors';
|
||||||
|
import { Type } from '@modules/authentication/core/domain/username.types';
|
||||||
|
import { UpdateUsernameRequestDto } from '@modules/authentication/interface/grpc-controllers/dtos/update-username.request.dto';
|
||||||
|
import { UpdateUsernameGrpcController } from '@modules/authentication/interface/grpc-controllers/update-username.grpc.controller';
|
||||||
|
import { CommandBus } from '@nestjs/cqrs';
|
||||||
|
import { RpcException } from '@nestjs/microservices';
|
||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
|
||||||
|
const updateUsernameRequest: UpdateUsernameRequestDto = {
|
||||||
|
userId: '78153e03-4861-4f58-a705-88526efee53b',
|
||||||
|
name: 'new-john.doe@email.com',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCommandBus = {
|
||||||
|
execute: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementationOnce(() => 'new-john.doe@email.com')
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new UsernameAlreadyExistsException();
|
||||||
|
})
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new Error();
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('Update Username Grpc Controller', () => {
|
||||||
|
let updateUsernameGrpcController: UpdateUsernameGrpcController;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: CommandBus,
|
||||||
|
useValue: mockCommandBus,
|
||||||
|
},
|
||||||
|
UpdateUsernameGrpcController,
|
||||||
|
],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
updateUsernameGrpcController = module.get<UpdateUsernameGrpcController>(
|
||||||
|
UpdateUsernameGrpcController,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(updateUsernameGrpcController).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update a username', async () => {
|
||||||
|
jest.spyOn(mockCommandBus, 'execute');
|
||||||
|
const result: IdResponse =
|
||||||
|
await updateUsernameGrpcController.updateUsername(updateUsernameRequest);
|
||||||
|
expect(result).toBeInstanceOf(IdResponse);
|
||||||
|
expect(result.id).toBe('new-john.doe@email.com');
|
||||||
|
expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw a dedicated RpcException if username already exists', async () => {
|
||||||
|
jest.spyOn(mockCommandBus, 'execute');
|
||||||
|
expect.assertions(3);
|
||||||
|
try {
|
||||||
|
await updateUsernameGrpcController.updateUsername(updateUsernameRequest);
|
||||||
|
} catch (e: any) {
|
||||||
|
expect(e).toBeInstanceOf(RpcException);
|
||||||
|
expect(e.error.code).toBe(RpcExceptionCode.ALREADY_EXISTS);
|
||||||
|
}
|
||||||
|
expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw a generic RpcException', async () => {
|
||||||
|
jest.spyOn(mockCommandBus, 'execute');
|
||||||
|
expect.assertions(3);
|
||||||
|
try {
|
||||||
|
await updateUsernameGrpcController.updateUsername(updateUsernameRequest);
|
||||||
|
} catch (e: any) {
|
||||||
|
expect(e).toBeInstanceOf(RpcException);
|
||||||
|
expect(e.error.code).toBe(RpcExceptionCode.UNKNOWN);
|
||||||
|
}
|
||||||
|
expect(mockCommandBus.execute).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
|
@ -31,12 +31,13 @@ export class UsernameMapper
|
||||||
|
|
||||||
toDomain = (record: UsernameModel): UsernameEntity => {
|
toDomain = (record: UsernameModel): UsernameEntity => {
|
||||||
const entity = new UsernameEntity({
|
const entity = new UsernameEntity({
|
||||||
id: record.authUuid,
|
id: record.username,
|
||||||
createdAt: new Date(record.createdAt),
|
createdAt: new Date(record.createdAt),
|
||||||
updatedAt: new Date(record.updatedAt),
|
updatedAt: new Date(record.updatedAt),
|
||||||
props: {
|
props: {
|
||||||
name: record.username,
|
name: record.username,
|
||||||
type: Type[record.type],
|
type: Type[record.type],
|
||||||
|
userId: record.authUuid,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return entity;
|
return entity;
|
||||||
|
|
Loading…
Reference in New Issue