feat(auth): server-side sessions replacing Basic-auth cookie promotion (#523) #612
63
frontend/src/routes/logout/page.server.test.ts
Normal file
63
frontend/src/routes/logout/page.server.test.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
vi.mock('$env/dynamic/private', () => ({
|
||||
env: { API_INTERNAL_URL: 'http://backend:8080' }
|
||||
}));
|
||||
|
||||
import { actions } from './+page.server';
|
||||
|
||||
type ActionsRecord = Record<string, (e: never) => unknown>;
|
||||
|
||||
function makeCookies(sessionId?: string) {
|
||||
return {
|
||||
get: vi.fn((name: string) => (name === 'fa_session' ? sessionId : undefined)),
|
||||
set: vi.fn(),
|
||||
delete: vi.fn()
|
||||
};
|
||||
}
|
||||
|
||||
describe('logout action', () => {
|
||||
beforeEach(() => vi.restoreAllMocks());
|
||||
|
||||
it('calls backend /api/auth/logout with the session cookie and redirects to /login', async () => {
|
||||
const mockFetch = vi.fn().mockResolvedValue(new Response(null, { status: 204 }));
|
||||
const cookies = makeCookies('opaque-id');
|
||||
|
||||
await expect(
|
||||
(actions as ActionsRecord).default({ cookies, fetch: mockFetch } as never)
|
||||
).rejects.toMatchObject({ status: 303, location: '/login' });
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledWith(
|
||||
'http://backend:8080/api/auth/logout',
|
||||
expect.objectContaining({
|
||||
method: 'POST',
|
||||
headers: { Cookie: 'fa_session=opaque-id' }
|
||||
})
|
||||
);
|
||||
expect(cookies.delete).toHaveBeenCalledWith('fa_session', { path: '/' });
|
||||
expect(cookies.delete).toHaveBeenCalledWith('auth_token', { path: '/' });
|
||||
});
|
||||
|
||||
it('clears cookies even when the backend logout call fails', async () => {
|
||||
const mockFetch = vi.fn().mockRejectedValue(new Error('connection refused'));
|
||||
const cookies = makeCookies('opaque-id');
|
||||
|
||||
await expect(
|
||||
(actions as ActionsRecord).default({ cookies, fetch: mockFetch } as never)
|
||||
).rejects.toMatchObject({ status: 303, location: '/login' });
|
||||
|
||||
expect(cookies.delete).toHaveBeenCalledWith('fa_session', { path: '/' });
|
||||
});
|
||||
|
||||
it('skips the backend call when no session cookie is present', async () => {
|
||||
const mockFetch = vi.fn();
|
||||
const cookies = makeCookies(undefined);
|
||||
|
||||
await expect(
|
||||
(actions as ActionsRecord).default({ cookies, fetch: mockFetch } as never)
|
||||
).rejects.toMatchObject({ status: 303, location: '/login' });
|
||||
|
||||
expect(mockFetch).not.toHaveBeenCalled();
|
||||
expect(cookies.delete).toHaveBeenCalledWith('fa_session', { path: '/' });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user