Files
Bonsai-webapp/src/app/statuses/statuses.store.spec.ts
T

133 lines
4.9 KiB
TypeScript

import { TestBed } from '@angular/core/testing';
import { DEFAULT_STATUSES, StatusesStore } from './statuses.store';
const STORAGE_KEY = 'bonsai_statuses';
describe('StatusesStore', () => {
let store: StatusesStore;
beforeEach(() => {
localStorage.removeItem(STORAGE_KEY);
TestBed.configureTestingModule({});
store = TestBed.inject(StatusesStore);
});
afterEach(() => {
localStorage.removeItem(STORAGE_KEY);
});
describe('statuses', () => {
it('returns default statuses when localStorage is empty', () => {
expect(store.statuses()).toEqual(DEFAULT_STATUSES);
});
it('restores statuses saved in localStorage', () => {
const saved = [
{ id: 'done', label: 'TERMINÉ', bg: '#dcfce7', color: '#166534', order: 0 },
{ id: 'draft', label: 'BROUILLON', bg: '#e2e8f0', color: '#475569', order: 1 },
];
localStorage.setItem(STORAGE_KEY, JSON.stringify(saved));
TestBed.resetTestingModule();
TestBed.configureTestingModule({});
const freshStore = TestBed.inject(StatusesStore);
expect(freshStore.statuses()).toEqual(saved);
});
it('falls back to default when localStorage contains invalid JSON', () => {
localStorage.setItem(STORAGE_KEY, 'not-json');
TestBed.resetTestingModule();
TestBed.configureTestingModule({});
const freshStore = TestBed.inject(StatusesStore);
expect(freshStore.statuses()).toEqual(DEFAULT_STATUSES);
});
it('sorts statuses by order on load', () => {
const unsorted = [DEFAULT_STATUSES[2], DEFAULT_STATUSES[0], DEFAULT_STATUSES[1], DEFAULT_STATUSES[3]];
localStorage.setItem(STORAGE_KEY, JSON.stringify(unsorted));
TestBed.resetTestingModule();
TestBed.configureTestingModule({});
const freshStore = TestBed.inject(StatusesStore);
expect(freshStore.statuses().map((s) => s.id)).toEqual(['draft', 'todo', 'in-progress', 'done']);
});
});
describe('setOrder', () => {
it('reassigns order values based on position', () => {
const reordered = [DEFAULT_STATUSES[3], DEFAULT_STATUSES[2], DEFAULT_STATUSES[1], DEFAULT_STATUSES[0]];
store.setOrder(reordered);
expect(store.statuses()[0].id).toBe('done');
expect(store.statuses()[0].order).toBe(0);
expect(store.statuses()[3].id).toBe('draft');
expect(store.statuses()[3].order).toBe(3);
});
it('persists the new order to localStorage', () => {
const reordered = [DEFAULT_STATUSES[1], DEFAULT_STATUSES[0], DEFAULT_STATUSES[2], DEFAULT_STATUSES[3]];
store.setOrder(reordered);
const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)!);
expect(stored[0].id).toBe('todo');
expect(stored[1].id).toBe('draft');
});
});
describe('getById', () => {
it('returns the matching status entity', () => {
expect(store.getById('draft')?.label).toBe('BROUILLON');
});
it('returns undefined for unknown id', () => {
expect(store.getById('unknown')).toBeUndefined();
});
});
describe('isCompleted', () => {
it('returns true for done status', () => {
expect(store.isCompleted('done')).toBe(true);
});
it('returns false for non-completed statuses', () => {
expect(store.isCompleted('draft')).toBe(false);
expect(store.isCompleted('todo')).toBe(false);
expect(store.isCompleted('in-progress')).toBe(false);
});
it('returns false for unknown status', () => {
expect(store.isCompleted('unknown')).toBe(false);
});
it('returns true for a custom status with countsAsCompleted true', () => {
store.create({ id: 'abandoned', label: 'ABANDONNÉE', bg: '#f1f5f9', color: '#64748b', countsAsCompleted: true });
expect(store.isCompleted('abandoned')).toBe(true);
});
});
describe('create', () => {
it('adds a new status with the next order value', () => {
store.create({ id: 'blocked', label: 'BLOQUÉ', bg: '#fee2e2', color: '#991b1b', countsAsCompleted: false });
const added = store.getById('blocked');
expect(added?.label).toBe('BLOQUÉ');
expect(added?.order).toBe(DEFAULT_STATUSES.length);
});
it('persists the new status to localStorage', () => {
store.create({ id: 'custom', label: 'CUSTOM', bg: '#fff', color: '#000', countsAsCompleted: false });
const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)!);
expect(stored.some((s: { id: string }) => s.id === 'custom')).toBe(true);
});
});
describe('update', () => {
it('updates label, bg and color of an existing status', () => {
store.update('draft', { label: 'NOUVEAU', bg: '#fff', color: '#000', countsAsCompleted: false });
const updated = store.getById('draft');
expect(updated?.label).toBe('NOUVEAU');
expect(updated?.bg).toBe('#fff');
});
it('does not change unrelated statuses', () => {
store.update('draft', { label: 'NOUVEAU' });
expect(store.getById('todo')?.label).toBe('À FAIRE');
});
});
});