import { describe, it, expect, vi, beforeEach } from 'vitest'; import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { TaskService } from '@app/features/tasks/data-access/services/task'; import { TaskDataSource } from '@app/features/tasks/data-access/data-sources/task-data-source.interface'; import { TASK_DATA_SOURCE } from '@app/features/tasks/data-access/data-sources/task-data-source.token'; import { TaskBuilder } from '@tests/builders/task.builder'; describe('TaskService', () => { let service: TaskService; let dataSource: TaskDataSource; beforeEach(() => { dataSource = { getAll: vi.fn(), getById: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn(), transition: vi.fn(), addNote: vi.fn(), deleteNote: vi.fn(), }; TestBed.configureTestingModule({ providers: [ TaskService, { provide: TASK_DATA_SOURCE, useValue: dataSource }, ], }); service = TestBed.inject(TaskService); }); describe('getAll', () => { it('should return paginated tasks from datasource', () => { const tasks = TaskBuilder.buildMany(3); const response = { data: tasks, pagination: { page: 1, pageSize: 10, total: 3, totalPages: 1 } }; vi.mocked(dataSource.getAll).mockReturnValue(of(response)); service.getAll().subscribe(result => { expect(result).toEqual(response); }); expect(dataSource.getAll).toHaveBeenCalledOnce(); }); it('should pass pagination params to datasource', () => { const params = { page: 2, pageSize: 5 }; const response = { data: [], pagination: { page: 2, pageSize: 5, total: 0, totalPages: 0 } }; vi.mocked(dataSource.getAll).mockReturnValue(of(response)); service.getAll(params).subscribe(); expect(dataSource.getAll).toHaveBeenCalledWith(params); }); }); describe('getById', () => { it('should return task by id from datasource', () => { const task = new TaskBuilder().withId('task-1').build(); vi.mocked(dataSource.getById).mockReturnValue(of(task)); service.getById('task-1').subscribe(result => { expect(result).toEqual(task); }); expect(dataSource.getById).toHaveBeenCalledWith('task-1'); }); }); describe('create', () => { it('should create task through datasource', () => { const dto = { title: 'New Task', description: 'Description' }; const created = new TaskBuilder().withTitle('New Task').build(); vi.mocked(dataSource.create).mockReturnValue(of(created)); service.create(dto).subscribe(result => { expect(result).toEqual(created); }); expect(dataSource.create).toHaveBeenCalledWith(dto); }); }); describe('update', () => { it('should update task through datasource', () => { const dto = { title: 'Updated' }; const updated = new TaskBuilder().withId('task-1').withTitle('Updated').build(); vi.mocked(dataSource.update).mockReturnValue(of(updated)); service.update('task-1', dto).subscribe(result => { expect(result).toEqual(updated); }); expect(dataSource.update).toHaveBeenCalledWith('task-1', dto); }); }); describe('delete', () => { it('should delete task through datasource', () => { vi.mocked(dataSource.delete).mockReturnValue(of(undefined)); service.delete('task-1').subscribe(); expect(dataSource.delete).toHaveBeenCalledWith('task-1'); }); }); describe('transition', () => { it('should transition task state through datasource', () => { const updated = new TaskBuilder().withId('task-1').withState('active').build(); vi.mocked(dataSource.transition).mockReturnValue(of(updated)); service.transition('task-1', 'active').subscribe(result => { expect(result).toEqual(updated); }); expect(dataSource.transition).toHaveBeenCalledWith('task-1', 'active'); }); }); describe('addNote', () => { it('should add note through datasource', () => { const updated = new TaskBuilder().withId('task-1').withNotes(['New note']).build(); vi.mocked(dataSource.addNote).mockReturnValue(of(updated)); service.addNote('task-1', 'New note').subscribe(result => { expect(result).toEqual(updated); }); expect(dataSource.addNote).toHaveBeenCalledWith('task-1', 'New note'); }); }); describe('deleteNote', () => { it('should delete note through datasource', () => { const updated = new TaskBuilder().withId('task-1').withNotes([]).build(); vi.mocked(dataSource.deleteNote).mockReturnValue(of(updated)); service.deleteNote('task-1', 0).subscribe(result => { expect(result).toEqual(updated); }); expect(dataSource.deleteNote).toHaveBeenCalledWith('task-1', 0); }); }); });