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: '/' });
	});
});
