Files
tickte-system/tests/unit/projektkontoView.test.mjs

161 lines
7.5 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.
import test from 'node:test'
import assert from 'node:assert/strict'
import { loadModule } from './load.mjs'
const {
STRIPE_HINWEIS, KEINE_PROJEKTE_HINWEIS,
stundenDe, satzText, ticketsText, stripeHinweis, vereinbartText, kontoZeile, ohneProjektZeile,
artLabel, projektSpalte, abgerechnetText, abgerechnetWarnung, ticketIdsOf,
} = await loadModule('src/lib/projektkontoView.js')
const konto = (over = {}) => ({
projektId: 'p1',
name: 'Website Relaunch',
projektTyp: 'Website',
tickets: [{ id: 't1', woid: '100131' }],
zeitquelle: ['t1'],
vereinbart: { festpreisCents: 120000, aufwand: null },
berechnetCents: 50000,
bezahltCents: 20000,
offenCents: 70000,
zeit: { minuten: 750, aboMinuten: 0, offeneMinuten: 750, satzCents: 10000, wertCents: 125000, offenerWertCents: 125000 },
...over,
})
const AUFWAND = { festpreisCents: null, aufwand: { stundensatzCents: 10000, schaetzungMinuten: 600 } }
test('stundenDe: Dezimalstunden mit Komma, ohne überflüssige Nullen', () => {
assert.equal(stundenDe(750), '12,5 Std.')
assert.equal(stundenDe(135), '2,25 Std.')
assert.equal(stundenDe(60), '1 Std.')
assert.equal(stundenDe(20), '0,33 Std.')
assert.equal(stundenDe(0), '0 Std.')
assert.equal(stundenDe(null), '0 Std.')
assert.equal(stundenDe('abc'), '0 Std.')
})
test('satzText: ganze Euro ohne Cent, sonst mit Cent', () => {
assert.equal(satzText(10000), '100 €/Std.')
assert.equal(satzText(8550), '85,50 €/Std.')
assert.equal(satzText(null), '–')
})
test('ticketsText: Ticketnummern mit Raute, ohne Nummer fällt der Eintrag weg', () => {
assert.equal(ticketsText([{ id: 'a', woid: '100131' }]), '#100131')
assert.equal(ticketsText([{ id: 'a', woid: '100131' }, { id: 'b', woid: '100140' }]), '#100131, #100140')
assert.equal(ticketsText([{ id: 'a' }, null]), '')
assert.equal(ticketsText(undefined), '')
})
test('vereinbartText: Festpreis, Aufwand mit Schätzung, beides, keine AB', () => {
assert.equal(vereinbartText({ festpreisCents: 120000, aufwand: null }), '1.200,00 €')
assert.equal(vereinbartText(AUFWAND), 'nach Aufwand, 100 €/Std., Schätzung 10 Std.')
assert.equal(vereinbartText({ festpreisCents: null, aufwand: { stundensatzCents: 8550, schaetzungMinuten: null } }), 'nach Aufwand, 85,50 €/Std.')
assert.equal(vereinbartText({ festpreisCents: 120000, aufwand: { stundensatzCents: 10000, schaetzungMinuten: null } }), '1.200,00 € und nach Aufwand, 100 €/Std.')
assert.equal(vereinbartText({ festpreisCents: null, aufwand: null }), 'keine AB')
assert.equal(vereinbartText(undefined), 'keine AB')
})
test('kontoZeile: Festpreis-AB mit Berechnet, bezahlt, Noch offen und Zeit', () => {
assert.deepEqual(kontoZeile(konto()), {
key: 'p1',
projektId: 'p1',
name: 'Website Relaunch',
meta: 'Website · #100131',
vereinbart: '1.200,00 €',
berechnet: '500,00 €',
bezahlt: 'bezahlt 200,00 €',
offen: '700,00 €',
zeit: { stunden: '12,5 Std.', wert: 'Wert 1.250,00 €', abo: '' },
})
// ohne Art und ohne Ticket bleibt nur der Name
assert.equal(kontoZeile(konto({ projektTyp: '', tickets: [] })).meta, '')
})
test('kontoZeile: Aufwand-AB (Noch offen = Wert der offenen Zeit) und Abo-Zeit getrennt', () => {
const z = kontoZeile(konto({
vereinbart: AUFWAND,
offenCents: null,
zeit: { minuten: 300, aboMinuten: 90, offeneMinuten: 180, satzCents: 10000, wertCents: 50000, offenerWertCents: 30000 },
}))
assert.equal(z.vereinbart, 'nach Aufwand, 100 €/Std., Schätzung 10 Std.')
assert.equal(z.offen, '300,00 €')
assert.deepEqual(z.zeit, { stunden: '5 Std.', wert: 'Wert 500,00 €', abo: 'über Abo: 1,5 Std.' })
})
test('kontoZeile: ohne AB steht „keine AB“ und Noch offen ist „–“', () => {
const z = kontoZeile(konto({ vereinbart: { festpreisCents: null, aufwand: null }, offenCents: null }))
assert.equal(z.vereinbart, 'keine AB')
assert.equal(z.offen, '–')
})
test('kontoZeile: Stripe nicht erreichbar zeigt „–“ statt Nullen, Zeit und Vereinbartes bleiben', () => {
const z = kontoZeile(konto({ berechnetCents: 0, bezahltCents: 0, offenCents: null }), { stripeOk: false })
assert.deepEqual([z.vereinbart, z.berechnet, z.bezahlt, z.offen], ['1.200,00 €', '–', '', '–'])
assert.equal(z.zeit.wert, 'Wert 1.250,00 €')
// Aufwand: der Wert der offenen Zeit braucht kein Stripe
const a = kontoZeile(konto({ vereinbart: AUFWAND, offenCents: null }), { stripeOk: false })
assert.equal(a.offen, '1.250,00 €')
assert.equal(stripeHinweis(false), STRIPE_HINWEIS)
assert.equal(stripeHinweis(true), '')
assert.equal(stripeHinweis(undefined), '')
assert.equal(STRIPE_HINWEIS, 'Stripe ist gerade nicht erreichbar. Berechnete und bezahlte Beträge sind deshalb nicht verfügbar.')
})
test('ohneProjektZeile: Rechnungen ohne Projekt, ohne Vereinbart und Zeit', () => {
assert.deepEqual(ohneProjektZeile({ berechnetCents: 30000, bezahltCents: 10000, anzahl: 3 }), {
key: 'ohne-projekt',
projektId: '',
name: 'Ohne Projekt',
meta: '3 Rechnungen',
vereinbart: '–',
berechnet: '300,00 €',
bezahlt: 'bezahlt 100,00 €',
offen: '–',
zeit: { stunden: '–', wert: '', abo: '' },
})
assert.equal(ohneProjektZeile({ berechnetCents: 0, bezahltCents: 0, anzahl: 1 }).meta, '1 Rechnung')
assert.equal(ohneProjektZeile({ berechnetCents: 0, bezahltCents: 0, anzahl: 0 }).meta, 'keine Rechnungen')
assert.equal(ohneProjektZeile(undefined).meta, 'keine Rechnungen')
const s = ohneProjektZeile({ berechnetCents: 30000, bezahltCents: 10000, anzahl: 3 }, { stripeOk: false })
assert.deepEqual([s.berechnet, s.bezahlt], ['–', ''])
})
test('Hinweis für Kunden ohne Projekte', () => {
assert.equal(KEINE_PROJEKTE_HINWEIS, 'Dieser Kunde hat noch keine Projekte. Rechnungen entstehen ohne Projektbezug.')
})
test('artLabel: Spalte Art der Rechnungstabelle', () => {
assert.deepEqual(
['frei', 'festbetrag', 'aufwand', 'anzahlung', 'schluss', 'abo'].map((a) => artLabel(a)),
['Ohne Projekt', 'Festbetrag', 'Aufwand', 'Anzahlung', 'Schlussrechnung', 'Abo']
)
assert.equal(artLabel(undefined), '–')
assert.equal(artLabel('unbekannt'), '–')
assert.equal(artLabel('constructor'), '–')
})
test('projektSpalte: Projektname der Rechnung oder „–“', () => {
assert.equal(projektSpalte({ projektName: ' Website Relaunch ' }), 'Website Relaunch')
assert.equal(projektSpalte({ projektName: '' }), '–')
assert.equal(projektSpalte({}), '–')
assert.equal(projektSpalte(null), '–')
})
test('abgerechnetText und abgerechnetWarnung: Rechnungsnummer oder Entwurf', () => {
const map = { w1: 'WEBKLAR-0009', w2: 'Entwurf' }
assert.equal(abgerechnetText(map, 'w1'), 'abgerechnet (WEBKLAR-0009)')
assert.equal(abgerechnetText(map, 'w2'), 'abgerechnet (Entwurf)')
assert.equal(abgerechnetText(map, 'w3'), null)
assert.equal(abgerechnetText(map, 'constructor'), null)
assert.equal(abgerechnetText(null, 'w1'), null)
assert.equal(abgerechnetWarnung(map, 'w1'), 'Dieses Arbeitsblatt ist abgerechnet (WEBKLAR-0009). Eine Änderung ändert die Rechnung nicht.')
assert.equal(abgerechnetWarnung(map, 'w2'), 'Dieses Arbeitsblatt ist abgerechnet (Entwurf). Eine Änderung ändert die Rechnung nicht.')
assert.equal(abgerechnetWarnung(map, 'w3'), null)
})
test('ticketIdsOf: eindeutige Ticket-Kennungen der Arbeitsblätter, höchstens fünf', () => {
assert.deepEqual(ticketIdsOf([{ workorderId: 't1' }, { workorderId: 't1' }, { workorderId: 't2' }, {}, null]), ['t1', 't2'])
assert.deepEqual(ticketIdsOf(undefined), [])
assert.equal(ticketIdsOf(Array.from({ length: 7 }, (_, i) => ({ workorderId: `t${i}` }))).length, 5)
})