// 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')