import { test } from 'node:test' import assert from 'node:assert/strict' // Vor dem Import von config.js setzen (jede Testdatei laeuft in einem eigenen Prozess) process.env.ABO_TEST_EMAILS = 'test@example.invalid' const { chargesFrom, redeemedDiscount } = await import('../server/services/offerDiscount.js') const { adminOfferView } = await import('../server/services/offers.js') test('Abbuchungen: vom Anker aus, Monatsende wie bei Stripe', () => { assert.deepEqual(chargesFrom('2026-09-26T08:00:00.000Z', '2026-09-26T08:00:00.000Z', 3), [ '2026-09-26T08:00:00.000Z', '2026-10-26T08:00:00.000Z', '2026-11-26T08:00:00.000Z', ]) // 31. bleibt Anker: Februar kuerzer, danach wieder der 31. assert.deepEqual(chargesFrom('2026-01-31T10:00:00.000Z', '2026-01-31T10:00:00.000Z', 4), [ '2026-01-31T10:00:00.000Z', '2026-02-28T10:00:00.000Z', '2026-03-31T10:00:00.000Z', '2026-04-30T10:00:00.000Z', ]) // Ab einem Zeitpunkt mitten im Abrechnungsmonat: naechste Abbuchung assert.deepEqual(chargesFrom('2026-01-15T10:00:00.000Z', '2026-03-20T12:00:00.000Z', 2), [ '2026-04-15T10:00:00.000Z', '2026-05-15T10:00:00.000Z', ]) assert.deepEqual(chargesFrom(null, '2026-03-20T12:00:00.000Z', 2), []) }) test('Angebot beim Abschluss, Leistung sofort: Abbuchungen 1..N rabattiert', () => { const sub = { startedAt: '2026-09-26T08:00:00.000Z', trialEnd: null } const d = redeemedDiscount({ months: 2, appliedAt: '2026-09-26T08:00:05.000Z', attachedLater: false }, sub) assert.deepEqual(d, { known: true, firstChargeAt: '2026-09-26T08:00:00.000Z', endsAt: '2026-11-26T08:00:00.000Z', subscriptionEndsAt: null }) }) test('Angebot beim Abschluss, Beginn nach Widerrufsfrist: Rabatt ab Leistungsbeginn', () => { const sub = { startedAt: '2026-09-26T08:00:00.000Z', trialEnd: '2026-10-13T04:00:00.000Z' } const d = redeemedDiscount({ months: 2, appliedAt: '2026-09-26T08:00:05.000Z', attachedLater: false }, sub) assert.equal(d.firstChargeAt, '2026-10-13T04:00:00.000Z') assert.equal(d.endsAt, '2026-12-13T04:00:00.000Z') }) test('Testkonto (Coupon nach der ersten Abbuchung): Abbuchungen 2..N+1', () => { const sub = { startedAt: '2026-09-26T08:00:00.000Z', trialEnd: null } const d = redeemedDiscount({ months: 2, appliedAt: '2026-09-26T08:00:05.000Z', attachedLater: true }, sub) assert.equal(d.firstChargeAt, '2026-10-26T08:00:00.000Z') assert.equal(d.endsAt, '2026-12-26T08:00:00.000Z') }) test('Laufendes Abo: ab der naechsten Abbuchung nach dem Anhaengen', () => { const sub = { startedAt: '2026-03-14T09:00:00.000Z', trialEnd: null } const d = redeemedDiscount({ months: 2, appliedAt: '2026-09-26T20:00:00.000Z', attachedLater: true }, sub) assert.equal(d.firstChargeAt, '2026-10-14T09:00:00.000Z') assert.equal(d.endsAt, '2026-12-14T09:00:00.000Z') }) test('Abo endet vor dem Rabatt: Abo-Ende wird gemeldet, sonst nicht', () => { const base = { startedAt: '2026-09-26T08:00:00.000Z', trialEnd: null } const offer = { months: 3, appliedAt: '2026-09-26T08:00:05.000Z', attachedLater: false } assert.equal(redeemedDiscount(offer, { ...base, cancelAt: '2026-10-26T08:00:00.000Z' }).subscriptionEndsAt, '2026-10-26T08:00:00.000Z') assert.equal(redeemedDiscount(offer, { ...base, endedAt: '2026-10-01T08:00:00.000Z' }).subscriptionEndsAt, '2026-10-01T08:00:00.000Z') assert.equal(redeemedDiscount(offer, { ...base, cancelAt: '2027-09-26T08:00:00.000Z' }).subscriptionEndsAt, null) }) test('Ohne Abo-Dokument ist das Rabattende unbekannt', () => { assert.deepEqual(redeemedDiscount({ months: 2, appliedAt: '2026-09-26T08:00:05.000Z', attachedLater: false }, null), { known: false }) assert.deepEqual(redeemedDiscount({ months: 2, appliedAt: null, attachedLater: true }, { startedAt: '2026-09-26T08:00:00.000Z' }), { known: false }) }) test('Admin-Ansicht: Rabatt nur bei eingeloesten Angeboten, Testkonto erkannt', () => { const doc = { $id: 'offer-1', $createdAt: '2026-09-26T07:00:00.000Z', status: 'aktiv', scope: 'neu', months: 2, monthlyPriceCents: 2500, regularPriceCents: 5000, validUntil: '2026-10-27T00:00:00.000Z', appliedAt: '2026-09-26T08:00:05.000Z', stripeSubscriptionId: 'sub_1', customerId: 'c1', } const sub = { $id: 'sub_1', startedAt: '2026-09-26T08:00:00.000Z', trialEnd: null } const normal = adminOfferView(doc, { name: 'Kunde', email: 'kunde@example.invalid' }, sub) assert.equal(normal.testAccount, false) assert.equal(normal.discount.endsAt, '2026-11-26T08:00:00.000Z') const testView = adminOfferView(doc, { name: 'Test', email: 'TEST@example.invalid' }, sub) assert.equal(testView.testAccount, true) assert.equal(testView.discount.endsAt, '2026-12-26T08:00:00.000Z') const running = adminOfferView({ ...doc, scope: 'laufend', appliedAt: '2026-10-01T12:00:00.000Z' }, { email: 'kunde@example.invalid' }, sub) assert.equal(running.discount.firstChargeAt, '2026-10-26T08:00:00.000Z') assert.equal(adminOfferView({ ...doc, status: 'offen', appliedAt: null }, { email: 'kunde@example.invalid' }, null).discount, null) assert.deepEqual(adminOfferView(doc, { email: 'kunde@example.invalid' }, undefined).discount, { known: false }) })