Details (original message): Add the API key login gate and credential-aware API/SSE client (owner-scoped multi-user)
44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
// 认证模块行为测试:密钥存取(无 DOM 回退内存)、凭证注入、资源 URL 追加 key。
|
|
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
|
import { auth } from '../src/auth'
|
|
|
|
describe('auth 凭证模块', () => {
|
|
beforeEach(() => {
|
|
auth.clear()
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
it('未设置密钥时 fetch 透传(无 Authorization 头)', async () => {
|
|
const spy = vi.fn().mockResolvedValue(new Response('{}'))
|
|
vi.stubGlobal('fetch', spy)
|
|
await auth.fetch('/api/projects')
|
|
const [, init] = spy.mock.calls[0] as [string, RequestInit | undefined]
|
|
const headers = new Headers(init?.headers ?? {})
|
|
expect(headers.get('Authorization')).toBeNull()
|
|
})
|
|
|
|
it('设置密钥后 fetch 注入 Bearer 头', async () => {
|
|
auth.setKey('ask_test123')
|
|
const spy = vi.fn().mockResolvedValue(new Response('{}'))
|
|
vi.stubGlobal('fetch', spy)
|
|
await auth.fetch('/api/projects', { method: 'POST' })
|
|
const [, init] = spy.mock.calls[0] as [string, RequestInit]
|
|
expect(new Headers(init.headers).get('Authorization')).toBe('Bearer ask_test123')
|
|
expect(init.method).toBe('POST') // 原有 init 语义保留
|
|
})
|
|
|
|
it('withKey:无密钥不改 URL;有密钥按是否含 ? 选择连接符', () => {
|
|
expect(auth.withKey('/api/artifacts/a/content')).toBe('/api/artifacts/a/content')
|
|
auth.setKey('ask_k')
|
|
expect(auth.withKey('/api/events?conversationId=c1')).toBe('/api/events?conversationId=c1&key=ask_k')
|
|
expect(auth.withKey('/api/artifacts/a/content')).toBe('/api/artifacts/a/content?key=ask_k')
|
|
})
|
|
|
|
it('clear 后恢复无凭证状态', () => {
|
|
auth.setKey('ask_x')
|
|
auth.clear()
|
|
expect(auth.apiKey()).toBe('')
|
|
expect(auth.withKey('/x')).toBe('/x')
|
|
})
|
|
})
|