mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
egregoros compat
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ApiClient } from './client'
|
||||
|
||||
function response(body: unknown, status = 200, headers: Record<string, string> = {}): Response {
|
||||
return new Response(JSON.stringify(body), {
|
||||
status,
|
||||
headers: { 'Content-Type': 'application/json', ...headers },
|
||||
})
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
|
||||
describe('ApiClient Egregoros compatibility', () => {
|
||||
it('refreshes an expired bearer token once and retries the request', async () => {
|
||||
const refreshToken = vi.fn().mockResolvedValue('fresh-token')
|
||||
const fetchMock = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce(response({ error: 'Invalid or expired token' }, 401))
|
||||
.mockResolvedValueOnce(response({ id: 'alice' }))
|
||||
vi.stubGlobal('fetch', fetchMock)
|
||||
const client = new ApiClient('egregoros.example', 'expired-token', refreshToken)
|
||||
|
||||
await expect(client.get('/api/v1/accounts/verify_credentials')).resolves.toEqual({
|
||||
id: 'alice',
|
||||
})
|
||||
|
||||
expect(refreshToken).toHaveBeenCalledOnce()
|
||||
expect((fetchMock.mock.calls[0][1].headers as Headers).get('Authorization')).toBe(
|
||||
'Bearer expired-token',
|
||||
)
|
||||
expect((fetchMock.mock.calls[1][1].headers as Headers).get('Authorization')).toBe(
|
||||
'Bearer fresh-token',
|
||||
)
|
||||
})
|
||||
|
||||
it('does not invent a next page when the server supplied only a prev link', async () => {
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn().mockResolvedValue(
|
||||
response(
|
||||
[{ id: 'newest' }, { id: 'oldest' }],
|
||||
200,
|
||||
{
|
||||
Link: '<https://egregoros.example/api/v1/timelines/public?since_id=newest>; rel="prev"',
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
const page = await new ApiClient('egregoros.example').page<{ id: string }>(
|
||||
'/api/v1/timelines/public',
|
||||
{ limit: 20 },
|
||||
)
|
||||
|
||||
expect(page.links.sinceId).toBe('newest')
|
||||
expect(page.links.maxId).toBeUndefined()
|
||||
})
|
||||
|
||||
it('derives a next cursor only for a full page when Link was stripped entirely', async () => {
|
||||
vi.stubGlobal(
|
||||
'fetch',
|
||||
vi.fn().mockResolvedValue(response([{ id: 'newest' }, { id: 'oldest' }])),
|
||||
)
|
||||
|
||||
const page = await new ApiClient('egregoros.example').page<{ id: string }>(
|
||||
'/api/v1/timelines/public',
|
||||
{ limit: 2 },
|
||||
)
|
||||
|
||||
expect(page.links.maxId).toBe('oldest')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user