161 lines
6.4 KiB
JavaScript
161 lines
6.4 KiB
JavaScript
import { describe, expect, it } from 'vitest'
|
|
|
|
import {
|
|
buildRuntimeReadinessReport,
|
|
deriveHealthBaseUrl,
|
|
parseEnvFile,
|
|
} from './runtime-readiness-lib.mjs'
|
|
|
|
describe('parseEnvFile', () => {
|
|
it('parses simple dotenv-style content with quotes and export prefixes', () => {
|
|
const parsed = parseEnvFile(`
|
|
# comment
|
|
export API_DOMAIN="https://hypertwist.app"
|
|
COOKIE_SECURE=true
|
|
VITE_SUPPORT_EMAIL='hello@hypertwist.app'
|
|
`)
|
|
|
|
expect(parsed).toEqual({
|
|
API_DOMAIN: 'https://hypertwist.app',
|
|
COOKIE_SECURE: 'true',
|
|
VITE_SUPPORT_EMAIL: 'hello@hypertwist.app',
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('buildRuntimeReadinessReport', () => {
|
|
it('passes a fully configured public same-origin posture', () => {
|
|
const report = buildRuntimeReadinessReport({
|
|
frontendEnv: {
|
|
VITE_SUPERTOKENS_API_DOMAIN: 'https://hypertwist.app',
|
|
VITE_SUPERTOKENS_WEBSITE_DOMAIN: 'https://hypertwist.app',
|
|
VITE_AUTH_API_BASE_URL: 'https://hypertwist.app',
|
|
VITE_WINDOWS_DOWNLOAD_URL: 'https://downloads.hypertwist.app/windows.exe',
|
|
VITE_PADDLE_CHECKOUT_URL_OPERATOR: 'https://buy.paddle.com/operator',
|
|
VITE_PADDLE_CHECKOUT_URL_STUDIO: 'https://buy.paddle.com/studio',
|
|
VITE_MPL_SOURCE_URL: 'https://hypertwist.app/open-source/source',
|
|
VITE_OPEN_SOURCE_REPO_URL: 'https://git.scriptoriumai.io/scriptoriumadmin/hypertwist',
|
|
},
|
|
serverEnv: {
|
|
API_DOMAIN: 'https://hypertwist.app',
|
|
WEBSITE_DOMAIN: 'https://hypertwist.app',
|
|
SUPERTOKENS_CORE_URI: 'https://auth-core.internal',
|
|
COOKIE_SECURE: 'true',
|
|
SERVE_STATIC_WEBSITE: 'true',
|
|
PADDLE_WEBHOOK_SECRET: 'secret',
|
|
PADDLE_PRICE_PLAN_MAP: '{"pri_operator":"operator"}',
|
|
},
|
|
liveHealth: {
|
|
supertokens: { ready: true },
|
|
fallback: { active: false },
|
|
runtime: {
|
|
public_origin_ready: true,
|
|
mode: 'public',
|
|
errors: [],
|
|
warnings: [],
|
|
},
|
|
billing: {
|
|
webhookSecretConfigured: true,
|
|
productPlanMapConfigured: false,
|
|
pricePlanMapConfigured: true,
|
|
},
|
|
},
|
|
})
|
|
|
|
expect(report.ok).toBe(true)
|
|
expect(report.failures).toEqual([])
|
|
})
|
|
|
|
it('warns when same-origin public posture leaves static website serving ambiguous', () => {
|
|
const report = buildRuntimeReadinessReport({
|
|
frontendEnv: {
|
|
VITE_SUPERTOKENS_API_DOMAIN: 'https://hypertwist.app',
|
|
VITE_SUPERTOKENS_WEBSITE_DOMAIN: 'https://hypertwist.app',
|
|
VITE_AUTH_API_BASE_URL: 'https://hypertwist.app',
|
|
VITE_WINDOWS_DOWNLOAD_URL: 'https://downloads.hypertwist.app/windows.exe',
|
|
VITE_PADDLE_CHECKOUT_URL_OPERATOR: 'https://buy.paddle.com/operator',
|
|
VITE_MPL_SOURCE_URL: 'https://hypertwist.app/open-source/source',
|
|
VITE_OPEN_SOURCE_REPO_URL: 'https://git.scriptoriumai.io/scriptoriumadmin/hypertwist',
|
|
},
|
|
serverEnv: {
|
|
API_DOMAIN: 'https://hypertwist.app',
|
|
WEBSITE_DOMAIN: 'https://hypertwist.app',
|
|
SUPERTOKENS_CORE_URI: 'https://auth-core.internal',
|
|
COOKIE_SECURE: 'true',
|
|
PADDLE_WEBHOOK_SECRET: 'secret',
|
|
PADDLE_PRICE_PLAN_MAP: '{"pri_operator":"operator"}',
|
|
},
|
|
liveHealth: null,
|
|
})
|
|
|
|
expect(report.warnings).toContain('SERVE_STATIC_WEBSITE is not explicitly set; confirm ../dist is present for first-party same-origin serving or that an external same-origin web server serves the frontend.')
|
|
})
|
|
|
|
it('fails localhost-grade posture and missing public-launch configuration', () => {
|
|
const report = buildRuntimeReadinessReport({
|
|
frontendEnv: {
|
|
VITE_SUPERTOKENS_API_DOMAIN: 'http://localhost:3001',
|
|
VITE_SUPERTOKENS_WEBSITE_DOMAIN: 'http://localhost:4273',
|
|
VITE_AUTH_API_BASE_URL: 'http://localhost:3001',
|
|
},
|
|
serverEnv: {
|
|
API_DOMAIN: 'http://localhost:3001',
|
|
WEBSITE_DOMAIN: 'http://localhost:4273',
|
|
SUPERTOKENS_CORE_URI: 'http://localhost:3567',
|
|
COOKIE_SECURE: 'false',
|
|
},
|
|
liveHealth: null,
|
|
})
|
|
|
|
expect(report.ok).toBe(false)
|
|
expect(report.failures).toContain('VITE_SUPERTOKENS_API_DOMAIN still targets a loopback/local-development origin.')
|
|
expect(report.failures).toContain('COOKIE_SECURE must be true before public launch.')
|
|
expect(report.failures).toContain('PADDLE_WEBHOOK_SECRET is missing.')
|
|
})
|
|
|
|
it('fails placeholder values even when production-shaped env files are otherwise populated', () => {
|
|
const report = buildRuntimeReadinessReport({
|
|
frontendEnv: {
|
|
VITE_SUPERTOKENS_API_DOMAIN: 'https://hypertwist.app',
|
|
VITE_SUPERTOKENS_WEBSITE_DOMAIN: 'https://hypertwist.app',
|
|
VITE_AUTH_API_BASE_URL: 'https://hypertwist.app',
|
|
VITE_WINDOWS_DOWNLOAD_URL: 'https://downloads.hypertwist.app/replace-me/windows.exe',
|
|
VITE_PADDLE_CHECKOUT_URL_OPERATOR: 'https://buy.paddle.com/replace-me-operator',
|
|
VITE_PADDLE_CHECKOUT_URL_STUDIO: 'https://buy.paddle.com/replace-me-studio',
|
|
VITE_MPL_SOURCE_URL: 'https://hypertwist.app/open-source/replace-me',
|
|
VITE_OPEN_SOURCE_REPO_URL: 'https://git.scriptoriumai.io/scriptoriumadmin/hypertwist',
|
|
},
|
|
serverEnv: {
|
|
API_DOMAIN: 'https://hypertwist.app',
|
|
WEBSITE_DOMAIN: 'https://hypertwist.app',
|
|
SUPERTOKENS_CORE_URI: 'http://127.0.0.1:3567',
|
|
COOKIE_SECURE: 'true',
|
|
PADDLE_WEBHOOK_SECRET: 'replace-me-paddle-webhook-secret',
|
|
PADDLE_PRICE_PLAN_MAP: '{"replace_me_price_operator":"operator"}',
|
|
},
|
|
liveHealth: null,
|
|
})
|
|
|
|
expect(report.ok).toBe(false)
|
|
expect(report.failures).toContain('VITE_WINDOWS_DOWNLOAD_URL still contains a placeholder value.')
|
|
expect(report.failures).toContain('VITE_PADDLE_CHECKOUT_URL_OPERATOR still contains a placeholder value.')
|
|
expect(report.failures).toContain('PADDLE_WEBHOOK_SECRET still contains a placeholder value.')
|
|
expect(report.failures).toContain('PADDLE_PRICE_PLAN_MAP still contains a placeholder value.')
|
|
})
|
|
})
|
|
|
|
describe('deriveHealthBaseUrl', () => {
|
|
it('prefers the explicit health URL over env-derived defaults', () => {
|
|
const baseUrl = deriveHealthBaseUrl({
|
|
explicitHealthUrl: 'https://hypertwist.app/',
|
|
frontendEnv: {
|
|
VITE_AUTH_API_BASE_URL: 'https://auth.hypertwist.app',
|
|
},
|
|
serverEnv: {
|
|
API_DOMAIN: 'https://server.hypertwist.app',
|
|
},
|
|
})
|
|
|
|
expect(baseUrl).toBe('https://hypertwist.app')
|
|
})
|
|
})
|