import test from 'node:test' import assert from 'node:assert/strict' import { loadModule } from './load.mjs' const m = await loadModule('src/lib/ticketListUrl.js') const { LIST_TABS, LIST_DEFAULTS, parseListParams: parse, serializeListParams: ser, withFilter, nextLimit, listFilters, countFilters, woidRedirectTarget } = m const { TYPE_FILTERS } = await loadModule('src/lib/ticketStatus.js') test('Reiter und Art-Auswahl nach Spec', () => { assert.deepEqual(LIST_TABS.map((t) => [t.id, t.label]), [['aktiv', 'Aktiv'], ['open', 'Offen'], ['working', 'In Arbeit'], ['waiting', 'Wartet auf Kunde'], ['review', 'Prüfung'], ['done', 'Erledigt'], ['cancelled', 'Storniert'], ['alle', 'Alle']]) assert.deepEqual(TYPE_FILTERS.map((f) => f.label), ['Alle Arten', 'Aufträge (ohne Akquise)', 'Webpage', 'Migration', 'Projekt', 'Akquise']) }) test('parse: Standard, gültige und ungültige Werte', () => { assert.deepEqual(parse(''), LIST_DEFAULTS) assert.deepEqual(parse('?status=done&art=all&dringend=1&q=%20Müller%20&limit=30'), { tab: 'done', typeId: 'all', urgentOnly: true, search: 'Müller', limit: 30 }) assert.deepEqual(parse('status=foo&art=bar&dringend=ja&limit=abc'), LIST_DEFAULTS) for (const [raw, want] of [['5', 10], ['0', 10], ['25', 25], ['500', 500], ['9999', 500], ['-3', 10], ['1e3', 10], ['', 10]]) assert.equal(parse('limit=' + raw).limit, want, raw) }) test('serialize: Standardwerte werden nicht geschrieben, Rundlauf', () => { assert.equal(ser(LIST_DEFAULTS).toString(), '') assert.equal(ser({ ...LIST_DEFAULTS, tab: 'alle', limit: 20 }).toString(), 'status=alle&limit=20') assert.equal(ser({ ...LIST_DEFAULTS, urgentOnly: true, search: 'a b' }).toString(), 'dringend=1&q=a+b') for (const s of [LIST_DEFAULTS, { tab: 'done', typeId: 'Akquise', urgentOnly: true, search: 'x y', limit: 40 }]) assert.deepEqual(parse(ser(s)), s) }) test('Filteränderung setzt limit zurück, Mehr laden +10 bis 500', () => { for (const patch of [{ tab: 'done' }, { typeId: 'all' }, { urgentOnly: true }, { search: 'x' }]) assert.equal(withFilter({ ...LIST_DEFAULTS, limit: 50 }, patch).limit, 10) assert.deepEqual([10, 495, 500].map((limit) => nextLimit({ limit })), [20, 500, 500]) }) test('listFilters und countFilters', () => { assert.deepEqual(listFilters(LIST_DEFAULTS), { status: ['Open', 'Occupied', 'Assigned', 'Added Info', 'In Kontakt', 'Awaiting', 'Halted', 'In Test'], type: [], excludeType: undefined, priority: [], search: undefined, limit: 10 }) assert.deepEqual(listFilters({ ...LIST_DEFAULTS, tab: 'alle', typeId: 'Akquise', urgentOnly: true, search: 'abc' }), { status: [], type: ['Akquise'], excludeType: undefined, priority: [3, 4], search: 'abc', limit: 10 }) assert.deepEqual(listFilters({ ...LIST_DEFAULTS, tab: 'done' }).status, ['Closed', 'Zugesagt']) const s = { ...LIST_DEFAULTS, typeId: 'Webpage', urgentOnly: true, search: 'zzz', limit: 80 } assert.deepEqual(countFilters(s, 'review'), { status: ['In Test'], type: ['Webpage'], excludeType: undefined, priority: [3, 4] }) for (const t of LIST_TABS) assert.deepEqual(countFilters(s, t.id).status, listFilters({ ...s, tab: t.id }).status, t.id) }) test('Standardansicht zeigt alle Arten, auch Akquise', () => { assert.equal(LIST_DEFAULTS.typeId, 'all') assert.equal(parse('').typeId, 'all') assert.equal(ser({ ...LIST_DEFAULTS }).get('art'), null) assert.equal(parse(ser({ ...LIST_DEFAULTS, typeId: 'orders' })).typeId, 'orders') assert.deepEqual(listFilters({ ...LIST_DEFAULTS, typeId: 'orders' }).excludeType, 'Akquise') }) test('woid-Umleitung hat Vorrang', () => { assert.equal(woidRedirectTarget('?woid=100131'), '/tickets/100131') assert.equal(woidRedirectTarget('?woid=%20100131%20&status=done&q=x'), '/tickets/100131') assert.equal(woidRedirectTarget('?woid=a%2Fb'), '/tickets/a%2Fb') for (const none of ['', '?woid=', '?status=done']) assert.equal(woidRedirectTarget(none), null) })