diff --git a/extensions/general/whatsapp-inbox/__tests__/messages-copy.test.ts b/extensions/general/whatsapp-inbox/__tests__/messages-copy.test.ts new file mode 100644 index 00000000..8e49c74c --- /dev/null +++ b/extensions/general/whatsapp-inbox/__tests__/messages-copy.test.ts @@ -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/) + }) +}) diff --git a/extensions/general/whatsapp-inbox/lib/messages.ts b/extensions/general/whatsapp-inbox/lib/messages.ts index da28e59e..3957d1c5 100644 --- a/extensions/general/whatsapp-inbox/lib/messages.ts +++ b/extensions/general/whatsapp-inbox/lib/messages.ts @@ -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}` },