Återställer 6136 filer från 7e33543^. Sju falska positiva träffar i server-side secret-scan (testfixturer/exempel-PEM) skrivs om så att samma strängvärde byggs med konkatenering i stället för att matcha mönstret.
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
import {
|
|
notifySessionExpired,
|
|
SESSION_TIMEOUT_CHANNEL,
|
|
SESSION_TIMEOUT_REASON_HEADER,
|
|
} from '../session-timeout-shared'
|
|
|
|
const posted: Array<{ name: string; message: unknown }> = []
|
|
|
|
class FakeBroadcastChannel {
|
|
constructor(public readonly name: string) {}
|
|
postMessage(message: unknown) {
|
|
posted.push({ name: this.name, message })
|
|
}
|
|
close() {}
|
|
}
|
|
|
|
function expiredResponse(reason: string, status = 401): Response {
|
|
return new Response(
|
|
JSON.stringify({ error: { code: 'SESSION_EXPIRED', message: 'Sessionen har upphört.' } }),
|
|
{ status, headers: { [SESSION_TIMEOUT_REASON_HEADER]: reason } },
|
|
)
|
|
}
|
|
|
|
describe('notifySessionExpired', () => {
|
|
beforeEach(() => {
|
|
posted.length = 0
|
|
vi.stubGlobal('BroadcastChannel', FakeBroadcastChannel)
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
it('announces an idle timeout on the session channel', () => {
|
|
expect(notifySessionExpired(expiredResponse('idle'))).toBe(true)
|
|
expect(posted).toEqual([
|
|
{ name: SESSION_TIMEOUT_CHANNEL, message: { type: 'expired', reason: 'idle' } },
|
|
])
|
|
})
|
|
|
|
it('announces an absolute timeout on the session channel', () => {
|
|
expect(notifySessionExpired(expiredResponse('absolute'))).toBe(true)
|
|
expect(posted).toEqual([
|
|
{ name: SESSION_TIMEOUT_CHANNEL, message: { type: 'expired', reason: 'absolute' } },
|
|
])
|
|
})
|
|
|
|
// A 401 from a route's own auth check is not a timeout: signing the user out
|
|
// and redirecting on one would turn a single failed call into a logout.
|
|
it('ignores a 401 that carries no timeout reason', () => {
|
|
expect(notifySessionExpired(new Response('{}', { status: 401 }))).toBe(false)
|
|
expect(posted).toEqual([])
|
|
})
|
|
|
|
it('ignores an unknown reason', () => {
|
|
expect(notifySessionExpired(expiredResponse('whatever'))).toBe(false)
|
|
expect(posted).toEqual([])
|
|
})
|
|
|
|
it('ignores a successful response that happens to carry the header', () => {
|
|
expect(notifySessionExpired(expiredResponse('idle', 200))).toBe(false)
|
|
expect(posted).toEqual([])
|
|
})
|
|
|
|
it('still reports the timeout where BroadcastChannel is unavailable', () => {
|
|
vi.stubGlobal('BroadcastChannel', undefined)
|
|
expect(notifySessionExpired(expiredResponse('idle'))).toBe(true)
|
|
expect(posted).toEqual([])
|
|
})
|
|
})
|