Files
dockhand-upstream/tests/oidc-discovery-url.test.ts

61 lines
2.5 KiB
TypeScript

import { describe, it, expect } from 'bun:test';
import { oidcDiscoveryUrls, fetchOidcDiscovery } from '../src/lib/utils/oidc-discovery-url';
const ok = (statusText = 'OK') => ({ ok: true, statusText });
const notOk = (statusText: string) => ({ ok: false, statusText });
describe('oidcDiscoveryUrls', () => {
it('tries the canonical (no trailing slash) URL first, then the trailing-slash variant', () => {
expect(oidcDiscoveryUrls('https://idp.example.com/realm')).toEqual([
'https://idp.example.com/realm/.well-known/openid-configuration',
'https://idp.example.com/realm/.well-known/openid-configuration/'
]);
});
it('normalises an issuer that already ends with a slash (no double slash)', () => {
expect(oidcDiscoveryUrls('https://idp.example.com/realm/')).toEqual([
'https://idp.example.com/realm/.well-known/openid-configuration',
'https://idp.example.com/realm/.well-known/openid-configuration/'
]);
});
it('handles a bare-host issuer', () => {
expect(oidcDiscoveryUrls('https://idp.example.com')).toEqual([
'https://idp.example.com/.well-known/openid-configuration',
'https://idp.example.com/.well-known/openid-configuration/'
]);
});
});
describe('fetchOidcDiscovery', () => {
it('returns the FIRST url on OK - a compliant provider never sees the fallback', async () => {
const tried: string[] = [];
const r = await fetchOidcDiscovery(['a', 'b'], async (u) => { tried.push(u); return ok(); });
expect(tried).toEqual(['a']);
expect(r.ok).toBe(true);
});
it('falls back to the trailing-slash url when the canonical one is 404 (#1368)', async () => {
const tried: string[] = [];
const r = await fetchOidcDiscovery(['canon', 'canon/'], async (u) => {
tried.push(u);
return u.endsWith('/') ? ok() : notOk('Not Found');
});
expect(tried).toEqual(['canon', 'canon/']);
expect(r.ok).toBe(true);
});
it('throws with the last statusText when every url is not-ok', async () => {
await expect(fetchOidcDiscovery(['a', 'b'], async () => notOk('Not Found')))
.rejects.toThrow('Failed to fetch OIDC discovery document: Not Found');
});
it('a network error is fatal - does NOT fall through to the next url', async () => {
const tried: string[] = [];
const boom = Object.assign(new TypeError('fetch failed'), { cause: { code: 'ENOTFOUND' } });
await expect(fetchOidcDiscovery(['a', 'b'], async (u) => { tried.push(u); throw boom; }))
.rejects.toThrow('Failed to reach OIDC issuer at a: fetch failed (ENOTFOUND)');
expect(tried).toEqual(['a']); // stopped at the first, did not try 'b'
});
});