feat(KAN-32): add hierarchical acceptance criteria checklist
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import vue from '@vitejs/plugin-vue';
|
||||
import { createServer } from 'vite';
|
||||
import { createSSRApp, h } from 'vue';
|
||||
import { renderToString } from 'vue/server-renderer';
|
||||
|
||||
const server = await createServer({
|
||||
configFile: false,
|
||||
cacheDir: 'node_modules/.vite/acceptance-criteria-fixture',
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('../../resources/js', import.meta.url)),
|
||||
},
|
||||
},
|
||||
server: { middlewareMode: true, hmr: false, watch: null },
|
||||
});
|
||||
try {
|
||||
const {
|
||||
canIndentAcceptanceCriterion: canIndent,
|
||||
indentAcceptanceCriterion: indent,
|
||||
removeAcceptanceCriterion: remove,
|
||||
syncAcceptanceCriteriaDescendantCheckedState: toggle,
|
||||
normalizeAcceptanceCriteria: normalize,
|
||||
} = await server.ssrLoadModule('/resources/js/lib/acceptance-criteria.ts');
|
||||
const items = [
|
||||
{ id: 11, text: 'Parent', indent: 0, checked: false },
|
||||
{ id: 12, text: 'Child', indent: 1, checked: true },
|
||||
{ id: 13, text: 'Grandchild', indent: 2, checked: false },
|
||||
{ id: 14, text: 'Next', indent: 0, checked: false },
|
||||
];
|
||||
const original = structuredClone(items);
|
||||
assert.equal(canIndent(items, 0), false);
|
||||
assert.equal(canIndent(items, 1), false);
|
||||
assert.equal(canIndent(items, 3), true);
|
||||
assert.deepEqual(
|
||||
indent(items, 1, -1).map((item) => item.indent),
|
||||
[0, 0, 1, 0],
|
||||
);
|
||||
assert.deepEqual(indent(indent(items, 1, -1), 1, 1), items);
|
||||
assert.deepEqual(indent(items, 0, -1), items);
|
||||
assert.deepEqual(indent(items, -1, 1), items);
|
||||
assert.deepEqual(remove(items, 0), [
|
||||
{ ...items[1], indent: 0 },
|
||||
{ ...items[2], indent: 1 },
|
||||
items[3],
|
||||
]);
|
||||
assert.deepEqual(remove(items, 1), [
|
||||
items[0],
|
||||
{ ...items[2], indent: 1 },
|
||||
items[3],
|
||||
]);
|
||||
assert.deepEqual(remove(items, 99), items);
|
||||
assert.deepEqual(
|
||||
toggle(items, 0, true).map((item) => item.checked),
|
||||
[true, true, true, false],
|
||||
);
|
||||
assert.deepEqual(
|
||||
toggle(items, 1, false).map((item) => item.checked),
|
||||
[false, false, false, false],
|
||||
);
|
||||
const deep = Array.from({ length: 9 }, (_, indent) => ({
|
||||
text: 'Deep',
|
||||
checked: false,
|
||||
indent,
|
||||
}));
|
||||
assert.equal(
|
||||
canIndent([{ text: 'Before', indent: 0, checked: false }, ...deep], 1),
|
||||
false,
|
||||
);
|
||||
assert.deepEqual(
|
||||
normalize(remove(items, 0)).map((item) => item.id),
|
||||
[12, 13, 14],
|
||||
);
|
||||
assert.deepEqual(items, original, 'Editing must not mutate saved criteria');
|
||||
const { default: Checklist } = await server.ssrLoadModule(
|
||||
'/resources/js/components/tickets/AcceptanceCriteriaChecklist.vue',
|
||||
);
|
||||
const { createLocalization } = await server.ssrLoadModule(
|
||||
'/resources/js/lib/localization.ts',
|
||||
);
|
||||
const render = (props) =>
|
||||
renderToString(
|
||||
createSSRApp({ render: () => h(Checklist, props) }).use(
|
||||
createLocalization(),
|
||||
),
|
||||
);
|
||||
const editable = await render({ modelValue: items });
|
||||
assert.equal((editable.match(/<textarea/g) ?? []).length, 4);
|
||||
assert.match(editable, /Indent criterion 4/);
|
||||
assert.match(editable, /1 of 4 complete/);
|
||||
const readonly = await render({ modelValue: items, readonly: true });
|
||||
assert.doesNotMatch(readonly, /<textarea|Add criterion|Edit checklist/);
|
||||
assert.equal((readonly.match(/type="checkbox" disabled/g) ?? []).length, 4);
|
||||
assert.match(
|
||||
await render({ modelValue: [], error: 'Server validation' }),
|
||||
/Server validation/,
|
||||
);
|
||||
console.log('Acceptance criteria behavior checks passed.');
|
||||
} finally {
|
||||
await server.close();
|
||||
}
|
||||
Reference in New Issue
Block a user