mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
109 lines
3.3 KiB
TypeScript
109 lines
3.3 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { Session } from './session.svelte'
|
|
|
|
const SESSION_KEY = 'plspace:session'
|
|
const APP_KEY = 'plspace:oauth:apps'
|
|
|
|
function json(body: unknown, status = 200): Response {
|
|
return new Response(JSON.stringify(body), {
|
|
status,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
})
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
describe('Session Egregoros compatibility', () => {
|
|
it('persists and automatically rotates a refresh token after an expired API request', async () => {
|
|
localStorage.setItem(
|
|
SESSION_KEY,
|
|
JSON.stringify({
|
|
host: 'egregoros.example',
|
|
token: 'expired-access-token',
|
|
refreshToken: 'first-refresh-token',
|
|
}),
|
|
)
|
|
localStorage.setItem(
|
|
APP_KEY,
|
|
JSON.stringify({
|
|
'egregoros.example': {
|
|
id: 'app-1',
|
|
name: 'plspace',
|
|
client_id: 'client-id',
|
|
client_secret: 'client-secret',
|
|
redirect_uri: `${window.location.origin}${window.location.pathname}`,
|
|
plspace_redirect_uri: `${window.location.origin}${window.location.pathname}`,
|
|
},
|
|
}),
|
|
)
|
|
|
|
const verifyCalls: string[] = []
|
|
vi.stubGlobal(
|
|
'fetch',
|
|
vi.fn(async (url: string, init?: RequestInit) => {
|
|
if (url.endsWith('/api/v2/instance')) {
|
|
return json({ title: 'Egregoros', version: 'egregoros/0.1.0' })
|
|
}
|
|
if (url.endsWith('/oauth/token')) {
|
|
expect(Object.fromEntries(new URLSearchParams(String(init?.body)))).toMatchObject({
|
|
grant_type: 'refresh_token',
|
|
refresh_token: 'first-refresh-token',
|
|
})
|
|
return json({
|
|
access_token: 'fresh-access-token',
|
|
refresh_token: 'rotated-refresh-token',
|
|
token_type: 'Bearer',
|
|
scope: 'read write follow',
|
|
created_at: 123,
|
|
expires_in: 3600,
|
|
})
|
|
}
|
|
if (url.endsWith('/api/v1/accounts/verify_credentials')) {
|
|
const authorization = (init?.headers as Headers).get('Authorization') ?? ''
|
|
verifyCalls.push(authorization)
|
|
if (authorization === 'Bearer expired-access-token') {
|
|
return json({ error: 'Invalid or expired token' }, 401)
|
|
}
|
|
return json({
|
|
id: 'account-1',
|
|
username: 'alice',
|
|
acct: 'alice',
|
|
display_name: 'Alice',
|
|
note: '',
|
|
url: 'https://egregoros.example/@alice',
|
|
avatar: '',
|
|
avatar_static: '',
|
|
header: '',
|
|
header_static: '',
|
|
locked: false,
|
|
created_at: '2026-01-01T00:00:00Z',
|
|
statuses_count: 0,
|
|
followers_count: 0,
|
|
following_count: 0,
|
|
fields: [],
|
|
emojis: [],
|
|
})
|
|
}
|
|
throw new Error(`Unexpected request: ${url}`)
|
|
}),
|
|
)
|
|
|
|
const session = new Session()
|
|
await session.restore()
|
|
|
|
expect(verifyCalls).toEqual([
|
|
'Bearer expired-access-token',
|
|
'Bearer fresh-access-token',
|
|
])
|
|
expect(session.token).toBe('fresh-access-token')
|
|
expect(session.signedIn).toBe(true)
|
|
expect(JSON.parse(String(localStorage.getItem(SESSION_KEY)))).toEqual({
|
|
host: 'egregoros.example',
|
|
token: 'fresh-access-token',
|
|
refreshToken: 'rotated-refresh-token',
|
|
})
|
|
})
|
|
})
|