client-sdk.test.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233
  1. import { describe, expect, it } from 'vitest'
  2. import { AgentClient, browserTokenProvider } from '../../../packages/client/src/index'
  3. describe('客户端 SDK:浏览器令牌', () => {
  4. it('缓存令牌、并发共用一次获取、过期前 60 秒换新', async () => {
  5. let calls = 0
  6. let ttl = 3600_000
  7. const provider = browserTokenProvider(async () => {
  8. calls++
  9. await new Promise(r => setTimeout(r, 10))
  10. return { token: `bt_${calls}`, expiresAt: new Date(Date.now() + ttl).toISOString() }
  11. })
  12. const [a, b] = await Promise.all([provider({ refresh: false }), provider({ refresh: false })])
  13. expect([a, b, calls]).toEqual(['bt_1', 'bt_1', 1])
  14. expect(await provider({ refresh: false })).toBe('bt_1')
  15. expect(await provider({ refresh: true })).toBe('bt_2')
  16. ttl = 30_000 // 快过期的令牌下次使用时换新
  17. expect(await provider({ refresh: true })).toBe('bt_3')
  18. expect(await provider({ refresh: false })).toBe('bt_4')
  19. })
  20. it('401 时刷新令牌并重试一次;不携带跨域 Cookie', async () => {
  21. const seen: { auth: string | null; credentials: RequestInit['credentials'] }[] = []
  22. const fetchImpl = (async (_url: string, init: RequestInit) => {
  23. const auth = (init.headers as Record<string, string>).authorization ?? null
  24. seen.push({ auth, credentials: init.credentials })
  25. return auth === 'Bearer bt_new' ? new Response('[]', { status: 200 }) : new Response(JSON.stringify({ error: { code: 'invalid_token', message: 'x' } }), { status: 401 })
  26. }) as typeof fetch
  27. const client = new AgentClient({ baseUrl: 'https://agent.example.com', fetch: fetchImpl, getToken: ({ refresh }) => (refresh ? 'bt_new' : 'bt_old') })
  28. expect(await client.profiles()).toEqual([])
  29. expect(seen).toEqual([{ auth: 'Bearer bt_old', credentials: 'same-origin' }, { auth: 'Bearer bt_new', credentials: 'same-origin' }])
  30. })
  31. })