Files
evening_detective_frontend/tests/conclusion.mjs
T
2026-09-07 03:24:31 +07:00

99 lines
3.5 KiB
JavaScript

// Run: node tests/conclusion.mjs
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import { runInNewContext } from 'node:vm'
import ts from 'typescript'
import { compileTemplate, parse } from 'vue/compiler-sfc'
const source = readFileSync(
new URL('../src/components/ScenariosEditorPage.vue', import.meta.url),
'utf8',
)
const { descriptor, errors: parseErrors } = parse(source)
assert.deepEqual(parseErrors, [])
const template = compileTemplate({
source: descriptor.template.content,
filename: 'ScenariosEditorPage.vue',
id: 'test',
})
assert.deepEqual(template.errors, [])
const functions = ['resetConclusion', 'removeConclusionVideo', 'updateConclusion', 'toRawFilename']
.map((name) => source.match(new RegExp(`(?:async )?function ${name}\\([^]*?\\n}`))[0])
.join('\n')
const calls = []
const errors = []
let upload = { filename: 'ending.mp4', fileType: 'video' }
let response = {}
const state = {
scenario: { value: { id: 1, story: { conclusion: { text: 'Saved', video: 'old.mp4' } } } },
conclusion: { value: { text: 'Draft', video: 'https://example.org/old.mp4' } },
conclusionFiles: { value: [] },
savingConclusion: { value: false },
uploadFile: async () => upload,
client: {
UpdateScenarioConclusion: async (request) => {
calls.push(request)
return response
},
},
message: { error: (error) => errors.push(error), success: () => {} },
}
runInNewContext(ts.transpile(functions, { target: ts.ScriptTarget.ES2022 }), state)
await state.updateConclusion()
assert.equal(calls.at(-1).conclusion.video, 'old.mp4')
assert.equal(state.scenario.value.story.conclusion.text, 'Draft')
state.conclusionFiles.value = [{ file: { name: 'ending.mp4' } }]
await state.updateConclusion()
assert.equal(calls.at(-1).conclusion.video, 'ending.mp4')
assert.equal(state.conclusionFiles.value.length, 0)
state.conclusionFiles.value = [{ file: { name: 'replacement.mp4' } }]
state.removeConclusionVideo()
assert.equal(state.conclusion.value.video, '')
assert.equal(state.conclusionFiles.value.length, 0)
assert.equal(state.scenario.value.story.conclusion.video, 'ending.mp4')
state.conclusion.value.text = 'Unsaved'
state.resetConclusion()
assert.equal(state.conclusion.value.text, 'Draft')
state.conclusionFiles.value = [{ file: { name: 'bad.png' } }]
for (const invalid of [
{ filename: '', fileType: '' },
{ filename: 'bad.png', fileType: 'image' },
]) {
upload = invalid
const count = calls.length
await state.updateConclusion()
assert.equal(calls.length, count)
assert.equal(state.conclusionFiles.value.length, 1)
assert.equal(state.savingConclusion.value, false)
}
state.conclusionFiles.value = []
state.conclusion.value.text = 'Keep draft'
response = { error: 'Denied' }
await state.updateConclusion()
assert.equal(state.conclusion.value.text, 'Keep draft')
assert.equal(state.scenario.value.story.conclusion.text, 'Draft')
assert.equal(errors.at(-1), 'Denied')
state.client.UpdateScenarioConclusion = async () => {
throw new Error('Offline')
}
await state.updateConclusion()
assert.equal(state.savingConclusion.value, false)
assert.equal(state.conclusion.value.text, 'Keep draft')
state.client.UpdateScenarioConclusion = async (request) => {
calls.push(request)
return {}
}
await state.updateConclusion(true)
assert.equal(calls.at(-1).conclusion.text, '')
assert.equal(calls.at(-1).conclusion.video, '')
assert.equal(state.conclusion.value.text, '')
console.log('Conclusion: save, upload, cancel, validation, errors and deletion passed')