mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-01 04:21:58 +00:00
66 lines
3.6 KiB
TypeScript
66 lines
3.6 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import { ResolveSpecClient, getResolveSpecClient } from '../resolvespec/client';
|
|
import { HeaderSpecClient, getHeaderSpecClient } from '../headerspec/client';
|
|
|
|
afterEach(() => vi.unstubAllGlobals());
|
|
|
|
for (const [name, Client, factory] of [
|
|
['ResolveSpec', ResolveSpecClient, getResolveSpecClient],
|
|
['HeaderSpec', HeaderSpecClient, getHeaderSpecClient],
|
|
] as const) {
|
|
describe(`${name} custom headers`, () => {
|
|
it('sends tenant headers on every operation and resolves collisions case-insensitively', async () => {
|
|
const fetchMock = vi.fn().mockResolvedValue({
|
|
ok: true, headers: new Headers(), json: async () => ({ success: true, data: [] }),
|
|
});
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
const headers = { 'X-Tenant': 'acme', authorization: 'Basic ignored', 'content-type': 'application/custom+json', 'x-limit': '99' };
|
|
const client = new Client({ baseUrl: 'http://localhost:3000', token: 'tok', headers });
|
|
await client.read('public', 'users', undefined, { limit: 10 });
|
|
await client.create('public', 'users', {});
|
|
if (client instanceof ResolveSpecClient) {
|
|
await client.update('public', 'users', {}, '1');
|
|
await client.getMetadata('public', 'users');
|
|
} else {
|
|
await client.update('public', 'users', '1', {});
|
|
}
|
|
await client.delete('public', 'users', '1');
|
|
for (const [, init] of fetchMock.mock.calls) {
|
|
const sent = new Headers(init.headers);
|
|
expect(sent.get('x-tenant')).toBe('acme');
|
|
expect(sent.get('authorization')).toBe('Bearer tok');
|
|
expect(sent.get('content-type')).toBe('application/custom+json');
|
|
}
|
|
if (client instanceof HeaderSpecClient) {
|
|
expect(new Headers(fetchMock.mock.calls[0][1].headers).get('x-limit')).toBe('10');
|
|
}
|
|
expect(headers.authorization).toBe('Basic ignored');
|
|
expect(headers['x-limit']).toBe('99');
|
|
});
|
|
|
|
it('supports custom authentication without a token', async () => {
|
|
const fetchMock = vi.fn().mockResolvedValue({
|
|
ok: true, headers: new Headers(), json: async () => ({ success: true, data: [] }),
|
|
});
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
await new Client({ baseUrl: 'http://localhost:3000', headers: { Authorization: 'Basic custom' } }).read('public', 'users');
|
|
expect(new Headers(fetchMock.mock.calls[0][1].headers).get('authorization')).toBe('Basic custom');
|
|
});
|
|
|
|
it('isolates cached clients by headers and token, and snapshots configuration', async () => {
|
|
const config = { baseUrl: 'http://tenant-cache', token: 'one', headers: { 'X-Tenant': 'acme', 'X-App': 'grid' } };
|
|
const first = factory(config);
|
|
expect(factory({ ...config, headers: { 'x-app': 'grid', 'x-tenant': 'acme' } })).toBe(first);
|
|
expect(factory({ ...config, token: 'two' })).not.toBe(first);
|
|
config.headers['X-Tenant'] = 'other';
|
|
expect(factory(config)).not.toBe(first);
|
|
const fetchMock = vi.fn().mockResolvedValue({
|
|
ok: true, headers: new Headers(), json: async () => ({ success: true, data: [] }),
|
|
});
|
|
vi.stubGlobal('fetch', fetchMock);
|
|
await first.read('public', 'users');
|
|
expect(new Headers(fetchMock.mock.calls[0][1].headers).get('x-tenant')).toBe('acme');
|
|
});
|
|
});
|
|
}
|