Skip to content

Commit

Permalink
Add option to disable project
Browse files Browse the repository at this point in the history
  • Loading branch information
ip512 committed May 28, 2024
1 parent 6b542fb commit e9c7f52
Show file tree
Hide file tree
Showing 31 changed files with 168 additions and 33 deletions.
14 changes: 14 additions & 0 deletions migrations/1716653153304-projectActive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";

export class ProjectActive1716653153304 implements MigrationInterface {
name = 'ProjectActive1716653153304'

public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "project" ADD "active" boolean NOT NULL DEFAULT true`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "project" DROP COLUMN "active"`);
}

}
1 change: 1 addition & 0 deletions src/Application/Project/Command/CreateProjectCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export class CreateProjectCommand implements ICommand {
constructor(
public readonly name: string,
public readonly invoiceUnit: InvoiceUnits,
public readonly active: boolean,
public readonly customerId: string
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ describe('CreateProjectCommandHandler', () => {
const command = new CreateProjectCommand(
'Project',
InvoiceUnits.DAY,
true,
'b5e8dc18-ca67-4323-bdae-654afe09499f'
);

Expand Down Expand Up @@ -83,7 +84,9 @@ describe('CreateProjectCommandHandler', () => {
).thenResolve(instance(customer));
when(
projectRepository.save(
deepEqual(new Project('Project', InvoiceUnits.DAY, instance(customer)))
deepEqual(
new Project('Project', InvoiceUnits.DAY, true, instance(customer))
)
)
).thenResolve(instance(createdProject));

Expand All @@ -97,7 +100,9 @@ describe('CreateProjectCommandHandler', () => {
verify(isProjectAlreadyExist.isSatisfiedBy('Project')).once();
verify(
projectRepository.save(
deepEqual(new Project('Project', InvoiceUnits.DAY, instance(customer)))
deepEqual(
new Project('Project', InvoiceUnits.DAY, true, instance(customer))
)
)
).once();
verify(createdProject.getId()).once();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class CreateProjectCommandHandler {
) {}

public async execute(command: CreateProjectCommand): Promise<string> {
const { name, customerId, invoiceUnit } = command;
const { name, customerId, active, invoiceUnit } = command;

const customer = await this.customerRepository.findOneById(customerId);
if (!customer) {
Expand All @@ -31,7 +31,7 @@ export class CreateProjectCommandHandler {
}

const project = await this.projectRepository.save(
new Project(name, invoiceUnit, customer)
new Project(name, invoiceUnit, active, customer)
);

return project.getId();
Expand Down
1 change: 1 addition & 0 deletions src/Application/Project/Command/UpdateProjectCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export class UpdateProjectCommand implements ICommand {
public readonly id: string,
public readonly name: string,
public readonly invoiceUnit: InvoiceUnits,
public readonly active: boolean,
public readonly customerId: string
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ describe('UpdateProjectCommandHandler', () => {
'afda00b1-bf49-4102-9bc2-bce17f3acd48',
'Project',
InvoiceUnits.HOUR,
true,
'd4aa560e-d2f7-422e-ae8d-6af5d0455eeb'
);

Expand Down Expand Up @@ -64,10 +65,20 @@ describe('UpdateProjectCommandHandler', () => {
).once();
verify(projectRepository.save(instance(updatedProject))).once();
verify(
updatedProject.update(instance(customer), InvoiceUnits.HOUR, 'Project')
updatedProject.update(
instance(customer),
InvoiceUnits.HOUR,
'Project',
true
)
).once();
verify(
updatedProject.update(instance(customer), InvoiceUnits.HOUR, 'Project')
updatedProject.update(
instance(customer),
InvoiceUnits.HOUR,
'Project',
true
)
).calledBefore(projectRepository.save(instance(updatedProject)));
verify(updatedProject.getName()).once();
});
Expand All @@ -88,7 +99,9 @@ describe('UpdateProjectCommandHandler', () => {
projectRepository.findOneById('afda00b1-bf49-4102-9bc2-bce17f3acd48')
).once();
verify(projectRepository.save(anything())).never();
verify(updatedProject.update(anything(), anything(), anything())).never();
verify(
updatedProject.update(anything(), anything(), anything(), anything())
).never();
verify(updatedProject.getName()).never();
}
});
Expand All @@ -114,7 +127,9 @@ describe('UpdateProjectCommandHandler', () => {
customerRepository.findOneById('d4aa560e-d2f7-422e-ae8d-6af5d0455eeb')
).once();
verify(projectRepository.save(anything())).never();
verify(updatedProject.update(anything(), anything(), anything())).never();
verify(
updatedProject.update(anything(), anything(), anything(), anything())
).never();
verify(updatedProject.getName()).never();
}
});
Expand All @@ -141,7 +156,9 @@ describe('UpdateProjectCommandHandler', () => {
customerRepository.findOneById('d4aa560e-d2f7-422e-ae8d-6af5d0455eeb')
).once();
verify(projectRepository.save(anything())).never();
verify(updatedProject.update(anything(), anything(), anything())).never();
verify(
updatedProject.update(anything(), anything(), anything(), anything())
).never();
verify(updatedProject.getName()).once();
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class UpdateProjectCommandHandler {
) {}

public async execute(command: UpdateProjectCommand): Promise<void> {
const { id, name, customerId, invoiceUnit } = command;
const { id, name, customerId, invoiceUnit, active } = command;

const project = await this.projectRepository.findOneById(id);
if (!project) {
Expand All @@ -38,7 +38,7 @@ export class UpdateProjectCommandHandler {
throw new ProjectAlreadyExistException();
}

project.update(customer, invoiceUnit, name);
project.update(customer, invoiceUnit, name, active);
await this.projectRepository.save(project);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('GetProjectByIdQueryHandler', () => {

when(project.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(project.getName()).thenReturn('Project');
when(project.isActive()).thenReturn(true);
when(project.getInvoiceUnit()).thenReturn(InvoiceUnits.DAY);
when(project.getCustomer()).thenReturn(instance(customer));
when(
Expand All @@ -34,6 +35,7 @@ describe('GetProjectByIdQueryHandler', () => {
new ProjectView(
'eb9e1d9b-dce2-48a9-b64f-f0872f3157d2',
'Project',
true,
InvoiceUnits.DAY,
new CustomerView('aeb50974-0dcd-4ef4-af43-d656250e43bc', 'Customer')
)
Expand All @@ -44,6 +46,7 @@ describe('GetProjectByIdQueryHandler', () => {
).once();
verify(project.getId()).once();
verify(project.getName()).once();
verify(project.isActive()).once();
verify(project.getInvoiceUnit()).once();
verify(project.getCustomer()).once();
verify(customer.getId()).once();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class GetProjectByIdQueryHandler {
return new ProjectView(
project.getId(),
project.getName(),
project.isActive(),
project.getInvoiceUnit(),
new CustomerView(customer.getId(), customer.getName())
);
Expand Down
1 change: 1 addition & 0 deletions src/Application/Project/Query/GetProjectsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { IQuery } from 'src/Application/IQuery';
export class GetProjectsQuery implements IQuery {
constructor(
public readonly page: number | null,
public readonly activeOnly = true,
public readonly customerId?: string
) {}
}
26 changes: 18 additions & 8 deletions src/Application/Project/Query/GetProjectsQueryHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,25 @@ describe('GetProjectsQueryHandler', () => {
const project1 = mock(Project);
when(project1.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(project1.getName()).thenReturn('z51');
when(project1.isActive()).thenReturn(false);
when(project1.getInvoiceUnit()).thenReturn(InvoiceUnits.DAY);
when(project1.getCustomer()).thenReturn(instance(customer1));

const project2 = mock(Project);
when(project2.getId()).thenReturn('d54f15d6-1a1d-47e8-8672-9f46018f9960');
when(project2.getName()).thenReturn('BO cruiser');
when(project2.isActive()).thenReturn(true);
when(project2.getInvoiceUnit()).thenReturn(InvoiceUnits.HOUR);
when(project2.getCustomer()).thenReturn(instance(customer1));

const project3 = mock(Project);
when(project3.getId()).thenReturn('992eb372-cc02-4ffe-86e0-7b955b7f1a6e');
when(project3.getInvoiceUnit()).thenReturn(InvoiceUnits.HOUR);
when(project3.isActive()).thenReturn(true);
when(project3.getName()).thenReturn('Vimeet');
when(project3.getCustomer()).thenReturn(instance(customer2));

when(projectRepository.findProjects(1, undefined)).thenResolve([
when(projectRepository.findProjects(1, false, undefined)).thenResolve([
[instance(project3), instance(project2), instance(project1)],
3
]);
Expand All @@ -52,12 +55,14 @@ describe('GetProjectsQueryHandler', () => {
new ProjectView(
'992eb372-cc02-4ffe-86e0-7b955b7f1a6e',
'Vimeet',
true,
InvoiceUnits.HOUR,
new CustomerView('b9a9b094-5bb2-4d0b-b01e-231b6cb50039', 'Proximum')
),
new ProjectView(
'd54f15d6-1a1d-47e8-8672-9f46018f9960',
'BO cruiser',
true,
InvoiceUnits.HOUR,
new CustomerView(
'58958f69-d104-471b-b780-bbb0ec6c52da',
Expand All @@ -67,6 +72,7 @@ describe('GetProjectsQueryHandler', () => {
new ProjectView(
'eb9e1d9b-dce2-48a9-b64f-f0872f3157d2',
'z51',
false,
InvoiceUnits.DAY,
new CustomerView(
'58958f69-d104-471b-b780-bbb0ec6c52da',
Expand All @@ -77,10 +83,10 @@ describe('GetProjectsQueryHandler', () => {
3
);

expect(await queryHandler.execute(new GetProjectsQuery(1))).toMatchObject(
expectedResult
);
verify(projectRepository.findProjects(1, undefined)).once();
expect(
await queryHandler.execute(new GetProjectsQuery(1, false))
).toMatchObject(expectedResult);
verify(projectRepository.findProjects(1, false, undefined)).once();
});

it('testGetAllProjects', async () => {
Expand All @@ -93,16 +99,18 @@ describe('GetProjectsQueryHandler', () => {
const project1 = mock(Project);
when(project1.getId()).thenReturn('eb9e1d9b-dce2-48a9-b64f-f0872f3157d2');
when(project1.getName()).thenReturn('z51');
when(project1.isActive()).thenReturn(true);
when(project1.getInvoiceUnit()).thenReturn(InvoiceUnits.DAY);
when(project1.getCustomer()).thenReturn(instance(customer1));

const project2 = mock(Project);
when(project2.getId()).thenReturn('d54f15d6-1a1d-47e8-8672-9f46018f9960');
when(project2.getName()).thenReturn('BO cruiser');
when(project2.isActive()).thenReturn(true);
when(project2.getInvoiceUnit()).thenReturn(InvoiceUnits.HOUR);
when(project2.getCustomer()).thenReturn(instance(customer1));

when(projectRepository.findProjects(null, undefined)).thenResolve([
when(projectRepository.findProjects(null, true, undefined)).thenResolve([
[instance(project2), instance(project1)],
2
]);
Expand All @@ -116,6 +124,7 @@ describe('GetProjectsQueryHandler', () => {
new ProjectView(
'd54f15d6-1a1d-47e8-8672-9f46018f9960',
'BO cruiser',
true,
InvoiceUnits.HOUR,
new CustomerView(
'58958f69-d104-471b-b780-bbb0ec6c52da',
Expand All @@ -125,6 +134,7 @@ describe('GetProjectsQueryHandler', () => {
new ProjectView(
'eb9e1d9b-dce2-48a9-b64f-f0872f3157d2',
'z51',
true,
InvoiceUnits.DAY,
new CustomerView(
'58958f69-d104-471b-b780-bbb0ec6c52da',
Expand All @@ -136,8 +146,8 @@ describe('GetProjectsQueryHandler', () => {
);

expect(
await queryHandler.execute(new GetProjectsQuery(null))
await queryHandler.execute(new GetProjectsQuery(null, true))
).toMatchObject(expectedResult);
verify(projectRepository.findProjects(null, undefined)).once();
verify(projectRepository.findProjects(null, true, undefined)).once();
});
});
4 changes: 3 additions & 1 deletion src/Application/Project/Query/GetProjectsQueryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ export class GetProjectsQueryHandler {
public async execute(
query: GetProjectsQuery
): Promise<Pagination<ProjectView>> {
const { customerId, page } = query;
const { customerId, activeOnly, page } = query;

const projectViews: ProjectView[] = [];

const [projects, total] = await this.projectRepository.findProjects(
page,
activeOnly,
customerId
);

Expand All @@ -32,6 +33,7 @@ export class GetProjectsQueryHandler {
new ProjectView(
project.getId(),
project.getName(),
project.isActive(),
project.getInvoiceUnit(),
new CustomerView(customer.getId(), customer.getName())
)
Expand Down
1 change: 1 addition & 0 deletions src/Application/Project/View/ProjectView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export class ProjectView {
constructor(
public readonly id: string,
public readonly name: string,
public readonly active?: boolean,
public readonly invoiceUnit?: string,
public readonly customer?: CustomerView
) {}
Expand Down
6 changes: 5 additions & 1 deletion src/Domain/Project/Project.entity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ describe('Project.entity', () => {
const project = new Project(
'Project name',
InvoiceUnits.DAY,
true,
instance(customer)
);

expect(project.getId()).toBe(undefined);
expect(project.getFullName()).toBe('[Radio France] Project name');
expect(project.getName()).toBe('Project name');
expect(project.getInvoiceUnit()).toBe(InvoiceUnits.DAY);
expect(project.isActive()).toBe(true);
expect(project.getCustomer()).toBe(instance(customer));
});

Expand All @@ -29,13 +31,15 @@ describe('Project.entity', () => {
const project = new Project(
'Project name',
InvoiceUnits.DAY,
false,
instance(customer)
);
project.update(instance(customer2), InvoiceUnits.HOUR, 'project');
project.update(instance(customer2), InvoiceUnits.HOUR, 'project', true);

expect(project.getId()).toBe(undefined);
expect(project.getFullName()).toBe('[RF] project');
expect(project.getName()).toBe('project');
expect(project.isActive()).toBe(true);
expect(project.getInvoiceUnit()).toBe(InvoiceUnits.HOUR);
expect(project.getCustomer()).toBe(instance(customer2));
});
Expand Down
Loading

0 comments on commit e9c7f52

Please sign in to comment.