mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 16:02:14 +00:00
8500435e82
Self-hosted instances that embed their own UI (Windmill as backend, custom
app at the instance root) can't be redirected back to their app after OAuth
login: isValidLogoutRedirect rejects same-origin absolute URLs, so the login
callback falls back to a client-side goto('/') into Windmill's own dashboard.
Same-origin redirects are never open redirects (and toSameOriginRelativePath
already treats them as safe), so accept them.
Also make the test-setup window global configurable so vitest's stubGlobal
can redefine it across the window-stubbing test suites.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
103 lines
2.3 KiB
TypeScript
103 lines
2.3 KiB
TypeScript
/**
|
|
* Vitest setup file to mock browser globals for testing
|
|
*/
|
|
|
|
// Provides a real in-memory IndexedDB (indexedDB / IDBKeyRange / structuredClone)
|
|
// under the node test environment so the IndexedDB-backed session list and
|
|
// chat-history stores can be exercised in unit tests.
|
|
import 'fake-indexeddb/auto'
|
|
import { vi } from 'vitest'
|
|
|
|
// Mock localStorage
|
|
const localStorageMock = {
|
|
store: {} as Record<string, string>,
|
|
getItem(key: string) {
|
|
return this.store[key] ?? null
|
|
},
|
|
setItem(key: string, value: string) {
|
|
this.store[key] = value
|
|
},
|
|
removeItem(key: string) {
|
|
delete this.store[key]
|
|
},
|
|
clear() {
|
|
this.store = {}
|
|
},
|
|
get length() {
|
|
return Object.keys(this.store).length
|
|
},
|
|
key(index: number) {
|
|
return Object.keys(this.store)[index] ?? null
|
|
}
|
|
}
|
|
|
|
// Mock sessionStorage
|
|
const sessionStorageMock = {
|
|
store: {} as Record<string, string>,
|
|
getItem(key: string) {
|
|
return this.store[key] ?? null
|
|
},
|
|
setItem(key: string, value: string) {
|
|
this.store[key] = value
|
|
},
|
|
removeItem(key: string) {
|
|
delete this.store[key]
|
|
},
|
|
clear() {
|
|
this.store = {}
|
|
},
|
|
get length() {
|
|
return Object.keys(this.store).length
|
|
},
|
|
key(index: number) {
|
|
return Object.keys(this.store)[index] ?? null
|
|
}
|
|
}
|
|
|
|
// Assign to globalThis
|
|
Object.defineProperty(globalThis, 'localStorage', {
|
|
value: localStorageMock,
|
|
writable: true
|
|
})
|
|
|
|
Object.defineProperty(globalThis, 'sessionStorage', {
|
|
value: sessionStorageMock,
|
|
writable: true
|
|
})
|
|
|
|
// Some modules (e.g. svelte5Utils.useLocalStorageValue) gate browser-only
|
|
// behavior on `typeof window`. Provide a minimal window so they don't
|
|
// short-circuit during tests.
|
|
if (typeof (globalThis as any).window === 'undefined') {
|
|
Object.defineProperty(globalThis, 'window', {
|
|
value: globalThis,
|
|
writable: true,
|
|
configurable: true
|
|
})
|
|
}
|
|
|
|
vi.mock('@codingame/monaco-vscode-standalone-typescript-language-features/worker', () => ({
|
|
TypeScriptWorker: class TypeScriptWorker {
|
|
private _mockScriptSnapshot?: {
|
|
getText: (start: number, end: number) => string
|
|
getLength: () => number
|
|
}
|
|
|
|
setMockCode(t: string) {
|
|
this._mockScriptSnapshot = {
|
|
getText: (start: number, end: number) => t.substring(start, end),
|
|
getLength: () => t.length
|
|
}
|
|
}
|
|
|
|
getScriptSnapshot(_fileName: string) {
|
|
return this._mockScriptSnapshot
|
|
}
|
|
getScriptVersion(_fileName: string) {
|
|
return '1'
|
|
}
|
|
},
|
|
ts: undefined,
|
|
initialize: undefined
|
|
}))
|