taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 0989504aa59c5e6911a7f4b862782e8635ba2b8c
parent 195c58648cc736ffe9e4be0dcfd235d96b2a5e66
Author: Florian Dold <dold@taler.net>
Date:   Tue, 21 Jul 2026 11:05:53 +0200

util: test the field layout of the generated payment QR codes

Diffstat:
Apackages/taler-util/src/qr.test.ts | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+), 0 deletions(-)

diff --git a/packages/taler-util/src/qr.test.ts b/packages/taler-util/src/qr.test.ts @@ -0,0 +1,65 @@ +/* + This file is part of GNU Taler + (C) 2026 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +import assert from "node:assert"; +import { test } from "node:test"; +import { getQrCodesForPayto, QrCodeSpec } from "./qr.js"; + +function contentOf(codes: QrCodeSpec[], type: string) { + const found = codes.find((c) => c.type === type); + assert.ok(found, `no ${type} code generated`); + return found.qrContent; +} + +test("EPC QR keeps the beneficiary IBAN in its own field", (t) => { + // The record is newline delimited: line 6 is the beneficiary name and line 7 + // the beneficiary IBAN. A payto parameter carrying a line break would + // otherwise let whoever supplied the URI choose the account being paid. + const codes = getQrCodesForPayto( + "payto://iban/DE75512108001245126199" + + "?receiver-name=Alice%0ADE89370400440532013000%0AEUR999.99" + + "&amount=EUR:10", + ); + const lines = contentOf(codes, "epc-qr").split("\n"); + assert.strictEqual(lines[6], "DE75512108001245126199"); + assert.strictEqual(lines[7], "EUR10.00"); +}); + +test("Swiss QR bill keeps its field layout", (t) => { + const codes = getQrCodesForPayto( + "payto://iban/CH9300762011623852957" + + "?receiver-name=Alice%0AS%0AMallory" + + "&amount=CHF:10", + ); + const lines = contentOf(codes, "spc").split("\n"); + assert.strictEqual(lines[0], "SPC"); + assert.strictEqual(lines[3], "CH9300762011623852957"); + assert.strictEqual(lines[4], "S"); + // Address lines follow the beneficiary name and must stay empty. + assert.strictEqual(lines[6], ""); + assert.strictEqual(lines[7], ""); +}); + +test("a well-formed payto still produces a usable EPC record", (t) => { + const codes = getQrCodesForPayto( + "payto://iban/DE75512108001245126199?receiver-name=Alice&amount=EUR:10", + ); + const lines = contentOf(codes, "epc-qr").split("\n"); + assert.strictEqual(lines[0], "BCD"); + assert.strictEqual(lines[5], "Alice"); + assert.strictEqual(lines[6], "DE75512108001245126199"); + assert.strictEqual(lines[7], "EUR10.00"); +});