import { TestBed, fakeAsync, tick } from '@angular/core/testing'; import { Toast, ToastService } from './toast.service'; describe('ToastService', () => { let service: ToastService; beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(ToastService); }); it('show() emits a toast with correct message and type', (done) => { service.current$.subscribe((toast) => { if (toast) { expect(toast.message).toBe('Hello!'); expect(toast.type).toBe('error'); done(); } }); service.show('Hello!', 'error'); }); it('type defaults to success when not provided', (done) => { service.current$.subscribe((toast) => { if (toast) { expect(toast.type).toBe('success'); done(); } }); service.show('Default type'); }); it('current$ emits null after the duration elapses', fakeAsync(() => { const emitted: (string | null)[] = []; service.current$.subscribe((t: Toast | null) => emitted.push(t ? t.message : null)); service.show('Auto-dismiss', 'success', 500); tick(500); expect(emitted).toContain(null); })); it('calling show() again before timer fires replaces the active toast', fakeAsync(() => { const messages: (string | null)[] = []; service.current$.subscribe((t: Toast | null) => messages.push(t ? t.message : null)); service.show('First', 'success', 1000); tick(200); service.show('Second', 'success', 1000); tick(0); const nonNull = messages.filter((m) => m !== null); expect(nonNull[nonNull.length - 1]).toBe('Second'); })); });