fix(whatsapp-inbox): name both ways to route receipts for multi-company senders (#1424)

Field feedback after the first live receipt: the link confirmation told a
multi-company sender only to set a default company in the panel, so the
per-receipt path looked unsupported even though it is the one that
actually runs when no default is set. Now it names both: set a default,
or send one receipt at a time and answer the company question after each.

The guidance also moves to its own paragraph. Run together with the AI
disclosure it read as one sentence, which is how a real user came away
believing the bot had called itself a "mänsklig AI-assistent".

New copy test asserts the promise (both options present, disclosure kept
in its own paragraph, single-company message unchanged) rather than the
exact wording, so a rewrite stays free but a dropped option fails.
Mutation-checked against the previous copy.

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-08-05 19:43:37 +02:00
committed by GitHub
co-authored by Jakob Wennberg Claude Fable 5
parent 77d20287b9
commit c84f951a5c
2 changed files with 44 additions and 2 deletions
@@ -0,0 +1,37 @@
import { describe, it, expect } from 'vitest'
import { botCopy } from '@/extensions/general/whatsapp-inbox/lib/messages'
/**
* Copy contracts that a rewrite must not quietly break. These assert the
* PROMISE the message makes to the user, not its exact wording: rephrasing
* is fine, dropping one of the two routing options is not.
*/
describe('m3Linked, multi-company sender', () => {
for (const locale of ['sv', 'en'] as const) {
it(`${locale}: names BOTH ways to route receipts`, () => {
const msg = botCopy(locale).m3Linked({ companyName: 'Arcim Technology AB', companyCount: 7 })
// Option 1: a default company set in the panel.
expect(msg).toMatch(locale === 'sv' ? /standardföretag/i : /default company/i)
// Option 2: per receipt, answered right after each one. Field feedback
// 2026-08-05: the old copy named only option 1, which read as if the
// per-receipt path did not exist.
expect(msg).toMatch(locale === 'sv' ? /ett kvitto i taget/i : /one receipt at a time/i)
})
it(`${locale}: keeps the routing guidance out of the AI-disclosure paragraph`, () => {
// Run together they read as a single sentence, which is how a real
// user mis-read the disclosure. Own paragraph, always.
const msg = botCopy(locale).m3Linked({ companyName: 'Arcim Technology AB', companyCount: 7 })
const disclosureParagraph = msg.split('\n\n').find((p) => /AI[- ]assistant|AI-assistent/i.test(p))
expect(disclosureParagraph).toBeDefined()
expect(disclosureParagraph).not.toMatch(/standardföretag|default company/i)
})
}
it('says nothing about company routing when the sender has exactly one company', () => {
const msg = botCopy('sv').m3Linked({ companyName: 'Arcim Technology AB', companyCount: 1 })
expect(msg).not.toMatch(/standardföretag/i)
expect(msg).toMatch(/AI-assistent/)
})
})