test: fix spec issues from code review (logout assertion order, refresh 5xx test)

This commit is contained in:
Chris Chen
2026-05-26 20:38:58 -07:00
parent dc7909e247
commit 4874f2a0a3
@@ -3,6 +3,9 @@ import {
HttpClientTestingModule, HttpClientTestingModule,
HttpTestingController HttpTestingController
} from '@angular/common/http/testing'; } from '@angular/common/http/testing';
// NOTE: UserInfo is the interface Task 2 will add to auth.service.ts.
// Importing it here intentionally causes a compile error until Task 2 is implemented.
// Task 2 MUST export `UserInfo` (not the old `User`) for these tests to pass.
import { import {
AuthService, AuthService,
LoginResultType, LoginResultType,
@@ -124,22 +127,36 @@ describe('AuthService', () => {
expect(service.getToken()).toBeNull(); expect(service.getToken()).toBeNull();
expect(service.isAuthenticated()).toBeFalse(); expect(service.isAuthenticated()).toBeFalse();
}); });
it('should return false and not throw on 5xx error', () => {
let result: boolean | undefined;
service.refresh().subscribe(r => result = r);
httpMock.expectOne(`${apiConfig.authUrl}/refresh`).flush(
{ message: 'Server error' },
{ status: 500, statusText: 'Internal Server Error' }
);
expect(result).toBeFalse();
expect(service.isAuthenticated()).toBeFalse();
});
}); });
// ── logout() ─────────────────────────────────────────────────────────────── // ── logout() ───────────────────────────────────────────────────────────────
describe('logout()', () => { describe('logout()', () => {
it('should clear token and user from memory immediately', () => { it('should clear token and user from memory immediately', (done) => {
// Seed state // Seed state via the login flow (avoids accessing private BehaviorSubjects)
service['accessToken$'].next('some-token'); service.login({ email: 'test@example.com', password: 'secret' }).subscribe(() => {
service['currentUser$'].next(MOCK_USER); // Now token + user are set — call logout and assert BEFORE flushing the HTTP call
service.logout(); service.logout();
httpMock.expectOne(`${apiConfig.authUrl}/logout`).flush(null, { status: 204, statusText: 'No Content' });
expect(service.getToken()).toBeNull(); expect(service.getToken()).toBeNull();
expect(service.getCurrentUser()).toBeNull(); expect(service.getCurrentUser()).toBeNull();
expect(service.isAuthenticated()).toBeFalse(); expect(service.isAuthenticated()).toBeFalse();
// Now flush the logout HTTP call so httpMock.verify() is satisfied
httpMock.expectOne(`${apiConfig.authUrl}/logout`).flush(null, { status: 204, statusText: 'No Content' });
done();
});
// Flush the login call
httpMock.expectOne(`${apiConfig.authUrl}/login`).flush(MOCK_API_RESPONSE);
}); });
it('should POST to /api/auth/logout with withCredentials', () => { it('should POST to /api/auth/logout with withCredentials', () => {
@@ -151,13 +168,14 @@ describe('AuthService', () => {
}); });
it('should not throw if the logout API call fails', () => { it('should not throw if the logout API call fails', () => {
expect(() => {
service.logout(); service.logout();
// Flush an error response — service must swallow it
httpMock.expectOne(`${apiConfig.authUrl}/logout`).flush( httpMock.expectOne(`${apiConfig.authUrl}/logout`).flush(
{ message: 'Server error' }, { message: 'Server error' },
{ status: 500, statusText: 'Internal Server Error' } { status: 500, statusText: 'Internal Server Error' }
); );
}).not.toThrow(); // If we reach here without an unhandled error, the test passes
expect(service.isAuthenticated()).toBeFalse();
}); });
}); });