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:
@@ -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/)
|
||||
})
|
||||
})
|
||||
@@ -77,9 +77,13 @@ const SV = {
|
||||
'Två tips: skicka som _dokument_ (gem-ikonen) för bästa skärpa, och en fil per kvitto. Flersidiga kvitton skickas som PDF.'
|
||||
const outro =
|
||||
'Jag är en AI-assistent. Skriv *hjälp* för mänsklig support, *stopp* för att koppla från.'
|
||||
// Two real ways to route a receipt, and the old copy named only one,
|
||||
// which read as if the per-receipt path did not exist. Own paragraph:
|
||||
// run together with the outro it read as a single sentence.
|
||||
const multi =
|
||||
companyCount > 1
|
||||
? `Du är med i ${companyCount} företag i Accounted. Välj standardföretag i panelen så hamnar kvitton rätt. `
|
||||
? `Du är med i ${companyCount} företag i Accounted. Välj antingen ett standardföretag i panelen, ` +
|
||||
'eller skicka ett kvitto i taget så frågar jag vilket företag det gäller direkt efter varje kvitto.\n\n'
|
||||
: ''
|
||||
return `${intro}\n\n${tips}\n\n${multi}${outro}`
|
||||
},
|
||||
@@ -206,7 +210,8 @@ const EN: typeof SV = {
|
||||
'I am an AI assistant. Type *hjälp* for human support, *stopp* to disconnect.'
|
||||
const multi =
|
||||
companyCount > 1
|
||||
? `You belong to ${companyCount} companies in Accounted. Pick a default company in the panel so receipts land in the right one. `
|
||||
? `You belong to ${companyCount} companies in Accounted. Either pick a default company in the panel, ` +
|
||||
'or send one receipt at a time and I will ask which company it belongs to right after each one.\n\n'
|
||||
: ''
|
||||
return `${intro}\n\n${tips}\n\n${multi}${outro}`
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user