Ajout des tests

This commit is contained in:
2026-05-23 20:18:18 +02:00
parent 5b5edbb3da
commit 80f8b56ec4
10 changed files with 1222 additions and 9 deletions
+158 -1
View File
@@ -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');
});
});
});