세션·로그인 제한, ZIP/업로드 스트리밍, CSP 최소 강제와 Report-Only, Playwright 격리 검증을 추가하고 미디어 목록을 reconcile 후 database 모드로 고정한다. Co-authored-by: Cursor <cursoragent@cursor.com>
91 lines
2.6 KiB
JavaScript
91 lines
2.6 KiB
JavaScript
import { mkdirSync, rmSync } from 'node:fs'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { spawnSync } from 'node:child_process'
|
|
|
|
const rootDir = process.cwd()
|
|
const composeProjectName = 'sori-studio-playwright'
|
|
const databaseName = 'sori_studio_test'
|
|
const databasePort = process.env.TEST_DB_PORT || '43091'
|
|
const uploadRoot = join(tmpdir(), 'sori-studio-playwright-uploads')
|
|
|
|
if (!databaseName.endsWith('_test')) {
|
|
throw new Error(`테스트 DB 이름은 _test로 끝나야 합니다: ${databaseName}`)
|
|
}
|
|
|
|
export const playwrightTestEnv = {
|
|
...process.env,
|
|
PLAYWRIGHT_TEST: '1',
|
|
DATABASE_URL: `postgres://sori_studio_test:sori_studio_test_password@127.0.0.1:${databasePort}/${databaseName}`,
|
|
DATABASE_NAME: databaseName,
|
|
POSTGRES_DB: databaseName,
|
|
POSTGRES_USER: 'sori_studio_test',
|
|
POSTGRES_PASSWORD: 'sori_studio_test_password',
|
|
ADMIN_EMAIL: 'playwright-admin@example.com',
|
|
ADMIN_PASSWORD: 'playwright-admin-password',
|
|
MEMBER_SESSION_SECRET: 'playwright-member-session-secret',
|
|
ANALYTICS_HASH_SECRET: 'playwright-analytics-secret',
|
|
NUXT_PUBLIC_SITE_URL: 'http://127.0.0.1:43100',
|
|
NUXT_POST_EXPORT_WORKER: '0',
|
|
NUXT_RECOMMENDED_FAVICON_CRON: '0',
|
|
MEDIA_CATALOG_MODE: 'database',
|
|
SORI_TEST_UPLOAD_ROOT: uploadRoot,
|
|
TEST_DB_PORT: databasePort
|
|
}
|
|
|
|
const composeArgs = [
|
|
'compose',
|
|
'--project-name',
|
|
composeProjectName,
|
|
'-f',
|
|
'docker-compose.test.yml'
|
|
]
|
|
|
|
/**
|
|
* 명령을 실행하고 실패 시 즉시 중단한다.
|
|
* @param {string} command - 실행 파일
|
|
* @param {string[]} args - 실행 인자
|
|
* @returns {void}
|
|
*/
|
|
const run = (command, args) => {
|
|
const result = spawnSync(command, args, {
|
|
cwd: rootDir,
|
|
env: playwrightTestEnv,
|
|
stdio: 'inherit'
|
|
})
|
|
|
|
if (result.status !== 0) {
|
|
throw new Error(`${command} 실행 실패 (${result.status || 1})`)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Playwright 전용 DB와 업로드 디렉터리를 새로 준비한다.
|
|
* @returns {void}
|
|
*/
|
|
export const setupPlaywrightTestEnvironment = () => {
|
|
teardownPlaywrightTestEnvironment()
|
|
rmSync(uploadRoot, { recursive: true, force: true })
|
|
mkdirSync(uploadRoot, { recursive: true })
|
|
|
|
try {
|
|
run('docker', [...composeArgs, 'up', '-d', '--wait'])
|
|
} catch (error) {
|
|
teardownPlaywrightTestEnvironment()
|
|
throw error
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Playwright 전용 자원만 정리한다.
|
|
* @returns {void}
|
|
*/
|
|
export const teardownPlaywrightTestEnvironment = () => {
|
|
spawnSync('docker', [...composeArgs, 'down', '--volumes'], {
|
|
cwd: rootDir,
|
|
env: playwrightTestEnv,
|
|
stdio: 'inherit'
|
|
})
|
|
rmSync(uploadRoot, { recursive: true, force: true })
|
|
}
|