improvements
This commit is contained in:
parent
c11a2c5093
commit
8651345d6e
|
@ -12,15 +12,9 @@ export class DeleteAuthUseCase {
|
||||||
|
|
||||||
async execute(command: DeleteAuthCommand) {
|
async execute(command: DeleteAuthCommand) {
|
||||||
try {
|
try {
|
||||||
const usernames = await this._usernameRepository.findAll(1, 99, {
|
await this._usernameRepository.deleteMany({
|
||||||
uuid: command.deleteAuthRequest.uuid,
|
uuid: command.deleteAuthRequest.uuid,
|
||||||
});
|
});
|
||||||
usernames.data.map(
|
|
||||||
async (username) =>
|
|
||||||
await this._usernameRepository.delete({
|
|
||||||
username: username.username,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
return await this._authRepository.delete({
|
return await this._authRepository.delete({
|
||||||
uuid: command.deleteAuthRequest.uuid,
|
uuid: command.deleteAuthRequest.uuid,
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { Auth } from '../entities/auth';
|
||||||
import * as bcrypt from 'bcrypt';
|
import * as bcrypt from 'bcrypt';
|
||||||
import { NotFoundException, UnauthorizedException } from '@nestjs/common';
|
import { NotFoundException, UnauthorizedException } from '@nestjs/common';
|
||||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||||
|
import { Username } from '../entities/username';
|
||||||
|
|
||||||
@QueryHandler(ValidateAuthQuery)
|
@QueryHandler(ValidateAuthQuery)
|
||||||
export class ValidateAuthUseCase {
|
export class ValidateAuthUseCase {
|
||||||
|
@ -14,19 +15,23 @@ export class ValidateAuthUseCase {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(validate: ValidateAuthQuery): Promise<Auth> {
|
async execute(validate: ValidateAuthQuery): Promise<Auth> {
|
||||||
|
let username = new Username();
|
||||||
try {
|
try {
|
||||||
const username = await this._usernameRepository.findOne({
|
username = await this._usernameRepository.findOne({
|
||||||
username: validate.username,
|
username: validate.username,
|
||||||
});
|
});
|
||||||
|
} catch (e) {
|
||||||
|
throw new NotFoundException();
|
||||||
|
}
|
||||||
|
try {
|
||||||
const auth = await this._authRepository.findOne({
|
const auth = await this._authRepository.findOne({
|
||||||
uuid: username.uuid,
|
uuid: username.uuid,
|
||||||
});
|
});
|
||||||
if (auth) {
|
if (auth) {
|
||||||
const isMatch = await bcrypt.compare(validate.password, auth.password);
|
const isMatch = await bcrypt.compare(validate.password, auth.password);
|
||||||
if (isMatch) return auth;
|
if (isMatch) return auth;
|
||||||
throw new UnauthorizedException();
|
|
||||||
}
|
}
|
||||||
throw new NotFoundException();
|
throw new UnauthorizedException();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ const mockUsernameRepository = {
|
||||||
return Promise.resolve(usernames);
|
return Promise.resolve(usernames);
|
||||||
}),
|
}),
|
||||||
delete: jest.fn().mockResolvedValue(undefined),
|
delete: jest.fn().mockResolvedValue(undefined),
|
||||||
|
deleteMany: jest.fn().mockResolvedValue(undefined),
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('DeleteAuthUseCase', () => {
|
describe('DeleteAuthUseCase', () => {
|
||||||
|
|
|
@ -8,20 +8,38 @@ import { ValidateAuthUseCase } from '../../domain/usecases/validate-auth.usecase
|
||||||
import { ValidateAuthQuery } from '../../queries/validate-auth.query';
|
import { ValidateAuthQuery } from '../../queries/validate-auth.query';
|
||||||
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
import { UsernameRepository } from '../../adapters/secondaries/username.repository';
|
||||||
import { Type } from '../../domain/dtos/type.enum';
|
import { Type } from '../../domain/dtos/type.enum';
|
||||||
|
import { NotFoundException, UnauthorizedException } from '@nestjs/common';
|
||||||
|
import { DatabaseException } from '../../../database/src/exceptions/DatabaseException';
|
||||||
|
|
||||||
const mockAuthRepository = {
|
const mockAuthRepository = {
|
||||||
findOne: jest.fn().mockResolvedValue({
|
findOne: jest
|
||||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
.fn()
|
||||||
password: bcrypt.hashSync('John123', 10),
|
.mockImplementationOnce(() => ({
|
||||||
}),
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
|
password: bcrypt.hashSync('John123', 10),
|
||||||
|
}))
|
||||||
|
.mockImplementationOnce(() => ({
|
||||||
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
|
password: bcrypt.hashSync('John123', 10),
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockUsernameRepository = {
|
const mockUsernameRepository = {
|
||||||
findOne: jest.fn().mockResolvedValue({
|
findOne: jest
|
||||||
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
.fn()
|
||||||
username: 'john.doe@email.com',
|
.mockImplementationOnce(() => ({
|
||||||
type: Type.EMAIL,
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
}),
|
username: 'john.doe@email.com',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
}))
|
||||||
|
.mockImplementationOnce(() => {
|
||||||
|
throw new DatabaseException();
|
||||||
|
})
|
||||||
|
.mockImplementationOnce(() => ({
|
||||||
|
uuid: 'bb281075-1b98-4456-89d6-c643d3044a91',
|
||||||
|
username: 'john.doe@email.com',
|
||||||
|
type: Type.EMAIL,
|
||||||
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('ValidateAuthUseCase', () => {
|
describe('ValidateAuthUseCase', () => {
|
||||||
|
@ -56,7 +74,23 @@ describe('ValidateAuthUseCase', () => {
|
||||||
new ValidateAuthQuery('john.doe@email.com', 'John123'),
|
new ValidateAuthQuery('john.doe@email.com', 'John123'),
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(bcrypt.compareSync('John123', auth.password)).toBeTruthy();
|
expect(auth.uuid).toBe('bb281075-1b98-4456-89d6-c643d3044a91');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not validate an auth with unknown username and returns not found exception', async () => {
|
||||||
|
await expect(
|
||||||
|
validateAuthUseCase.execute(
|
||||||
|
new ValidateAuthQuery('jane.doe@email.com', 'Jane123'),
|
||||||
|
),
|
||||||
|
).rejects.toBeInstanceOf(NotFoundException);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not validate an auth with wrong password and returns unauthorized exception', async () => {
|
||||||
|
await expect(
|
||||||
|
validateAuthUseCase.execute(
|
||||||
|
new ValidateAuthQuery('john.doe@email.com', 'John1234'),
|
||||||
|
),
|
||||||
|
).rejects.toBeInstanceOf(UnauthorizedException);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -151,7 +151,26 @@ export abstract class PrismaRepository<T> implements IRepository<T> {
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
if (e instanceof PrismaClientKnownRequestError) {
|
||||||
|
throw new DatabaseException(
|
||||||
|
PrismaClientKnownRequestError.name,
|
||||||
|
e.code,
|
||||||
|
e.message,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new DatabaseException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteMany(where: any): Promise<void> {
|
||||||
|
try {
|
||||||
|
const entity = await this._prisma[this._model].deleteMany({
|
||||||
|
where: where,
|
||||||
|
});
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
} catch (e) {
|
||||||
if (e instanceof PrismaClientKnownRequestError) {
|
if (e instanceof PrismaClientKnownRequestError) {
|
||||||
throw new DatabaseException(
|
throw new DatabaseException(
|
||||||
PrismaClientKnownRequestError.name,
|
PrismaClientKnownRequestError.name,
|
||||||
|
|
|
@ -13,4 +13,5 @@ export interface IRepository<T> {
|
||||||
update(uuid: string, entity: Partial<T>, include?: any): Promise<T>;
|
update(uuid: string, entity: Partial<T>, include?: any): Promise<T>;
|
||||||
updateWhere(where: any, entity: Partial<T> | any, include?: any): Promise<T>;
|
updateWhere(where: any, entity: Partial<T> | any, include?: any): Promise<T>;
|
||||||
delete(uuid: string): Promise<void>;
|
delete(uuid: string): Promise<void>;
|
||||||
|
deleteMany(where: any): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ const fakeEntityCreated: FakeEntity = {
|
||||||
uuid: 'some-uuid',
|
uuid: 'some-uuid',
|
||||||
};
|
};
|
||||||
|
|
||||||
const fakeEntities: FakeEntity[] = [];
|
let fakeEntities: FakeEntity[] = [];
|
||||||
Array.from({ length: 10 }).forEach(() => {
|
Array.from({ length: 10 }).forEach(() => {
|
||||||
fakeEntities.push(createRandomEntity());
|
fakeEntities.push(createRandomEntity());
|
||||||
});
|
});
|
||||||
|
@ -117,6 +117,20 @@ const mockPrismaService = {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
deleteMany: jest.fn().mockImplementation((params: any) => {
|
||||||
|
const foundEntities = fakeEntities.filter((entity) =>
|
||||||
|
entity.name.startsWith(params?.where?.name),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (foundEntities.length == 0) {
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeEntities = fakeEntities.filter(
|
||||||
|
(entity) => !entity.name.startsWith(params?.where?.name),
|
||||||
|
);
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -241,4 +255,20 @@ describe('PrismaRepository', () => {
|
||||||
expect(entity.name).toBe(fakeEntities[0].name);
|
expect(entity.name).toBe(fakeEntities[0].name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('deleteMany', () => {
|
||||||
|
it('should delete many entities', async () => {
|
||||||
|
await fakeRepository.deleteMany({ name: 'name' });
|
||||||
|
const nbEntities = fakeEntities.filter((entity) =>
|
||||||
|
entity.name.startsWith('name'),
|
||||||
|
).length;
|
||||||
|
expect(nbEntities).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should throw an exception if an entity doesn't exist", async () => {
|
||||||
|
await expect(
|
||||||
|
fakeRepository.deleteMany({ name: 'fake-name' }),
|
||||||
|
).rejects.toBeInstanceOf(DatabaseException);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue