import assert from 'node:assert/strict'; import { fileURLToPath } from 'node:url'; import vue from '@vitejs/plugin-vue'; import { createServer } from 'vite'; import { createSSRApp, h } from 'vue'; import { renderToString } from 'vue/server-renderer'; import { createInertiaApp } from '@inertiajs/vue3'; const server = await createServer({ configFile: false, plugins: [vue()], resolve: { alias: { '@': fileURLToPath(new URL('../../resources/js', import.meta.url)), }, }, server: { middlewareMode: true, hmr: false, watch: null }, appType: 'custom', }); try { const { createLocalization } = await server.ssrLoadModule( '/resources/js/lib/localization.ts', ); const { createAppearance } = await server.ssrLoadModule( '/resources/js/composables/useAppearance.ts', ); const { initializeNativeApp, useNativeApp, registerNativeRecovery } = await server.ssrLoadModule('/resources/js/composables/useNativeApp.ts'); const { isNativeAppState } = await server.ssrLoadModule( '/resources/js/lib/native-app.ts', ); const App = ( await server.ssrLoadModule('/resources/js/pages/settings/App.vue') ).default; const Appearance = ( await server.ssrLoadModule( '/resources/js/pages/settings/Appearance.vue', ) ).default; const render = async (signedIn = false, component = App) => { const result = await createInertiaApp({ page: { component: 'settings/App', url: '/settings/app', version: null, clearHistory: false, encryptHistory: false, props: { name: 'KanbanGit', errors: {}, sidebarOpen: true, appearance: 'system', auth: { user: signedIn ? { name: 'Test', email: 'test@example.test' } : null, permissions: { globalAdmin: false, projectCreate: false, canManageTeams: false, }, }, navigation: { project: null }, }, }, resolve: () => component, render: renderToString, setup: ({ App, props, plugin }) => createSSRApp({ render: () => h(App, props) }) .use(plugin) .use(createLocalization()) .use(createAppearance('system')), }); return result.body; }; await initializeNativeApp(); assert.match(await render(), /compatible KanbanGit app/); assert.doesNotMatch( await render(true, Appearance), /href="\/settings\/app"/, ); let calls = []; let current = { apiVersion: 1, platform: 'ios', version: '1.0.0', workspace: 'https://example.test/app/', capabilities: ['workspace'], }; const bridge = { version: 2, request: async (action, payload) => { calls.push([action, payload]); return structuredClone(current); }, }; globalThis.window = { kanbanNative: bridge }; await initializeNativeApp(); assert.equal(calls.length, 0); bridge.version = 1; current.apiVersion = 2; await initializeNativeApp(); assert.equal(useNativeApp().state.value, null); current.apiVersion = 1; await initializeNativeApp(); assert.equal(calls.at(-1)[0], 'settingsReady'); delete globalThis.window; let html = await render(); assert.match(html, /value="https:\/\/example.test\/app\/"/); assert.doesNotMatch( html, /Check for updates now|Install update|native-update-interval/, ); assert.match(await render(true, Appearance), /href="\/settings\/app"/); current = { ...current, platform: 'macos', capabilities: ['workspace', 'updates'], updates: { phase: 'available', currentVersion: '1.0.0', build: '1', version: '1.1.0', notes: '', downloaded: 0, total: null, error: null, preferences: { automatic: true, intervalHours: 6 }, }, }; globalThis.window = { kanbanNative: bridge }; await useNativeApp().poll(); delete globalThis.window; html = await render(true); assert.match(html, /Check for updates now/); assert.match(html, /Install update/); assert.match(html, /<script>bad/); assert.doesNotMatch(html, /