Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
76 lines
3.2 KiB
JavaScript
76 lines
3.2 KiB
JavaScript
'use strict';
|
|
const test = require('node:test');
|
|
const assert = require('node:assert');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
|
|
let JSDOM = null;
|
|
try { ({ JSDOM } = require('jsdom')); } catch (e) { /* jsdom fehlt -> skip */ }
|
|
const SRC = fs.readFileSync(path.join(__dirname, '../../app/static/doppelzaehlung.js'), 'utf8');
|
|
|
|
const HTML = `
|
|
<form id="f" hx-post="/api/recurring"><input name="name" value="Rate Auto"></form>
|
|
<dialog id="doppelzaehlung-dialog">
|
|
<p class="dz-meldung"></p><ul class="dz-konflikte"></ul>
|
|
<button type="button" id="dz-abbrechen">Abbrechen</button>
|
|
<button type="button" id="dz-bestaetigen">Trotzdem speichern</button>
|
|
</dialog>`;
|
|
const BODY = JSON.stringify({ detail: { code: 'doppelzaehlung_kredit', meldung: 'Erklärung',
|
|
konflikte: [{ posten: 'Rate Auto', posten_betrag: '-100.00', kredit: 'Auto', kredit_rate: '100.00' }] } });
|
|
|
|
function load() {
|
|
const dom = new JSDOM(`<!doctype html><body>${HTML}</body>`, { runScripts: 'outside-only' });
|
|
const w = dom.window;
|
|
const calls = [];
|
|
w.htmx = { trigger: (el, name) => calls.push([el.id, name]) };
|
|
const dlg = w.document.getElementById('doppelzaehlung-dialog');
|
|
dlg.showModal = function () { this.setAttribute('open', ''); };
|
|
dlg.close = function () { this.removeAttribute('open'); };
|
|
w.eval(SRC);
|
|
w.FBDoppel.init(w.document);
|
|
const form = w.document.getElementById('f');
|
|
const evt = { detail: { xhr: { status: 409, responseText: BODY }, elt: form } };
|
|
return { w, dlg, form, evt, calls };
|
|
}
|
|
|
|
test('409 öffnet Dialog mit Erklärung und Konfliktliste', { skip: !JSDOM }, () => {
|
|
const { w, dlg, evt } = load();
|
|
assert.equal(w.FBDoppel.handle(evt), true);
|
|
assert.ok(dlg.hasAttribute('open'));
|
|
assert.equal(dlg.querySelector('.dz-meldung').textContent, 'Erklärung');
|
|
assert.equal(dlg.querySelectorAll('.dz-konflikte li').length, 1);
|
|
});
|
|
|
|
test('andere Fehler werden nicht abgefangen', { skip: !JSDOM }, () => {
|
|
const { w, form } = load();
|
|
assert.equal(w.FBDoppel.handle({ detail: { xhr: { status: 422, responseText: '{}' }, elt: form } }), false);
|
|
});
|
|
|
|
test('Abbrechen speichert nicht', { skip: !JSDOM }, () => {
|
|
const { w, dlg, form, evt, calls } = load();
|
|
w.FBDoppel.handle(evt);
|
|
w.document.getElementById('dz-abbrechen').click();
|
|
assert.ok(!dlg.hasAttribute('open'));
|
|
assert.equal(calls.length, 0);
|
|
assert.ok(!form.hasAttribute('data-doppelzaehlung-bestaetigt'));
|
|
assert.equal(form.querySelector('input').value, 'Rate Auto');
|
|
});
|
|
|
|
test('Trotzdem speichern sendet erneut mit Flag', { skip: !JSDOM }, () => {
|
|
const { w, dlg, form, evt, calls } = load();
|
|
w.FBDoppel.handle(evt);
|
|
w.document.getElementById('dz-bestaetigen').click();
|
|
assert.ok(!dlg.hasAttribute('open'));
|
|
assert.equal(form.getAttribute('data-doppelzaehlung-bestaetigt'), '1');
|
|
assert.deepEqual(calls, [['f', 'submit']]);
|
|
});
|
|
|
|
test('Flag nach Request entfernt', { skip: !JSDOM }, () => {
|
|
const { w, form, evt } = load();
|
|
w.FBDoppel.handle(evt);
|
|
w.document.getElementById('dz-bestaetigen').click();
|
|
const e = new w.CustomEvent('htmx:afterRequest', { bubbles: true, detail: { elt: form } });
|
|
form.dispatchEvent(e);
|
|
assert.ok(!form.hasAttribute('data-doppelzaehlung-bestaetigt'));
|
|
});
|