import {describe, it, expect, vi} from 'vitest';
import {getRedirectUrl, InvalidStateError} from './oauth-bridge.js';
import {GmailOAuthServerProvider} from './gmail/oauth-provider.js';
describe('oauth-bridge', () => {
describe('getRedirectUrl', () => {
it('parses state and returns redirect URL', async () => {
const requestId = '550e8400-e29b-41d4-a716-446655440000';
const mockProvider = {
handleGoogleCallback: vi.fn().mockResolvedValue({
redirectUrl: 'https://client.example.com/callback?code=abc',
}),
} as unknown as GmailOAuthServerProvider;
const result = await getRedirectUrl(
mockProvider,
'google-auth-code',
requestId
);
expect(result).toBe('https://client.example.com/callback?code=abc');
expect(mockProvider.handleGoogleCallback).toHaveBeenCalledWith(
requestId,
'google-auth-code'
);
});
it('throws InvalidStateError when state contains invalid UUID format', async () => {
const mockProvider = {} as GmailOAuthServerProvider;
await expect(
getRedirectUrl(mockProvider, 'code', 'not-a-uuid')
).rejects.toThrow(InvalidStateError);
});
it('throws InvalidStateError when state is not a valid UUID', async () => {
const mockProvider = {} as GmailOAuthServerProvider;
await expect(
getRedirectUrl(mockProvider, 'code', 'invalid-state')
).rejects.toThrow(InvalidStateError);
});
it('throws InvalidStateError when state is empty', async () => {
const mockProvider = {} as GmailOAuthServerProvider;
await expect(
getRedirectUrl(mockProvider, 'code', '')
).rejects.toThrow(InvalidStateError);
});
it('throws InvalidStateError when state has extra characters', async () => {
const mockProvider = {} as GmailOAuthServerProvider;
await expect(
getRedirectUrl(mockProvider, 'code', '550e8400-e29b-41d4-a716-446655440000-extra')
).rejects.toThrow(InvalidStateError);
});
});
describe('InvalidStateError', () => {
it('has correct message', () => {
const error = new InvalidStateError();
expect(error.message).toBe('Invalid state parameter format');
expect(error.name).toBe('InvalidStateError');
});
});
});