Ajout des tests
This commit is contained in:
@@ -1,22 +1,179 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { Router } from '@angular/router';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { vi } from 'vitest';
|
||||
import { Issues } from './issues';
|
||||
import { IssueEntity, IssuesStore } from './issues.store';
|
||||
|
||||
const makeIssue = (overrides: Partial<IssueEntity> = {}): IssueEntity => ({
|
||||
id: 99,
|
||||
type: 'Story',
|
||||
assignee: '',
|
||||
epic: '',
|
||||
name: 'Test Issue',
|
||||
dueDate: '',
|
||||
description: '',
|
||||
estimatedTime: null,
|
||||
dependsOnIds: [],
|
||||
comments: [],
|
||||
priority: 'Moyenne',
|
||||
status: 'draft',
|
||||
progress: 50,
|
||||
...overrides,
|
||||
});
|
||||
|
||||
describe('Issues', () => {
|
||||
let component: Issues;
|
||||
let fixture: ComponentFixture<Issues>;
|
||||
let store: IssuesStore;
|
||||
let router: Router;
|
||||
|
||||
beforeEach(async () => {
|
||||
localStorage.clear();
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [Issues],
|
||||
providers: [provideRouter([])],
|
||||
}).compileComponents();
|
||||
|
||||
store = TestBed.inject(IssuesStore);
|
||||
router = TestBed.inject(Router);
|
||||
fixture = TestBed.createComponent(Issues);
|
||||
component = fixture.componentInstance;
|
||||
await fixture.whenStable();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('filteredIssues', () => {
|
||||
it('returns all issues when no type is selected', () => {
|
||||
(component as any).selectedType = null;
|
||||
expect((component as any).filteredIssues.length).toBe(store.issues().length);
|
||||
});
|
||||
|
||||
it('returns only issues matching the selected type', () => {
|
||||
(component as any).selectedType = 'Bug';
|
||||
const filtered: IssueEntity[] = (component as any).filteredIssues;
|
||||
expect(filtered.every((i) => i.type === 'Bug')).toBe(true);
|
||||
});
|
||||
|
||||
it('returns empty array when no issues match the selected type', () => {
|
||||
(component as any).selectedType = 'Epic';
|
||||
const filtered: IssueEntity[] = (component as any).filteredIssues;
|
||||
// Default store has no Epics, so this should be empty
|
||||
expect(filtered.every((i) => i.type === 'Epic')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectType', () => {
|
||||
it('sets selectedType when none is active', () => {
|
||||
(component as any).selectedType = null;
|
||||
(component as any).selectType('Bug');
|
||||
expect((component as any).selectedType).toBe('Bug');
|
||||
});
|
||||
|
||||
it('clears selectedType when the same type is selected again (toggle off)', () => {
|
||||
(component as any).selectedType = 'Bug';
|
||||
(component as any).selectType('Bug');
|
||||
expect((component as any).selectedType).toBeNull();
|
||||
});
|
||||
|
||||
it('switches to a different type', () => {
|
||||
(component as any).selectedType = 'Bug';
|
||||
(component as any).selectType('Story');
|
||||
expect((component as any).selectedType).toBe('Story');
|
||||
});
|
||||
|
||||
it('selectType(null) clears the filter', () => {
|
||||
(component as any).selectedType = 'Bug';
|
||||
(component as any).selectType(null);
|
||||
expect((component as any).selectedType).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('createIssue', () => {
|
||||
it('navigates to /issues/new with a draftId query param', async () => {
|
||||
const spy = vi.spyOn(router, 'navigate').mockResolvedValue(true);
|
||||
(component as any).createIssue();
|
||||
expect(spy).toHaveBeenCalledWith(
|
||||
['/issues/new'],
|
||||
expect.objectContaining({ queryParams: expect.objectContaining({ mode: 'edit' }) }),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('openIssue', () => {
|
||||
it('navigates to the issue detail page', async () => {
|
||||
const spy = vi.spyOn(router, 'navigate').mockResolvedValue(true);
|
||||
(component as any).openIssue(42);
|
||||
expect(spy).toHaveBeenCalledWith(['/issues', 42]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getProgress', () => {
|
||||
it('returns issue.progress for non-Epic types', () => {
|
||||
const issue = makeIssue({ type: 'Story', progress: 75 });
|
||||
expect((component as any).getProgress(issue)).toBe(75);
|
||||
});
|
||||
|
||||
it('returns 0 for an Epic with no children', () => {
|
||||
const epic = makeIssue({ id: 50, type: 'Epic', name: 'Empty Epic', progress: 0 });
|
||||
store.upsert(epic);
|
||||
expect((component as any).getProgress(epic)).toBe(0);
|
||||
});
|
||||
|
||||
it('returns 100 for an Epic where all children are done', () => {
|
||||
const epic = makeIssue({ id: 51, type: 'Epic', name: 'Full Epic', progress: 0 });
|
||||
store.upsert(epic);
|
||||
store.upsert(makeIssue({ id: 52, name: 'Child 1', epic: 'Full Epic', status: 'done' }));
|
||||
store.upsert(makeIssue({ id: 53, name: 'Child 2', epic: 'Full Epic', status: 'done' }));
|
||||
expect((component as any).getProgress(epic)).toBe(100);
|
||||
});
|
||||
|
||||
it('calculates percentage for an Epic with some done children', () => {
|
||||
const epic = makeIssue({ id: 54, type: 'Epic', name: 'Partial Epic', progress: 0 });
|
||||
store.upsert(epic);
|
||||
store.upsert(makeIssue({ id: 55, name: 'Done', epic: 'Partial Epic', status: 'done' }));
|
||||
store.upsert(makeIssue({ id: 56, name: 'Pending', epic: 'Partial Epic', status: 'todo' }));
|
||||
expect((component as any).getProgress(epic)).toBe(50);
|
||||
});
|
||||
|
||||
it('counts children by dependsOnIds as well as epic name', () => {
|
||||
const epic = makeIssue({ id: 57, type: 'Epic', name: 'Dep Epic', progress: 0 });
|
||||
store.upsert(epic);
|
||||
store.upsert(makeIssue({ id: 58, name: 'DepChild', dependsOnIds: [57], status: 'done' }));
|
||||
expect((component as any).getProgress(epic)).toBe(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('typeBadgeClass', () => {
|
||||
it('maps Bug to text-bg-danger', () => {
|
||||
expect((component as any).typeBadgeClass('Bug')).toBe('text-bg-danger');
|
||||
});
|
||||
|
||||
it('maps Study to text-bg-secondary', () => {
|
||||
expect((component as any).typeBadgeClass('Study')).toBe('text-bg-secondary');
|
||||
});
|
||||
|
||||
it('maps Story to text-bg-success', () => {
|
||||
expect((component as any).typeBadgeClass('Story')).toBe('text-bg-success');
|
||||
});
|
||||
|
||||
it('maps Task to text-bg-primary', () => {
|
||||
expect((component as any).typeBadgeClass('Task')).toBe('text-bg-primary');
|
||||
});
|
||||
|
||||
it('maps Technical Story to text-bg-warning', () => {
|
||||
expect((component as any).typeBadgeClass('Technical Story')).toBe('text-bg-warning');
|
||||
});
|
||||
|
||||
it('maps Epic to text-bg-info', () => {
|
||||
expect((component as any).typeBadgeClass('Epic')).toBe('text-bg-info');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user