From 1162935f584ce51cd6d204e22a3d554207cd6158 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Mon, 19 Dec 2022 19:51:55 -0300 Subject: [PATCH] add a bunch of tests. --- event.test.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ event.ts | 2 +- filter.test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ filter.ts | 10 ++++++++-- keys.test.js | 20 ++++++++++++++++++++ nip04.test.js | 14 ++++++++++++++ package.json | 5 ++++- 7 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 event.test.js create mode 100644 filter.test.js create mode 100644 keys.test.js create mode 100644 nip04.test.js diff --git a/event.test.js b/event.test.js new file mode 100644 index 0000000..0e77547 --- /dev/null +++ b/event.test.js @@ -0,0 +1,49 @@ +/* eslint-env jest */ + +const { + validateEvent, + verifySignature, + signEvent, + getEventHash, + getPublicKey +} = require('./cjs') + +const event = { + id: 'd7dd5eb3ab747e16f8d0212d53032ea2a7cadef53837e5a6c66d42849fcb9027', + kind: 1, + pubkey: '22a12a128a3be27cd7fb250cbe796e692896398dc1440ae3fa567812c8107c1c', + created_at: 1670869179, + content: + 'NOSTR "WINE-ACCOUNT" WITH HARVEST DATE STAMPED\n\n\n"The older the wine, the greater its reputation"\n\n\n22a12a128a3be27cd7fb250cbe796e692896398dc1440ae3fa567812c8107c1c\n\n\nNWA 2022-12-12\nAA', + tags: [['client', 'astral']], + sig: 'f110e4fdf67835fb07abc72469933c40bdc7334615610cade9554bf00945a1cebf84f8d079ec325d26fefd76fe51cb589bdbe208ac9cdbd63351ddad24a57559' +} + +const unsigned = { + created_at: 1671217411, + kind: 0, + tags: [], + content: + '{"name":"fiatjaf","about":"buy my merch at fiatjaf store","picture":"https://fiatjaf.com/static/favicon.jpg","nip05":"_@fiatjaf.com"}' +} + +const privateKey = + '5c6c25b7ef18d8633e97512159954e1aa22809c6b763e94b9f91071836d00217' + +test('validate event', () => { + expect(validateEvent(event)).toBeTruthy() +}) + +test('check signature', async () => { + expect(await verifySignature(event)).toBeTruthy() +}) + +test('sign event', async () => { + let sig = await signEvent(unsigned, privateKey) + let hash = getEventHash(unsigned) + let pubkey = getPublicKey(privateKey) + + let signed = {...unsigned, id: hash, sig, pubkey} + + expect(await verifySignature(signed)).toBeTruthy() +}) diff --git a/event.ts b/event.ts index 6d54923..8b93890 100644 --- a/event.ts +++ b/event.ts @@ -64,6 +64,6 @@ export function verifySignature( export async function signEvent(event: Event, key: string): Promise { return Buffer.from( - await secp256k1.schnorr.sign(getEventHash(event), key) + await secp256k1.schnorr.sign(event.id || getEventHash(event), key) ).toString('hex') } diff --git a/filter.test.js b/filter.test.js new file mode 100644 index 0000000..ecc5002 --- /dev/null +++ b/filter.test.js @@ -0,0 +1,42 @@ +/* eslint-env jest */ + +const {matchFilters} = require('./cjs') + +test('test if filters match', () => { + ;[ + { + filters: [{ids: ['i']}], + good: [{id: 'i'}], + bad: [{id: 'j'}] + }, + { + filters: [{authors: ['abc']}, {kinds: [1, 3]}], + good: [ + {pubkey: 'xyz', kind: 3}, + {pubkey: 'abc', kind: 12}, + {pubkey: 'abc', kind: 1} + ], + bad: [{pubkey: 'hhh', kind: 12}] + }, + { + filters: [{'#e': ['yyy'], since: 444}], + good: [ + { + tags: [ + ['e', 'uuu'], + ['e', 'yyy'] + ], + created_at: 555 + } + ], + bad: [{tags: [['e', 'uuu']], created_at: 111}] + } + ].forEach(({filters, good, bad}) => { + good.forEach(ev => { + expect(matchFilters(filters, ev)).toBeTruthy() + }) + bad.forEach(ev => { + expect(matchFilters(filters, ev)).toBeFalsy() + }) + }) +}) diff --git a/filter.ts b/filter.ts index 3f9858d..20137c8 100644 --- a/filter.ts +++ b/filter.ts @@ -9,7 +9,10 @@ export type Filter = { [key: `#${string}`]: string[] } -export function matchFilter(filter: Filter, event: Event & {id: string}) { +export function matchFilter( + filter: Filter, + event: Event & {id: string} +): boolean { if (filter.ids && filter.ids.indexOf(event.id) === -1) return false if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) return false if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) @@ -35,7 +38,10 @@ export function matchFilter(filter: Filter, event: Event & {id: string}) { return true } -export function matchFilters(filters: Filter[], event: Event & {id: string}) { +export function matchFilters( + filters: Filter[], + event: Event & {id: string} +): boolean { for (let i = 0; i < filters.length; i++) { if (matchFilter(filters[i], event)) return true } diff --git a/keys.test.js b/keys.test.js new file mode 100644 index 0000000..ac0e65b --- /dev/null +++ b/keys.test.js @@ -0,0 +1,20 @@ +/* eslint-env jest */ + +const {generatePrivateKey, getPublicKey} = require('./cjs') + +test('test private key generation', () => { + expect(generatePrivateKey()).toMatch(/[a-f0-9]{64}/) +}) + +test('test public key generation', () => { + expect(getPublicKey(generatePrivateKey())).toMatch(/[a-f0-9]{64}/) +}) + +test('test public key from private key deterministic', () => { + let sk = generatePrivateKey() + let pk = getPublicKey(sk) + + for (let i = 0; i < 5; i++) { + expect(getPublicKey(sk)).toEqual(pk) + } +}) diff --git a/nip04.test.js b/nip04.test.js new file mode 100644 index 0000000..0de777e --- /dev/null +++ b/nip04.test.js @@ -0,0 +1,14 @@ +/* eslint-env jest */ + +const {nip04, getPublicKey, generatePrivateKey} = require('./cjs') + +test('encrypt and decrypt message', () => { + let sk1 = generatePrivateKey() + let sk2 = generatePrivateKey() + let pk1 = getPublicKey(sk1) + let pk2 = getPublicKey(sk2) + + expect(nip04.decrypt(sk2, pk1, nip04.encrypt(sk1, pk2, 'hello'))).toEqual( + 'hello' + ) +}) diff --git a/package.json b/package.json index 7697e1a..8e333fc 100644 --- a/package.json +++ b/package.json @@ -34,11 +34,14 @@ "eslint-plugin-babel": "^5.3.1", "esm-loader-typescript": "^1.0.1", "events": "^3.3.0", + "jest": "^29.3.1", + "ts-jest": "^29.0.3", "tsd": "^0.22.0", "typescript": "^4.9.4" }, "scripts": { "build": "node build.cjs", - "prepublish": "yarn run build" + "pretest": "node build.cjs", + "test": "jest" } }