// @vitest-environment jsdom // // The API-keys page. We stub `fetch` to the framework's `/v1/api-keys` surface // and assert the two paths that matter for a template shipped against an api // that does NOT enable keys by default: a 404 shows the "enable apiKeys" notice // (degrade, don't break), and a 200 renders the key list + issue form. import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' import { act, createElement, type ReactNode } from 'react' import { createRoot, type Root } from 'react-dom/client' import { I18nProvider } from '@voltro/i18n' import enCatalog from '../../../locales/en' const { default: ApiKeys } = await import('./page') ;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true let container: HTMLDivElement let root: Root const render = (node: ReactNode): void => { container = document.createElement('div') document.body.appendChild(container) act(() => { root = createRoot(container) root.render( createElement(I18nProvider, { locale: 'en', messages: enCatalog, defaultLocale: 'en', children: node }), ) }) } const stubFetch = (status: number, body: unknown): void => { ;(globalThis as { fetch: unknown }).fetch = vi.fn(async () => ({ ok: status >= 200 && status < 300, status, json: async () => body, })) as unknown as typeof fetch } const flush = async (): Promise => { await act(async () => { await Promise.resolve(); await Promise.resolve() }) } afterEach(() => { if (root) act(() => root.unmount()) container?.remove() document.body.innerHTML = '' }) beforeEach(() => { vi.restoreAllMocks() }) describe('api-keys — graceful states', () => { test('a 404 (apiKeys not enabled) shows the enable notice, not a broken table', async () => { stubFetch(404, { error: 'not_found' }) render(createElement(ApiKeys)) await flush() expect(container.querySelector('.notice')).not.toBeNull() expect(container.textContent).toContain('aren’t enabled') // No issue form when the surface is unavailable. expect(container.querySelector('form')).toBeNull() }) test('a 200 renders the key list and the issue form', async () => { stubFetch(200, { keys: [{ id: 'k1', name: 'CI', keyPrefix: 'voltro_ab', createdAt: 0, lastUsedAt: null, revokedAt: null }] }) render(createElement(ApiKeys)) await flush() expect(container.querySelector('form')).not.toBeNull() expect(container.textContent).toContain('CI') expect(container.textContent).toContain('voltro_ab') }) })