import { HttpClient } from '@angular/common/http'; import { TestBed } from '@angular/core/testing'; import { NEVER, of, Subject, throwError } from 'rxjs'; import { vi } from 'vitest'; import { SessionService } from './session.service'; describe('SessionService', () => { const http = { get: vi.fn(), post: vi.fn() }; beforeEach(() => { vi.clearAllMocks(); TestBed.configureTestingModule({ providers: [SessionService, { provide: HttpClient, useValue: http }], }); }); it('distinguishes a pending session check from its final outcome', () => { const response = new Subject<{ authenticated: boolean }>(); http.get.mockReturnValueOnce(response); const service = TestBed.inject(SessionService); service.refresh(); expect(service.status()).toBe('checking'); response.next({ authenticated: false }); response.complete(); expect(service.status()).toBe('anonymous'); }); it('stores an authenticated user and applies its defaults', () => { const service = TestBed.inject(SessionService); http.get.mockReturnValueOnce( of({ authenticated: true, username: 'Camille', email: 'camille@example.com' }), ); service.refresh(); expect(service.username()).toBe('Camille'); expect(service.email()).toBe('camille@example.com'); http.get.mockReturnValueOnce(of({ authenticated: true })); service.refresh(); expect(service.username()).toBe('User'); expect(service.email()).toBe(''); }); it('clears the session for an anonymous or failed request', () => { const service = TestBed.inject(SessionService); http.get.mockReturnValueOnce(of({ authenticated: false })); service.refresh(); expect(service.isLoggedIn()).toBe(false); http.get.mockReturnValueOnce(throwError(() => new Error('offline'))); service.refresh(); expect(http.get).toHaveBeenCalledWith('/api/user'); expect(service.username()).toBe(''); }); it('posts logout with a truthful pending state', () => { const service = TestBed.inject(SessionService); service.status.set('authenticated'); http.post.mockReturnValueOnce(NEVER); service.logout(); expect(service.status()).toBe('signing-out'); expect(http.post).toHaveBeenCalledWith('/logout', null, { responseType: 'text' }); }); });