import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute, ParamMap, Router, convertToParamMap, provideRouter } from '@angular/router'; import { BehaviorSubject, of } from 'rxjs'; import { Notifications } from './notifications'; import { NotificationsApi } from '../../../core/notifications/notifications-api'; import { NotificationsStore } from '../../../core/notifications/notifications-store'; import { NotificationItem } from '../../../models/notification.model'; describe('Notifications', () => { let routeParams: BehaviorSubject; let fixture: ComponentFixture; let api: { loadNotifications: ReturnType }; let store: { markRead: ReturnType }; const item: NotificationItem = { id: 1, event: 'player_creation', actorUserId: 9, payload: { playerId: 21, playerName: 'Ada Lovelace' }, read: false, createdAt: '2026-08-04T10:00:00.000Z', }; beforeEach(async () => { routeParams = new BehaviorSubject(convertToParamMap({ id: '5' })); api = { loadNotifications: vi.fn() }; store = { markRead: vi.fn() }; await TestBed.configureTestingModule({ imports: [Notifications], providers: [ provideRouter([]), { provide: NotificationsApi, useValue: api }, { provide: NotificationsStore, useValue: store }, { provide: ActivatedRoute, useValue: { parent: { paramMap: routeParams } } }, ], }).compileComponents(); fixture = TestBed.createComponent(Notifications); }); it('loads the first page for the routed team id', () => { api.loadNotifications.mockReturnValue(of({ data: [item], page: 1, limit: 20, total: 1, hasNextPage: false })); fixture.detectChanges(); expect(api.loadNotifications).toHaveBeenCalledWith(5, { page: 1, limit: 20 }); expect((fixture.componentInstance as any).items()).toEqual([item]); }); it('loads the next page and appends results', () => { api.loadNotifications .mockReturnValueOnce(of({ data: [item], page: 1, limit: 20, total: 21, hasNextPage: true })) .mockReturnValueOnce(of({ data: [{ ...item, id: 2 }], page: 2, limit: 20, total: 21, hasNextPage: false })); fixture.detectChanges(); (fixture.componentInstance as any).loadMore(); expect(api.loadNotifications).toHaveBeenLastCalledWith(5, { page: 2, limit: 20 }); expect((fixture.componentInstance as any).items().length).toBe(2); }); it('marks a clicked item as read and navigates to its target', () => { api.loadNotifications.mockReturnValue(of({ data: [item], page: 1, limit: 20, total: 1, hasNextPage: false })); fixture.detectChanges(); const router = TestBed.inject(Router); const navigateSpy = vi.spyOn(router, 'navigate'); (fixture.componentInstance as any).onItemClick(item); expect(store.markRead).toHaveBeenCalledWith(5, 1); expect(navigateSpy).toHaveBeenCalledWith(['/team', 5, 'members', 21]); }); });