From dd3d3e4b5f76e71bcf5cf53dd2097a58e416a6af Mon Sep 17 00:00:00 2001 From: Emma Jamieson-Hoare Date: Tue, 2 Jun 2026 14:07:47 +0200 Subject: [PATCH 1/2] test: add ES2020 challenge typecheck fixture --- examples/charge-wagmi/src/mppx-es2020-compat.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 examples/charge-wagmi/src/mppx-es2020-compat.ts diff --git a/examples/charge-wagmi/src/mppx-es2020-compat.ts b/examples/charge-wagmi/src/mppx-es2020-compat.ts new file mode 100644 index 00000000..665cc19c --- /dev/null +++ b/examples/charge-wagmi/src/mppx-es2020-compat.ts @@ -0,0 +1,13 @@ +import { Challenge } from 'mppx' + +// Included by the ES2020 example tsconfig to catch library APIs that require newer libs. +export const serializedChallenge = Challenge.serialize( + Challenge.from({ + id: 'abc123', + realm: 'api.example.com', + method: 'tempo', + intent: 'charge', + request: { amount: '1000000', currency: 'USD' }, + description: 'Pay "premium" path C:\\tempo\\api', + }), +) From 5298d2a24a6494001d41f2298cbfae16d00cbb68 Mon Sep 17 00:00:00 2001 From: Emma Jamieson-Hoare Date: Tue, 2 Jun 2026 14:34:52 +0200 Subject: [PATCH 2/2] test: expand challenge quoted-string escaping cases --- src/Challenge.test.ts | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Challenge.test.ts b/src/Challenge.test.ts index 357e0b27..b1226130 100644 --- a/src/Challenge.test.ts +++ b/src/Challenge.test.ts @@ -454,19 +454,45 @@ describe('serialize', () => { expect(header).toContain('expires="2025-01-06T12:00:00Z"') }) - test('behavior: escapes quoted-string values', () => { + test.each([ + { + description: 'Plain payment description', + escaped: 'Plain payment description', + label: 'plain values', + }, + { + description: 'Pay "premium"', + escaped: 'Pay \\"premium\\"', + label: 'double quotes', + }, + { + description: 'Path C:\\tempo\\api', + escaped: 'Path C:\\\\tempo\\\\api', + label: 'backslashes', + }, + { + description: 'Pay "premium" path C:\\tempo\\api', + escaped: 'Pay \\"premium\\" path C:\\\\tempo\\\\api', + label: 'mixed quotes and backslashes', + }, + { + description: 'Ends with slash \\', + escaped: 'Ends with slash \\\\', + label: 'trailing backslash', + }, + ])('behavior: escapes quoted-string values: $label', ({ description, escaped }) => { const challenge = Challenge.from({ id: 'abc123', realm: 'api.example.com', method: 'tempo', intent: 'charge', request: { amount: '1000000' }, - description: 'Pay "premium" path C:\\tempo\\api', + description, }) const header = Challenge.serialize(challenge) - expect(header).toContain('description="Pay \\"premium\\" path C:\\\\tempo\\\\api"') - expect(Challenge.deserialize(header).description).toBe('Pay "premium" path C:\\tempo\\api') + expect(header).toContain(`description="${escaped}"`) + expect(Challenge.deserialize(header).description).toBe(description) }) test('error: rejects CRLF in quoted-string values', () => {