83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
|
|
import { vi, describe, it, expect } from 'vitest';
|
||
|
|
|
||
|
|
// Define environment variables required statically by auth.ts
|
||
|
|
process.env.KEYCLOAK_URL = 'http://keycloak-internal';
|
||
|
|
process.env.NEXT_PUBLIC_KEYCLOAK_URL = 'https://keycloak-public';
|
||
|
|
process.env.KEYCLOAK_REALM = 'meshitrack';
|
||
|
|
process.env.KEYCLOAK_CLIENT_ID = 'web-client';
|
||
|
|
process.env.KEYCLOAK_CLIENT_SECRET = 'secret';
|
||
|
|
|
||
|
|
vi.mock('next-auth', () => {
|
||
|
|
return {
|
||
|
|
default: vi.fn((config) => {
|
||
|
|
(globalThis as any).__capturedConfig = config;
|
||
|
|
return {
|
||
|
|
handlers: { GET: vi.fn(), POST: vi.fn() },
|
||
|
|
signIn: vi.fn(),
|
||
|
|
signOut: vi.fn(),
|
||
|
|
auth: vi.fn(),
|
||
|
|
};
|
||
|
|
}),
|
||
|
|
};
|
||
|
|
});
|
||
|
|
|
||
|
|
vi.mock('next-auth/providers/keycloak', () => {
|
||
|
|
return {
|
||
|
|
default: vi.fn((config) => config),
|
||
|
|
};
|
||
|
|
});
|
||
|
|
|
||
|
|
// Import auth.ts to trigger the NextAuth config capture
|
||
|
|
import { auth } from '../../src/lib/auth';
|
||
|
|
|
||
|
|
describe('auth library configuration', () => {
|
||
|
|
it('initializes NextAuth with correct pages and structures', () => {
|
||
|
|
expect(auth).toBeDefined();
|
||
|
|
const config = (globalThis as any).__capturedConfig;
|
||
|
|
expect(config).toBeDefined();
|
||
|
|
expect(config.pages.signIn).toBe('/login');
|
||
|
|
expect(config.callbacks).toBeDefined();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('jwt callback appends access tokens when account metadata is present', async () => {
|
||
|
|
const config = (globalThis as any).__capturedConfig;
|
||
|
|
const jwtCallback = config.callbacks.jwt;
|
||
|
|
const token = { name: 'Admin' };
|
||
|
|
const account = {
|
||
|
|
access_token: 'jwt-access-token-xyz',
|
||
|
|
refresh_token: 'jwt-refresh-token-abc',
|
||
|
|
expires_at: 1999999999,
|
||
|
|
};
|
||
|
|
|
||
|
|
const result = await jwtCallback({ token, account });
|
||
|
|
expect(result).toEqual({
|
||
|
|
name: 'Admin',
|
||
|
|
accessToken: 'jwt-access-token-xyz',
|
||
|
|
refreshToken: 'jwt-refresh-token-abc',
|
||
|
|
expiresAt: 1999999999,
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('jwt callback returns standard token without change if account metadata is missing', async () => {
|
||
|
|
const config = (globalThis as any).__capturedConfig;
|
||
|
|
const jwtCallback = config.callbacks.jwt;
|
||
|
|
const token = { name: 'Admin', accessToken: 'pre-existing-token' };
|
||
|
|
|
||
|
|
const result = await jwtCallback({ token, account: undefined });
|
||
|
|
expect(result).toEqual({
|
||
|
|
name: 'Admin',
|
||
|
|
accessToken: 'pre-existing-token',
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('session callback populates access token from jwt metadata', async () => {
|
||
|
|
const config = (globalThis as any).__capturedConfig;
|
||
|
|
const sessionCallback = config.callbacks.session;
|
||
|
|
const session = { user: { name: 'Admin' } } as any;
|
||
|
|
const token = { accessToken: 'extracted-token-from-jwt' };
|
||
|
|
|
||
|
|
const result = await sessionCallback({ session, token });
|
||
|
|
expect(result.accessToken).toBe('extracted-token-from-jwt');
|
||
|
|
});
|
||
|
|
});
|