Files
AtreidesAssetsFree/tests/ui/label-combobox.test.mjs
2026-10-29 11:57:29 +01:00

181 lines
6.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Generated, do not edit. sha256:18ea78362b2006de67f8de24f1ba22509bacedd2360fbc539ff44c9c147a971f
import { describe, it, mock } from 'node:test';
import assert from 'node:assert/strict';
let gemeld = [];
mock.module('../../client/ui/dialog.js', { namedExports: { alert: (o) => { gemeld.push(o); } } });
const { labelComboMarkup, labelComboMount, labelComboRead } =
await import('../../client/ui/label-combobox.js');
function maakHost() {
const hidden = { value: '' };
const input = { value: '', gefocust: 0, focus() { this.gefocust++; } };
const datalist = { innerHTML: '' };
const addBtn = {};
const delBtn = { disabled: false };
const map = {
'[data-label-id]': hidden,
'[data-label-input]': input,
datalist,
'[data-label-add]': addBtn,
'[data-label-del]': delBtn,
};
return { querySelector: (sel) => map[sel] ?? null, hidden, input, datalist, addBtn, delBtn };
}
function maakApi(labels = [{ id: 1, name: 'Salaris' }, { id: 2, name: 'Spaargeld' }]) {
const rijen = [...labels];
let volgend = Math.max(0, ...rijen.map(l => l.id)) + 1;
return {
lijst: rijen,
aanroepen: { list: 0, create: 0 },
async listLabels() { this.aanroepen.list++; return [...rijen]; },
async createLabel({ name }) {
this.aanroepen.create++;
const id = volgend++;
rijen.push({ id, name });
return id;
},
};
}
describe('labelComboMarkup', () => {
it('levert de twee knoppen en het verborgen id-veld', () => {
const html = labelComboMarkup('labelId', 7);
assert.match(html, /data-label-add/);
assert.match(html, /data-label-del/);
assert.match(html, /data-label-id value="7"/);
});
it('escapet de veldnaam en laat een leeg id leeg', () => {
assert.match(labelComboMarkup('a"b', null), /data-field="a"b"/);
assert.match(labelComboMarkup('labelId', null), /data-label-id value=""/);
});
});
describe('labelComboRead', () => {
it('geeft null bij leeg en een getal bij een gekozen label', () => {
const host = maakHost();
host.hidden.value = '';
assert.equal(labelComboRead(host), null);
host.hidden.value = '3';
assert.equal(labelComboRead(host), 3);
assert.equal(labelComboRead(null), null);
});
});
describe('labelComboMount met een ASYNCHRONE labelApi', () => {
it('vult de datalist en zet het huidige label in het veld', async () => {
const host = maakHost();
const api = maakApi();
host.hidden.value = '2';
await labelComboMount(host, api, () => {});
assert.match(host.datalist.innerHTML, /Salaris/);
assert.match(host.datalist.innerHTML, /Spaargeld/);
assert.equal(host.input.value, 'Spaargeld', 'het gekoppelde label hoort in het veld te staan');
assert.equal(host.delBtn.disabled, false, 'ontkoppelen kan, want er hángt een label aan');
});
it('zet de ontkoppel-knop uit als er geen label hangt', async () => {
const host = maakHost();
await labelComboMount(host, maakApi(), () => {});
assert.equal(host.input.value, '');
assert.equal(host.delBtn.disabled, true);
});
it('koppelt met + een BESTAAND label zonder er een nieuw bij te maken', async () => {
const host = maakHost();
const api = maakApi();
const gekozen = [];
await labelComboMount(host, api, id => gekozen.push(id));
host.input.value = ' salaris ';
await host.addBtn.onclick();
assert.deepEqual(gekozen, [1], 'de naam hoort op te lossen naar het bestaande label');
assert.equal(api.aanroepen.create, 0, 'geen tweede label met dezelfde naam');
assert.equal(host.hidden.value, 1);
});
it('maakt met + een NIEUW label en verwerkt het meteen in de lijst', async () => {
const host = maakHost();
const api = maakApi();
const gekozen = [];
await labelComboMount(host, api, id => gekozen.push(id));
host.input.value = 'Vakantiegeld';
await host.addBtn.onclick();
assert.equal(api.aanroepen.create, 1);
assert.deepEqual(gekozen, [3]);
assert.equal(host.input.value, 'Vakantiegeld');
assert.match(host.datalist.innerHTML, /Vakantiegeld/);
});
it('doet met + bij een leeg veld niets dan focussen', async () => {
const host = maakHost();
const api = maakApi();
const gekozen = [];
await labelComboMount(host, api, id => gekozen.push(id));
host.input.value = ' ';
await host.addBtn.onclick();
assert.equal(api.aanroepen.create, 0);
assert.deepEqual(gekozen, []);
assert.equal(host.input.gefocust, 1);
});
it('meldt een fout van createLabel en koppelt dan niets', async () => {
gemeld = [];
const host = maakHost();
const api = maakApi();
api.createLabel = async () => { throw new Error('naam bestaat al'); };
const gekozen = [];
await labelComboMount(host, api, id => gekozen.push(id));
host.input.value = 'Nieuw';
await host.addBtn.onclick();
assert.equal(gemeld.length, 1);
assert.match(gemeld[0].message, /naam bestaat al/);
assert.deepEqual(gekozen, [], 'een mislukte aanmaak mag geen koppeling doorgeven');
});
it('ontkoppelt met − zonder het label zelf te raken', async () => {
const host = maakHost();
const api = maakApi();
host.hidden.value = '1';
const gekozen = [];
await labelComboMount(host, api, id => gekozen.push(id));
host.delBtn.onclick();
assert.deepEqual(gekozen, [null]);
assert.equal(host.hidden.value, '');
assert.equal(api.lijst.length, 2, 'het label blijft bestaan');
});
it('koppelt bij het typen van een bestaande naam, en wacht bij een nieuwe op +', async () => {
const host = maakHost();
const gekozen = [];
await labelComboMount(host, maakApi(), id => gekozen.push(id));
host.input.value = 'Spaargeld';
host.input.onchange();
assert.deepEqual(gekozen, [2]);
host.input.value = 'Bestaat nog niet';
host.input.onchange();
assert.deepEqual(gekozen, [2], 'een onbekende naam koppelt niets tot je op + drukt');
assert.equal(host.hidden.value, '');
assert.equal(host.delBtn.disabled, true);
host.input.value = '';
host.input.onchange();
assert.deepEqual(gekozen, [2, null], 'het veld leegmaken ontkoppelt');
});
});