test: isEventMatchingFilter

This commit is contained in:
Ricardo Arturo Cabral Mejia 2022-08-07 03:22:39 +00:00
parent b3b05f8ae0
commit d8cd553e24
No known key found for this signature in database
GPG Key ID: 5931EBF43A650245
6 changed files with 235 additions and 18 deletions

View File

@ -1,4 +1,31 @@
[
{
"id": "cf8de9db67a1d7203512d1d81e6190f5e53abfdc0ac90275f67172b65a5b09a0",
"pubkey": "e8b487c079b0f67c695ae6c4c2552a47f38adfa2533cc5926bd2c102942fdcb7",
"created_at": 1645030752,
"kind": 1,
"tags": [["r", "https://fiatjaf.com"]],
"content": "r",
"sig": "53d12018d036092794366283eca36df4e0cabd014b6e91bbf684c8bb9bbbe9dedafa77b6b928587e11e05e036227598dded8713e8da17d55076e12242b361542"
},
{
"id": "91503a45bca4631ce768b1ba806a4526c2a953d9fa60a8c7afa65341776d85a2",
"pubkey": "e8b487c079b0f67c695ae6c4c2552a47f38adfa2533cc5926bd2c102942fdcb7",
"created_at": 1645030912,
"kind": 1,
"tags": [["r", "https://fiatjaf.com"]],
"content": "testing a comment here",
"sig": "f3c2acfb971920f822e8f2c6a61b60a897ac349b6dbbd906f7e21781fbd58517fce4f9b5b93270236875861e09336cedbbc498b84ec3d5b65dea212546114c9d"
},
{
"id": "423a19c9f81fb295101fe2ae491b928b327832a3346b9929e55777b9a97364ad",
"pubkey": "e8b487c079b0f67c695ae6c4c2552a47f38adfa2533cc5926bd2c102942fdcb7",
"created_at": 1645049616,
"kind": 1,
"tags": [["r", "https://fiatjaf.com"]],
"content": "what",
"sig": "3ee017e2090ad8c1d1ac14bf68692620aa91bdf7b8b1f76f3bf7192ff52f0e9e15c57ba1c69132c0864e88774c265dfde8727dd81cda444b5cd973fd5bc44bca"
},
{
"id": "00391038e0d23e69d30289ede976ef6663313df85b479a4b59895e5245428f0c",
"pubkey": "22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793",

8
src/constants/base.ts Normal file
View File

@ -0,0 +1,8 @@
export enum EventKinds {
SET_METADATA = 0,
TEXT_NODE = 1,
RECOMMEND_SERVER = 2,
CONTACT_LIST = 3,
ENCRYPTED_DIRECT_MESSAGE = 4,
DELETE = 5,
}

View File

@ -1,5 +1,5 @@
import { Event, CanonicalEvent } from 'types/event'
import { SubscriptionFilter } from 'types/subscription'
import { CanonicalEvent, Event } from './types/event'
import { SubscriptionFilter } from './types/subscription'
export const serializeEvent = (event: Partial<Event>): CanonicalEvent => [
0,
@ -36,9 +36,24 @@ export const isEventMatchingFilter =
return false
}
// TODO: support #e and #p tags
// if (Array.isArray(filter['#e']) && filter['#e'].length) {
// filter['#e'].event.tags.some()
// }
// NIP-01: Support #e and #p tags
// NIP-12: Support generic tag queries
const isGenericTagQuery = (key: string) => /^#[a-z]$/.test(key)
if (
Object.entries(filter)
.filter(
([key, criteria]) =>
isGenericTagQuery(key) && Array.isArray(criteria),
)
.some(([key, criteria]) => {
return !event.tags.some(
(tag) => tag[0] === key[1] && criteria.includes(tag[1]),
)
})
) {
return false
}
return true
}

View File

@ -1,20 +1,13 @@
import { Pubkey } from 'types'
import { EventKinds } from '../constants/base'
import { Pubkey, TagName } from '../types/base'
export type EventId = string
export interface Tag {
0: TagName
[index: number]: string
}
export enum EventKinds {
SET_METADATA = 0,
TEXT_NODE = 1,
RECOMMEND_SERVER = 2,
CONTACT_LIST = 3,
ENCRYPTED_DIRECT_MESSAGE = 4,
DELETE = 5,
}
export interface Event {
id: EventId
pubkey: Pubkey

View File

@ -1,6 +1,7 @@
import { expect } from 'chai'
import { Event, EventKinds, CanonicalEvent } from '../../src/types/event'
import { serializeEvent } from '../../src/event'
import { Event, CanonicalEvent } from '../../src/types/event'
import { isEventMatchingFilter, serializeEvent } from '../../src/event'
import { EventKinds } from '../../src/constants/base'
describe('serializeEvent', () => {
it('returns serialized event given a Nostr event', () => {
@ -24,3 +25,176 @@ describe('serializeEvent', () => {
expect(serializeEvent(event)).to.eqls(expected)
})
})
describe('isEventMatchingFilter', () => {
let event: Event
beforeEach(() => {
event = {
id: '6b3cdd0302ded8068ad3f0269c74423ca4fee460f800f3d90103b63f14400407',
pubkey:
'22e804d26ed16b68db5259e78449e96dab5d464c8f470bda3eb1a70467f2c793',
created_at: 1648351380,
kind: 1,
tags: [
[
'p',
'8355095016fddbe31fcf1453b26f613553e9758cf2263e190eac8fd96a3d3de9',
'wss://nostr-pub.wellorder.net',
],
[
'e',
'7377fa81fc6c7ae7f7f4ef8938d4a603f7bf98183b35ab128235cc92d4bebf96',
'wss://nostr-relay.untethr.me',
],
],
content:
"I've set up mirroring between relays: https://i.imgur.com/HxCDipB.png",
sig: 'b37adfed0e6398546d623536f9ddc92b95b7dc71927e1123266332659253ecd0ffa91ddf2c0a82a8426c5b363139d28534d6cac893b8a810149557a3f6d36768',
}
})
it('returns true if filter is empty', () => {
expect(isEventMatchingFilter({})(event)).to.be.true
})
describe('ids filter', () => {
it('returns false if ids filter is empty', () => {
expect(isEventMatchingFilter({ ids: [] })(event)).to.be.false
})
it('returns true if ids filter contains event id', () => {
expect(isEventMatchingFilter({ ids: [event.id] })(event)).to.be.true
})
it('returns false if ids filter does not contains event id', () => {
expect(isEventMatchingFilter({ ids: ['something else'] })(event)).to.be
.false
})
})
describe('authors filter', () => {
it('returns false if authors filter is empty', () => {
expect(isEventMatchingFilter({ authors: [] })(event)).to.be.false
})
it('returns true if authors filter contains event id', () => {
expect(isEventMatchingFilter({ authors: [event.pubkey] })(event)).to.be
.true
})
it('returns false if authors filter does not contains event id', () => {
expect(isEventMatchingFilter({ authors: ['something else'] })(event)).to
.be.false
})
})
describe('kinds filter', () => {
it('returns false if kinds filter is empty', () => {
expect(isEventMatchingFilter({ kinds: [] })(event)).to.be.false
})
it('returns true if kinds filter contains event id', () => {
expect(isEventMatchingFilter({ kinds: [event.kind] })(event)).to.be.true
})
it('returns false if kinds filter does not contains event id', () => {
expect(isEventMatchingFilter({ kinds: [666] })(event)).to.be.false
})
})
describe('since filter', () => {
it('returns true if since < event created at', () => {
expect(isEventMatchingFilter({ since: event.created_at - 1 })(event)).to
.be.true
})
it('returns true if since = event created at', () => {
expect(isEventMatchingFilter({ since: event.created_at })(event)).to.be
.true
})
it('returns false if since > event created at', () => {
expect(isEventMatchingFilter({ since: event.created_at + 1 })(event)).to
.be.false
})
})
describe('until filter', () => {
it('returns false if until < event created at', () => {
expect(isEventMatchingFilter({ until: event.created_at - 1 })(event)).to
.be.false
})
it('returns true if until = event created at', () => {
expect(isEventMatchingFilter({ until: event.created_at })(event)).to.be
.true
})
it('returns true if until > event created at', () => {
expect(isEventMatchingFilter({ until: event.created_at + 1 })(event)).to
.be.true
})
})
describe('#e filter', () => {
it('returns false if #e filter is empty', () => {
expect(isEventMatchingFilter({ '#e': [] })(event)).to.be.false
})
it('returns true if #e filter contains e tag in event', () => {
expect(isEventMatchingFilter({ '#e': [event.tags[1][1]] })(event)).to.be
.true
})
it('returns false if #e filter does not contain tag in event', () => {
expect(isEventMatchingFilter({ '#e': ['something else'] })(event)).to.be
.false
})
})
describe('#p filter', () => {
it('returns false if #p filter is empty', () => {
expect(isEventMatchingFilter({ '#p': [] })(event)).to.be.false
})
it('returns true if #p filter contains p tag in event', () => {
expect(isEventMatchingFilter({ '#p': [event.tags[0][1]] })(event)).to.be
.true
})
it('returns false if #p filter does not contain tag in event', () => {
expect(isEventMatchingFilter({ '#p': ['something else'] })(event)).to.be
.false
})
})
describe('#r filter', () => {
beforeEach(() => {
event = {
id: 'cf8de9db67a1d7203512d1d81e6190f5e53abfdc0ac90275f67172b65a5b09a0',
pubkey:
'e8b487c079b0f67c695ae6c4c2552a47f38adfa2533cc5926bd2c102942fdcb7',
created_at: 1645030752,
kind: 1,
tags: [['r', 'https://fiatjaf.com']],
content: 'r',
sig: '53d12018d036092794366283eca36df4e0cabd014b6e91bbf684c8bb9bbbe9dedafa77b6b928587e11e05e036227598dded8713e8da17d55076e12242b361542',
}
})
it('returns false if #r filter is empty', () => {
expect(isEventMatchingFilter({ '#r': [] })(event)).to.be.false
})
it('returns true if #r filter contains p tag in event', () => {
expect(isEventMatchingFilter({ '#r': [event.tags[0][1]] })(event)).to.be
.true
})
it('returns false if #r filter does not contain tag in event', () => {
expect(isEventMatchingFilter({ '#r': ['something else'] })(event)).to.be
.false
})
})
})