Viewing is open to everyone. Downloading and starring need a GitHub sign-in.
Sign in with GitHub
payload.test.mjs
v0.1.0-build.85
Latest
Commit ede38f5
Sign in with GitHub to download. Each download is recorded with your GitHub username.
| 1 | // Pure-JS tests: payload classification (spec/CKey-Payload-Conventions.md). |
| 2 | import test from 'node:test'; |
| 3 | import assert from 'node:assert/strict'; |
| 4 | import { classifyPayload, readableText, toHex } from '../js/payload.mjs'; |
| 5 | |
| 6 | const kind = (t) => classifyPayload(t).kind; |
| 7 | |
| 8 | test('recognized forms', () => { |
| 9 | assert.deepEqual(classifyPayload('https://citeory.com/tour'), { |
| 10 | kind: 'https', target: 'https://citeory.com/tour', label: 'Open citeory.com', |
| 11 | }); |
| 12 | assert.equal(classifyPayload(' HTTP://Example.com/x ').kind, 'http'); |
| 13 | assert.equal(classifyPayload(' HTTP://Example.com/x ').target, 'HTTP://Example.com/x'); |
| 14 | assert.deepEqual(classifyPayload('mailto:hello@citeory.com?subject=Hi'), { |
| 15 | kind: 'mailto', target: 'mailto:hello@citeory.com?subject=Hi', label: 'Email hello@citeory.com', |
| 16 | }); |
| 17 | assert.equal(classifyPayload('tel:+1 (555) 123-4567').label, 'Call +15551234567'); |
| 18 | assert.equal(classifyPayload('sms:+15551234567?body=Hi').label, 'Message +15551234567'); |
| 19 | assert.equal(classifyPayload('geo:37.33490,-122.00900?q=Apple%20Park').label, 'Show 37.33490, -122.00900 on a map'); |
| 20 | assert.deepEqual(classifyPayload('address:1 Infinite Loop\n Cupertino, CA 95014\n\n'), { |
| 21 | kind: 'address', target: '1 Infinite Loop, Cupertino, CA 95014', label: 'Show 1 Infinite Loop, Cupertino, CA 95014 on a map', |
| 22 | }); |
| 23 | const vcard = 'BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ada Lovelace\r\nEND:VCARD'; |
| 24 | assert.deepEqual(classifyPayload(vcard), { kind: 'vcard', target: vcard, label: 'Add contact Ada Lovelace' }); |
| 25 | }); |
| 26 | |
| 27 | test('validation failures are plain text (rule 4)', () => { |
| 28 | assert.equal(kind('mailto:nobody'), 'text'); |
| 29 | assert.equal(kind('tel:12'), 'text'); |
| 30 | assert.equal(kind('sms:+1'), 'text'); |
| 31 | assert.equal(kind('geo:91,0'), 'text'); |
| 32 | assert.equal(kind('geo:0,181'), 'text'); |
| 33 | assert.equal(kind('geo:abc'), 'text'); |
| 34 | assert.equal(kind('address: \n '), 'text'); |
| 35 | assert.equal(kind('https://'), 'text'); |
| 36 | assert.equal(kind('BEGIN:VCARD\nFN:x'), 'text'); |
| 37 | }); |
| 38 | |
| 39 | test('allowlist only (rule 2)', () => { |
| 40 | for (const t of ['javascript:alert(1)', 'data:text/html,hi', 'file:///etc/passwd', 'intent://x#Intent;end', 'myapp://open', 'ftp://x.org']) { |
| 41 | assert.deepEqual(classifyPayload(t), { kind: 'text', target: null, label: 'Plain text' }, t); |
| 42 | } |
| 43 | assert.equal(kind('just words'), 'text'); |
| 44 | assert.equal(kind(''), 'text'); |
| 45 | }); |
| 46 | |
| 47 | test('bytes input and readable text', () => { |
| 48 | const enc = new TextEncoder(); |
| 49 | assert.equal(classifyPayload(enc.encode('https://openckey.org')).kind, 'https'); |
| 50 | assert.equal(classifyPayload(Uint8Array.of(0xff, 0x00)).label, 'Binary data'); |
| 51 | assert.equal(readableText(enc.encode('a\tb\r\nc')), 'a\tb\r\nc'); |
| 52 | assert.equal(readableText(enc.encode('Grüße 👋')), 'Grüße 👋'); |
| 53 | assert.equal(readableText(Uint8Array.of(0x61, 0x00)), null); |
| 54 | assert.equal(readableText(Uint8Array.of(0x61, 0x1b)), null); |
| 55 | assert.equal(readableText(enc.encode('a\u0085b')), null); |
| 56 | assert.equal(readableText(Uint8Array.of(0xc3, 0x28)), null); |
| 57 | assert.equal(readableText(new Uint8Array(0)), null); |
| 58 | assert.equal(toHex(Uint8Array.of(0, 15, 255)), '000fff'); |
| 59 | }); |