Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: ♻️ Tasks module #125

Merged
merged 10 commits into from
Dec 17, 2024
5 changes: 5 additions & 0 deletions libs/tasks/application/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
// tasks
export * from './lib/tasks.service';
export * from './lib/use-cases/get-all-tasks.use-case';

// user tasks
export * from './lib/user-tasks.service';
export * from './lib/use-cases/get-all-user-tasks.use-case';
export * from './lib/use-cases/create-some-user-tasks.use-case';
export * from './lib/use-cases/update-some-user-tasks.use-case';
30 changes: 23 additions & 7 deletions libs/tasks/application/src/lib/tasks.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TasksService } from './tasks.service';
import { GetAllTasksUseCase } from './use-cases/get-all-tasks.use-case';
import { TASKS_REPOSITORY, TasksRepository, Task } from '@tasks/domain';

describe('TasksService', () => {
let service: TasksService;
let getAllTasksUseCase: GetAllTasksUseCase;
let mockTasksRepository: TasksRepository;

beforeEach(async () => {
mockTasksRepository = {
findAll: jest.fn(),
};

const module: TestingModule = await Test.createTestingModule({
providers: [
TasksService,
{
provide: GetAllTasksUseCase,
useValue: {
execute: jest.fn(),
},
provide: TASKS_REPOSITORY,
useValue: mockTasksRepository,
},
],
}).compile();

service = module.get<TasksService>(TasksService);
getAllTasksUseCase = module.get<GetAllTasksUseCase>(GetAllTasksUseCase);
});

it('should be defined', () => {
expect(service).toBeDefined();
});

describe('findMany', () => {
it('should return all tasks', async () => {
const mockTasks = [
Task.create('task-1', 'Task 1', 'Description 1', ['category-1']),
Task.create('task-2', 'Task 2', 'Description 2', ['category-2']),
];
mockTasksRepository.findAll = jest.fn().mockResolvedValue(mockTasks);

const result = await service.findAll();

expect(result).toEqual(mockTasks);
expect(mockTasksRepository.findAll).toHaveBeenCalled();
});
});
});
13 changes: 7 additions & 6 deletions libs/tasks/application/src/lib/tasks.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Injectable } from '@nestjs/common';
import { Task } from '@tasks/domain';

import { GetAllTasksUseCase } from './use-cases/get-all-tasks.use-case';
import { Inject, Injectable } from '@nestjs/common';
import { Task, TASKS_REPOSITORY, TasksRepository } from '@tasks/domain';

@Injectable()
export class TasksService {
constructor(private readonly getAllTasksUseCase: GetAllTasksUseCase) {}
constructor(
@Inject(TASKS_REPOSITORY)
private readonly tasksRepository: TasksRepository,
) {}

async findAll(): Promise<Task[]> {
return await this.getAllTasksUseCase.execute();
return await this.tasksRepository.findAll();
}
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserTasksService } from '../user-tasks.service';
import { CreateSomeUserTasksUseCase } from './create-some-user-tasks.use-case';

describe('CreateSomeUserTasksUseCase', () => {
let useCase: CreateSomeUserTasksUseCase;
let userTasksService: UserTasksService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
CreateSomeUserTasksUseCase,
{
provide: UserTasksService,
useValue: {
createSome: jest.fn(),
},
},
],
}).compile();

useCase = module.get<CreateSomeUserTasksUseCase>(CreateSomeUserTasksUseCase);
userTasksService = module.get<UserTasksService>(UserTasksService);
});

it('should be defined', () => {
expect(useCase).toBeDefined();
});

describe('execute', () => {
it('should create multiple user tasks', async () => {
const userId = 'test-user-id';
const tasks = [
{ id: '1', createdAt: new Date() },
{ id: '2', createdAt: new Date() },
];
const expectedResult = 'success';

jest.spyOn(userTasksService, 'createSome').mockResolvedValue(expectedResult);

const result = await useCase.execute(userId, tasks);

expect(result).toEqual(expectedResult);
expect(userTasksService.createSome).toHaveBeenCalledWith(userId, tasks);
});
});
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Injectable } from '@nestjs/common';
import { UserTasksService } from '../user-tasks.service';

@Injectable()
export class CreateSomeUserTasksUseCase {
constructor(private readonly userTasksService: UserTasksService) {}

async execute(
userId: string,
tasks: { id: string; createdAt: Date }[],
): Promise<string> {
return await this.userTasksService.createSome(userId, tasks);
}
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TasksService } from '../tasks.service';
import { GetAllTasksUseCase } from './get-all-tasks.use-case';
import { Task } from '@tasks/domain';

describe('GetAllTasksUseCase', () => {
let useCase: GetAllTasksUseCase;
let tasksService: TasksService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
GetAllTasksUseCase,
{
provide: TasksService,
useValue: {
findAll: jest.fn(),
},
},
],
}).compile();

useCase = module.get<GetAllTasksUseCase>(GetAllTasksUseCase);
tasksService = module.get<TasksService>(TasksService);
});

it('should be defined', () => {
expect(useCase).toBeDefined();
});

describe('execute', () => {
it('should return all tasks', async () => {
const expectedTasks: Task[] = [
{
id: '1',
title: 'Test Task',
description: 'Test Description',
categories: ['category-1'],
},
];

jest.spyOn(tasksService, 'findAll').mockResolvedValue(expectedTasks);

const result = await useCase.execute();

expect(result).toEqual(expectedTasks);
expect(tasksService.findAll).toHaveBeenCalled();
});
});
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Inject, Injectable } from '@nestjs/common';
import { Task, TASKS_REPOSITORY, TasksRepository } from '@tasks/domain';
import { Injectable } from '@nestjs/common';
import { Task } from '@tasks/domain';

import { TasksService } from '../tasks.service';

@Injectable()
export class GetAllTasksUseCase {
constructor(
@Inject(TASKS_REPOSITORY)
private readonly tasksRepository: TasksRepository,
) {}
constructor(private readonly tasksService: TasksService) {}

async execute(): Promise<Task[]> {
return await this.tasksRepository.findAll();
return await this.tasksService.findAll();
}
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Test } from '@nestjs/testing';
import { TaskStatusEnum, UserTask } from '@tasks/domain';
import { GetAllUserTasksUseCase } from './get-all-user-tasks.use-case';
import { UserTasksService } from '../user-tasks.service';

describe('GetAllUserTasksUseCase', () => {
let useCase: GetAllUserTasksUseCase;
let userTasksService: UserTasksService;

beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
providers: [
GetAllUserTasksUseCase,
{
provide: UserTasksService,
useValue: {
findMany: jest.fn(),
},
},
],
}).compile();

useCase = moduleRef.get<GetAllUserTasksUseCase>(GetAllUserTasksUseCase);
userTasksService = moduleRef.get<UserTasksService>(UserTasksService);
});

describe('execute', () => {
it('should return all user tasks', async () => {
const userId = 'test-user-id';
const expectedTasks: UserTask[] = [
{
id: '1',
userId,
taskId: '1',
createdAt: new Date('2024-01-01T00:00:00.000Z'),
status: TaskStatusEnum.TODO,
updatedAt: null,
},
];

jest.spyOn(userTasksService, 'findMany').mockResolvedValue(expectedTasks);

const result = await useCase.execute(userId);

expect(result).toBe(expectedTasks);
expect(userTasksService.findMany).toHaveBeenCalledWith(userId);
});
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Injectable } from "@nestjs/common";
import { UserTask } from "@tasks/domain";

import { UserTasksService } from "../user-tasks.service";

@Injectable()
export class GetAllUserTasksUseCase {
constructor(private readonly userTasksService: UserTasksService) {}

async execute(userId: string): Promise<UserTask[]> {
return await this.userTasksService.findMany(userId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserTasksService } from '../user-tasks.service';
import { UpdateSomeUserTasksUseCase } from './update-some-user-tasks.use-case';

describe('UpdateSomeUserTasksUseCase', () => {
let useCase: UpdateSomeUserTasksUseCase;
let userTasksService: UserTasksService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UpdateSomeUserTasksUseCase,
{
provide: UserTasksService,
useValue: {
updateSome: jest.fn(),
},
},
],
}).compile();

useCase = module.get<UpdateSomeUserTasksUseCase>(UpdateSomeUserTasksUseCase);
userTasksService = module.get<UserTasksService>(UserTasksService);
});

it('should be defined', () => {
expect(useCase).toBeDefined();
});

describe('execute', () => {
it('should update multiple user tasks', async () => {
const userId = 'test-user-id';
const userTasks = [
{ id: '1', updatedAt: new Date() },
{ id: '2', updatedAt: new Date() },
];
const expectedResult = 'success';

jest.spyOn(userTasksService, 'updateSome').mockResolvedValue(expectedResult);

const result = await useCase.execute(userId, userTasks);

expect(result).toEqual(expectedResult);
expect(userTasksService.updateSome).toHaveBeenCalledWith(userId, userTasks);
});
});
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Injectable } from '@nestjs/common';
import { UserTasksService } from '../user-tasks.service';

@Injectable()
export class UpdateSomeUserTasksUseCase {
constructor(private readonly userTasksService: UserTasksService) {}

async execute(
userId: string,
userTasks: { id: string; updatedAt: Date }[],
): Promise<string> {
return await this.userTasksService.updateSome(userId, userTasks);
}
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
}
5 changes: 2 additions & 3 deletions libs/tasks/application/src/lib/user-tasks.service.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Injectable } from '@nestjs/common';
import { UserTask } from '@tasks/domain';

@Injectable()
export class UserTasksService {
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
async findMany(
userId: string,
): Promise<[]> {
async findMany(userId: string): Promise<UserTask[]> {
// TODO: Implement this
return [];
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
}
Expand Down
10 changes: 7 additions & 3 deletions libs/tasks/domain/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export * from './lib/entities/task.entity';
export * from './lib/entities/user-task.entity';
// tasks
export * from './lib/tasks-repository.interface';

export * from './lib/entities/task.entity';
export * from './lib/value-objects/task-status.enum';

export * from './lib/tasks.repository';
// user tasks
export * from './lib/user-tasks-repository.interface';

export * from './lib/entities/user-task.entity';
Loading
Loading