feat: productionize learning engine and classroom
This commit is contained in:
92
OpenMAIC/tests/lib/ops/api-fetch.test.ts
Normal file
92
OpenMAIC/tests/lib/ops/api-fetch.test.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
// @vitest-environment jsdom
|
||||
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { installOpsBrowserBoundary } from '@/lib/ops/api-fetch';
|
||||
|
||||
const AUTH_STORAGE_KEY = 'works-square.operations.auth.v1';
|
||||
|
||||
describe('installOpsBrowserBoundary', () => {
|
||||
let nativeFetch: ReturnType<typeof vi.fn>;
|
||||
let cleanup: (() => void) | undefined;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.stubEnv('NEXT_PUBLIC_OPENMAIC_DEPLOYMENT_ROLE', 'ops');
|
||||
vi.stubEnv('NEXT_PUBLIC_OPENMAIC_BASE_PATH', '/learning-ops');
|
||||
window.localStorage.clear();
|
||||
nativeFetch = vi.fn(async () => new Response(null, { status: 204 }));
|
||||
window.fetch = nativeFetch as unknown as typeof window.fetch;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanup?.();
|
||||
cleanup = undefined;
|
||||
window.localStorage.clear();
|
||||
vi.unstubAllEnvs();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('maps root-relative API requests to the Ops basePath and adds the Works bearer token', async () => {
|
||||
window.localStorage.setItem(
|
||||
AUTH_STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
accessToken: 'works-access-token',
|
||||
expiresAt: Date.now() + 60_000,
|
||||
}),
|
||||
);
|
||||
cleanup = installOpsBrowserBoundary();
|
||||
|
||||
await window.fetch('/api/server-providers', {
|
||||
method: 'POST',
|
||||
headers: { 'X-Request-Id': 'request-1' },
|
||||
});
|
||||
|
||||
expect(nativeFetch).toHaveBeenCalledTimes(1);
|
||||
const [input, init] = nativeFetch.mock.calls[0] as [RequestInfo | URL, RequestInit];
|
||||
expect(input).toBe('/learning-ops/api/server-providers');
|
||||
expect(init.method).toBe('POST');
|
||||
const headers = new Headers(init.headers);
|
||||
expect(headers.get('Authorization')).toBe('Bearer works-access-token');
|
||||
expect(headers.get('X-Request-Id')).toBe('request-1');
|
||||
});
|
||||
|
||||
it('leaves external URLs and unrelated root-relative paths unchanged', async () => {
|
||||
cleanup = installOpsBrowserBoundary();
|
||||
|
||||
await window.fetch('https://example.test/api/courses');
|
||||
await window.fetch('/courses/course-1', { method: 'GET' });
|
||||
|
||||
expect(nativeFetch).toHaveBeenNthCalledWith(1, 'https://example.test/api/courses', {});
|
||||
expect(nativeFetch).toHaveBeenNthCalledWith(2, '/courses/course-1', { method: 'GET' });
|
||||
});
|
||||
|
||||
it('restores unwrapped fetch behavior when cleaned up', async () => {
|
||||
cleanup = installOpsBrowserBoundary();
|
||||
const wrappedFetch = window.fetch;
|
||||
|
||||
cleanup();
|
||||
cleanup = undefined;
|
||||
|
||||
expect(window.fetch).not.toBe(wrappedFetch);
|
||||
await window.fetch('/api/server-providers');
|
||||
expect(nativeFetch).toHaveBeenCalledTimes(1);
|
||||
expect(nativeFetch.mock.calls[0]?.[0]).toBe('/api/server-providers');
|
||||
});
|
||||
|
||||
it.each([
|
||||
{
|
||||
label: 'expired session',
|
||||
value: JSON.stringify({ accessToken: 'expired-token', expiresAt: Date.now() - 1 }),
|
||||
},
|
||||
{ label: 'malformed session JSON', value: '{not-json' },
|
||||
{ label: 'session without a string token', value: JSON.stringify({ accessToken: 123 }) },
|
||||
])('does not add Authorization for a $label', async ({ value }) => {
|
||||
window.localStorage.setItem(AUTH_STORAGE_KEY, value);
|
||||
cleanup = installOpsBrowserBoundary();
|
||||
|
||||
await window.fetch('/api/server-providers');
|
||||
|
||||
const [, init] = nativeFetch.mock.calls[0] as [RequestInfo | URL, RequestInit];
|
||||
expect(new Headers(init.headers).has('Authorization')).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user