import { test } from 'node:test' import assert from 'node:assert/strict' import { ANALYSE_ATTRIBUTES, CONSENT_ATTRIBUTES, CONSENT_INDEXES, main } from '../scripts/analyse-setup.mjs' import { config } from '../server/config.js' function mockClient({ attrs = [], consentsExist = false, consentAttrs = [], indexes = [] } = {}) { const calls = { attrs: [], collections: [], indexes: [] } return { calls, async collectionExists() { return consentsExist }, async ensureCollection(id, name) { calls.collections.push({ id, name }) return true }, async listAttributes(id) { return (id === config.collections.portalFeatures ? attrs : consentAttrs).map((key) => ({ key })) }, async createAttribute(id, attr) { calls.attrs.push(`${id}.${attr.key}`) }, async waitForAttribute() {}, async listIndexes() { return indexes.map((key) => ({ key })) }, async createIndex(id, index) { calls.indexes.push(`${id}.${index.key}`) }, } } test('Schema: 14 Attribute mit Groessen, alle optional', () => { const sizes = Object.fromEntries(ANALYSE_ATTRIBUTES.filter((a) => a.type === 'string').map((a) => [a.key, a.size])) assert.deepEqual(sizes, { accentColor: 7, avvVersion: 20, avvAcceptedAt: 40, avvAcceptedBy: 100, activatedAt: 40, offSince: 40, privacyTicketId: 40, activatedMailAt: 40, avvConsentDate: 10, avvConsentChannel: 10, removalTicketId: 40, publishTicketId: 40, audienceTextVersion: 20, }) assert.equal(ANALYSE_ATTRIBUTES.length, 14) assert.equal(ANALYSE_ATTRIBUTES.find((a) => a.key === 'audienceConfirmed').type, 'boolean') assert.ok(ANALYSE_ATTRIBUTES.every((a) => a.required === false)) }) test('Schema: Historien-Collection analyseConsents', () => { assert.equal(config.collections.analyseConsents, 'analyseConsents') const sizes = Object.fromEntries(CONSENT_ATTRIBUTES.filter((a) => a.type === 'string').map((a) => [a.key, a.size])) assert.deepEqual(sizes, { customerId: 36, projectId: 36, siteKey: 40, event: 8, avvVersion: 20, via: 8, acceptedAt: 40, acceptedBy: 100, textformDate: 10, textformChannel: 10, audienceTextVersion: 20, }) assert.equal(CONSENT_ATTRIBUTES.find((a) => a.key === 'audienceConfirmed').type, 'boolean') assert.deepEqual(CONSENT_INDEXES.map((i) => i.attributes), [['projectId']]) }) test('main legt nur fehlende Attribute an und die fehlende Collection samt Index', async () => { const client = mockClient({ attrs: ['accentColor'] }) const result = await main({ client, log: () => {} }) assert.equal(client.calls.attrs.filter((k) => k.startsWith('portalFeatures.')).length, 13) assert.ok(!client.calls.attrs.includes('portalFeatures.accentColor')) assert.equal(client.calls.attrs.filter((k) => k.startsWith('analyseConsents.')).length, 12) assert.deepEqual(client.calls.collections, [{ id: 'analyseConsents', name: 'analyseConsents' }]) assert.deepEqual(client.calls.indexes, ['analyseConsents.projectId_idx']) assert.equal(result.missing.length, 25) }) test('main ueberspringt vorhandene Collection, Attribute und Index', async () => { const client = mockClient({ attrs: ANALYSE_ATTRIBUTES.map((a) => a.key), consentsExist: true, consentAttrs: CONSENT_ATTRIBUTES.map((a) => a.key), indexes: ['projectId_idx'], }) const result = await main({ client, log: () => {} }) assert.deepEqual(client.calls, { attrs: [], collections: [], indexes: [] }) assert.equal(result.missing.length, 0) }) test('main --check legt nichts an und meldet missing', async () => { const client = mockClient({ attrs: ['accentColor'] }) const result = await main({ check: true, client, log: () => {} }) assert.deepEqual(client.calls, { attrs: [], collections: [], indexes: [] }) assert.equal(result.missing.length, 25) assert.equal(result.missingCollection, true) }) test('Konfiguration: analyse ist standardmaessig aus', () => { assert.equal(config.analyse.enabled, false) assert.equal(config.analyse.url, 'http://webklar-analytics:8091') assert.equal(config.analyse.adminToken, '') assert.equal(config.analyse.heatSecret, '') assert.equal(config.analyse.avvVersion, '2026-10-02') })