62 lines
3.3 KiB
JavaScript
62 lines
3.3 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { mkdtemp, mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
import os from 'node:os'
|
|
import path from 'node:path'
|
|
import test from 'node:test'
|
|
import { readDevelopmentRuntime, resolveRuntimeFile, runtimeRoot, sourceRoot } from '../../deploy/runtime-config.mjs'
|
|
import { fileDigest, sourceFingerprint } from '../../deploy/build-state.mjs'
|
|
|
|
test('开发配置只从模拟部署目录读取且不返回凭据字段', async () => {
|
|
const root = await mkdtemp(path.join(os.tmpdir(), 'smail-runtime-config-'))
|
|
await mkdir(path.join(root, 'config'))
|
|
await mkdir(path.join(root, 'ssl'))
|
|
await writeFile(path.join(root, 'config/config.json'), JSON.stringify({
|
|
generation: 9, domains: { web: 'mail.example.test' }, database: { password: 'not-exported' }
|
|
}))
|
|
await writeFile(path.join(root, 'config/ssl.json'), JSON.stringify({
|
|
tls: { certificateRef: 'ssl/public.crt', privateKeyRef: 'ssl/private.key' }
|
|
}))
|
|
await writeFile(path.join(root, 'ssl/public.crt'), 'certificate')
|
|
await writeFile(path.join(root, 'ssl/private.key'), 'key')
|
|
const runtime = readDevelopmentRuntime(root)
|
|
assert.equal(runtime.origin, 'https://mail.example.test')
|
|
assert.equal(runtime.generation, 9)
|
|
assert.equal(runtime.privateKeyPath, path.join(root, 'ssl/private.key'))
|
|
assert.equal(JSON.stringify(runtime).includes('not-exported'), false)
|
|
assert.equal(runtimeRoot, path.join(sourceRoot, 'yunx-test'))
|
|
assert.throws(() => resolveRuntimeFile(root, '../outside.key'))
|
|
assert.throws(() => resolveRuntimeFile(root, path.join(root, 'ssl/private.key')))
|
|
})
|
|
|
|
test('源码指纹检测编辑且忽略编译嵌入目录', async () => {
|
|
const root = await mkdtemp(path.join(os.tmpdir(), 'smail-build-state-'))
|
|
for (const name of ['backend', 'frontend', 'plugins/pmail_telegram_push', 'deploy']) {
|
|
await mkdir(path.join(root, name), { recursive: true })
|
|
}
|
|
await writeFile(path.join(root, 'backend/main.go'), 'package main')
|
|
const before = await sourceFingerprint(root)
|
|
await mkdir(path.join(root, 'backend/dist'))
|
|
await writeFile(path.join(root, 'backend/dist/index.html'), 'generated')
|
|
assert.equal(await sourceFingerprint(root), before)
|
|
await writeFile(path.join(root, 'backend/main.go'), 'package main\n')
|
|
assert.notEqual(await sourceFingerprint(root), before)
|
|
assert.equal((await fileDigest(path.join(root, 'backend/main.go'))).length, 64)
|
|
await writeFile(path.join(root, 'empty.exe'), '')
|
|
await assert.rejects(fileDigest(path.join(root, 'empty.exe')))
|
|
})
|
|
|
|
test('部署和启动必须完整构建、验证产物且不覆盖运行配置', async () => {
|
|
const read = name => readFile(path.join(sourceRoot, name), 'utf8')
|
|
const deploy = await read('deploy/deploy-runtime.ps1')
|
|
const start = await read('deploy/start-dev.ps1')
|
|
assert.ok(deploy.indexOf("'build.ps1'") < deploy.indexOf('Copy-Item'))
|
|
assert.match(deploy, /verify --deployed/)
|
|
assert.match(deploy, /deployment-history/)
|
|
assert.doesNotMatch(deploy, /Copy-Item[^\n]*(config|data|ssl)/)
|
|
assert.doesNotMatch(start, /SkipBuild|SkipFrontend/)
|
|
assert.match(start, /\$env:SMAIL_ROOT = \$runtime/)
|
|
assert.match(start, /\$workingDirectory = \$runtime/)
|
|
assert.match(start, /build-state\.mjs'\) verify --deployed/)
|
|
assert.match(await read('.gitignore'), /^\/yunx-test\/$/m)
|
|
})
|