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

feat: ✨ add task domain behaviors #117

Merged
merged 2 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions libs/tasks/application/src/lib/user-tasks.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Injectable } from '@nestjs/common';
import { UserTask } from '@tasks/domain';

@Injectable()
export class UserTasksService {
async findMany(
userId: string,
): Promise<UserTask[]> {
): Promise<[]> {
zhumeisongsong marked this conversation as resolved.
Show resolved Hide resolved
// TODO: Implement this
return [];
}
Expand Down
54 changes: 25 additions & 29 deletions libs/tasks/domain/src/lib/entities/task.entity.spec.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
import { Task } from './task.entity';

describe('Task', () => {
it('should create a task with all properties', () => {
const task = new Task(
'test-id',
'Test Title',
'Test Description',
['category1', 'category2']
);
describe('create', () => {
it('should create a new task', () => {
const task = Task.create('id', 'Test Task', 'Test Description', [
'category1',
'category2',
]);

expect(task.id).toBe('test-id');
expect(task.title).toBe('Test Title');
expect(task.description).toBe('Test Description');
expect(task.categories).toEqual(['category1', 'category2']);
});
expect(task.id).toBe('id');
expect(task.title).toBe('Test Task');
expect(task.description).toBe('Test Description');
expect(task.categories).toEqual(['category1', 'category2']);
});

it('should allow null description', () => {
const task = new Task(
'test-id',
'Test Title',
null,
['category1']
);
it('should create a task with null description', () => {
const task = Task.create('id', 'Test Task', null, ['category1']);

expect(task.description).toBeNull();
});
expect(task.id).toBe('id');
expect(task.title).toBe('Test Task');
expect(task.description).toBeNull();
expect(task.categories).toEqual(['category1']);
});

it('should create a task with empty categories array', () => {
const task = new Task(
'test-id',
'Test Title',
'Test Description',
[]
);
it('should create a task with empty categories', () => {
const task = Task.create('id', 'Test Task', 'Test Description', []);

expect(task.categories).toEqual([]);
expect(task.id).toBe('id');
expect(task.title).toBe('Test Task');
expect(task.description).toBe('Test Description');
expect(task.categories).toEqual([]);
});
});
});
14 changes: 13 additions & 1 deletion libs/tasks/domain/src/lib/entities/task.entity.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
export class Task {
constructor(
private constructor(
public readonly id: string,
public readonly title: string,
public readonly description: string | null,
public readonly categories: string[],
) {}

/**
* Creates a new task
*/
static create(
id: string,
title: string,
description: string | null,
categories: string[],
): Task {
return new Task(id, title, description, categories);
}
}
73 changes: 48 additions & 25 deletions libs/tasks/domain/src/lib/entities/user-task.entity.spec.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
import { User } from '@users/domain';
import { Task } from './task.entity';
import { TaskStatusEnum } from '../value-objects/task-status.enum';
import { UserTask } from './user-task.entity';

describe('UserTask', () => {
it('should create a user task instance', () => {
const task = new Task('task-1', 'Test Task', 'Description', ['category1']);
const user = new User('user-1', '[email protected]', null, null);
const now = new Date();

const userTask = new UserTask(
'user-task-1',
now,
null,
'task-1',
task,
'user-1',
user,
);

expect(userTask).toBeDefined();
expect(userTask.id).toBe('user-task-1');
expect(userTask.createdAt).toBe(now);
expect(userTask.updatedAt).toBeNull();
expect(userTask.taskId).toBe('task-1');
expect(userTask.task).toBe(task);
expect(userTask.userId).toBe('user-1');
expect(userTask.user).toBe(user);
describe('create', () => {
it('should create a new user task with TODO status', () => {
const task = UserTask.create('id', 'userId', 'taskId');

expect(task.id).toBe('id');
expect(task.userId).toBe('userId');
expect(task.taskId).toBe('taskId');
expect(task.status).toBe(TaskStatusEnum.TODO);
expect(task.updatedAt).toBeNull();
expect(task.createdAt).toBeInstanceOf(Date);
});
});

describe('markAsInProgress', () => {
it('should mark task as in progress', () => {
const task = UserTask.create('id', 'userId', 'taskId');
const inProgressTask = task.markAsInProgress();

expect(inProgressTask.status).toBe(TaskStatusEnum.IN_PROGRESS);
expect(inProgressTask.updatedAt).toBeInstanceOf(Date);
});

it('should return same instance if already in progress', () => {
const task = UserTask.create('id', 'userId', 'taskId');
const inProgressTask = task.markAsInProgress();
const sameTask = inProgressTask.markAsInProgress();

expect(sameTask).toBe(inProgressTask);
});
});

describe('markAsDone', () => {
it('should mark task as done', () => {
const task = UserTask.create('id', 'userId', 'taskId');
const doneTask = task.markAsDone();

expect(doneTask.status).toBe(TaskStatusEnum.DONE);
expect(doneTask.updatedAt).toBeInstanceOf(Date);
});

it('should return same instance if already done', () => {
const task = UserTask.create('id', 'userId', 'taskId');
const doneTask = task.markAsDone();
const sameTask = doneTask.markAsDone();

expect(sameTask).toBe(doneTask);
});
});
});
61 changes: 53 additions & 8 deletions libs/tasks/domain/src/lib/entities/user-task.entity.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,60 @@
import { User } from '@users/domain';

import { Task } from './task.entity';
import { TaskStatus, TaskStatusEnum } from '../value-objects/task-status.enum';

export class UserTask {
constructor(
private constructor(
public readonly id: string,
public readonly userId: string,
public readonly taskId: string,
public readonly createdAt: Date,
public readonly updatedAt: Date | null,
public readonly taskId: string,
public readonly task: Task | null,
public readonly userId: string,
public readonly user: User | null,
public readonly status: TaskStatus,
) {}

/**
* Creates a new user task
*/
static create(id: string, userId: string, taskId: string): UserTask {
return new UserTask(
id,
userId,
taskId,
new Date(),
null,
TaskStatusEnum.TODO,
);
}

/**
* Marks the task as in progress
*/
markAsInProgress(): UserTask {
if (this.status === TaskStatusEnum.IN_PROGRESS) {
return this;
}
return new UserTask(
this.id,
this.userId,
this.taskId,
this.createdAt,
new Date(),
TaskStatusEnum.IN_PROGRESS,
);
}

/**
* Marks the task as done
*/
markAsDone(): UserTask {
if (this.status === TaskStatusEnum.DONE) {
return this;
}
return new UserTask(
this.id,
this.userId,
this.taskId,
this.createdAt,
new Date(),
TaskStatusEnum.DONE,
);
}
}
Loading