Shop Review B I-1: Eingangsmail G15 bei SEPA, G09 nimmt die Bestellung ausdruecklich an
G15 "Wir haben Ihre Bestellung erhalten" geht einmal raus, sobald Stripe die Sitzung abgeschlossen, die Zahlung aber noch nicht gemeldet hat (meldeEingang, Marker mailsEingangAt, aus dem Webhook und aus pruefeOffene). G09 sagt ausdruecklich, dass der Kaufvertrag mit der Mail geschlossen ist, trennt Bestell- und Zahlungsdatum und nennt die Telefonnummer des Anbieters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1b7aa9ebe3
commit
77fb8c8f44
11 files changed
+238
-27
No files matched your search
@@ -234,6 +234,62 @@ test('schliesseAb: SEPA noch nicht bezahlt ist wirkungslos, bis async_payment_su
|
||||
assert.match(sink.sent.find((m) => m.to[0].address === 'erika@brot.example').text, /Lastschrift/)
|
||||
})
|
||||
|
||||
test('meldeEingang I-1: nur bei unbezahlter, abgeschlossener Sitzung einer offenen Bestellung - einmal G15 an die Adresse der Sitzung, Marker, kein Vertragstext', async () => {
|
||||
await aufbau()
|
||||
const b = await bestelle()
|
||||
const unbezahlt = zahle(b, { payment_status: 'unpaid', payment_method_types: ['sepa_debit'] })
|
||||
assert.deepEqual(await B.meldeEingang({ accountId: ACCOUNT, session: { ...unbezahlt, payment_status: 'paid' }, now: nach(60) }), { gesendet: false }, 'bezahlt ist Sache von schliesseAb')
|
||||
assert.deepEqual(await B.meldeEingang({ accountId: 'acct_fremd', session: unbezahlt, now: nach(60) }), { gesendet: false }, 'fremdes Konto')
|
||||
assert.deepEqual(await B.meldeEingang({ accountId: ACCOUNT, session: { ...unbezahlt, customer_details: null }, now: nach(60) }), { gesendet: false }, 'ohne Adresse')
|
||||
await warteAufVersand()
|
||||
assert.equal(sink.sent.length, 0)
|
||||
|
||||
assert.deepEqual(await B.meldeEingang({ accountId: ACCOUNT, session: unbezahlt, now: nach(60) }), { gesendet: true })
|
||||
assert.deepEqual(await B.meldeEingang({ accountId: ACCOUNT, session: unbezahlt, now: nach(120) }), { gesendet: false }, 'nur einmal')
|
||||
await warteAufVersand()
|
||||
assert.equal(sink.sent.length, 1)
|
||||
assert.equal(sink.sent[0].to[0].address, 'max@example.com')
|
||||
assert.match(sink.sent[0].subject, /^Wir haben Ihre Bestellung \S+ erhalten$/)
|
||||
assert.doesNotMatch(sink.sent[0].text, /Kaufvertrag ist damit geschlossen/)
|
||||
assert.equal(order(b.orderId).status, 'offen')
|
||||
assert.equal(JSON.parse(order(b.orderId).bestellung).mailsEingangAt, nach(60).toISOString())
|
||||
|
||||
// Später bezahlt: G09 folgt, der Marker bleibt erhalten
|
||||
await B.schliesseAb({ accountId: ACCOUNT, session: { ...unbezahlt, payment_status: 'paid' }, now: nach(3 * 86400) })
|
||||
await warteAufVersand()
|
||||
assert.equal(JSON.parse(order(b.orderId).bestellung).mailsEingangAt, nach(60).toISOString())
|
||||
assert.deepEqual(await B.meldeEingang({ accountId: ACCOUNT, session: unbezahlt, now: nach(4 * 86400) }), { gesendet: false }, 'nicht mehr offen')
|
||||
})
|
||||
|
||||
test('meldeEingang I-1: scheitert das Einreihen, bleibt der Marker leer und die Versuche werden gezählt (höchstens 5)', async () => {
|
||||
await aufbau()
|
||||
const b = await bestelle()
|
||||
const unbezahlt = zahle(b, { payment_status: 'unpaid', payment_method_types: ['sepa_debit'] })
|
||||
await deleteDocument(config.collections.portalFeatures, FEATURE) // Shop-Kontext fehlt: das Einreihen scheitert
|
||||
K.leereCache()
|
||||
for (let i = 0; i < 7; i += 1) assert.deepEqual(await B.meldeEingang({ accountId: ACCOUNT, session: unbezahlt, now: nach(60 + i) }), { gesendet: false })
|
||||
const d = JSON.parse(order(b.orderId).bestellung)
|
||||
assert.equal(d.mailsEingangAt, undefined)
|
||||
assert.equal(d.mailsVersuche.eingang, 5)
|
||||
assert.match(warnLog(), /G15 zur Bestellung/)
|
||||
})
|
||||
|
||||
test('pruefeOffene I-1: SEPA unterwegs - der Minutenjob holt die Eingangsmail G15 nach, ein zweiter Lauf schickt keine zweite', async () => {
|
||||
await aufbau()
|
||||
const sepa = await bestelle([{ produktId: 'a1', menge: 1 }])
|
||||
zahle(sepa, { payment_status: 'unpaid', payment_method_types: ['sepa_debit'] })
|
||||
const spaet = nach(30 * 60 + 30 + 6 * 60)
|
||||
const z = await B.pruefeOffene(spaet)
|
||||
assert.deepEqual(z, { geprueft: 1, bezahlt: 0, verworfen: 0, wartend: 1, fehler: 0 })
|
||||
await warteAufVersand()
|
||||
assert.equal(sink.sent.length, 1)
|
||||
assert.equal(sink.sent[0].to[0].address, 'max@example.com')
|
||||
await B.pruefeOffene(nach(30 * 60 + 30 + 8 * 60))
|
||||
await warteAufVersand()
|
||||
assert.equal(sink.sent.length, 1)
|
||||
assert.equal(order(sepa.orderId).status, 'offen')
|
||||
})
|
||||
|
||||
test('schliesseAb: späte Zahlung nach Ablauf wird angenommen, andere Stornos nicht', async () => {
|
||||
await aufbau()
|
||||
const a = await bestelle()
|
||||
|
||||
Reference in new issue
Block a user