nostream/test/unit/schemas/event-schema.spec.ts
Ricardo Arturo Cabral Mejia da61ac5a99
chore: allow 500 tags max
2022-10-18 23:11:27 -04:00

134 lines
6.3 KiB
TypeScript

import { expect } from 'chai'
import { assocPath, omit, range } from 'ramda'
import { Event } from '../../../src/@types/event'
import { eventSchema } from '../../../src/schemas/event-schema'
import { validateSchema } from '../../../src/utils/validation'
describe('NIP-01', () => {
let event: Event
describe('validate event schema', () => {
beforeEach(() => {
event = {
'id': 'fa4dd948576fe182f5d0e3120b9df42c83dffa1c884754d5e4d3b0a2f98a01c5',
'pubkey': 'edfa27d49d2af37ee331e1225bb6ed1912c6d999281b36d8018ad99bc3573c29',
'created_at': 1660306803,
'kind': 7,
'tags': [
[
'e',
'c58e83bb744e4c29642db7a5c3bd1519516ad5c51f6ba5f90c451d03c1961210',
'',
'root'
],
[
'e',
'd0d78967b734628cec7bdfa2321c71c1f1c48e211b4b54333c3b0e94e7e99166',
'',
'reply'
],
[
'p',
'edfa27d49d2af37ee331e1225bb6ed1912c6d999281b36d8018ad99bc3573c29'
],
[
'p',
'32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245'
],
[
'e',
'6fed2aae1e4f7d8b535774e4f7061c10e2ff20df1ef047da09462c7937925cd5'
],
[
'p',
'2ef93f01cd2493e04235a6b87b10d3c4a74e2a7eb7c3caf168268f6af73314b5'
]
],
'content': '',
'sig': '313a9b8cd68267a51da84e292c0937d1f3686c6757c4584f50fcedad2b13fad755e6226924f79880fb5aa9de95c04231a4823981513ac9e7092bad7488282a96'
}
})
it('returns same event if event is valid', () => {
const result = validateSchema(eventSchema)(event)
expect(result.error).to.be.undefined
expect(result.value).to.deep.equal(event)
})
const cases = {
id: [
{ message: 'must be a string', transform: assocPath(['id'], null), },
{ message: 'must only contain lowercase characters', transform: assocPath(['id'], 'F'.repeat(64)), },
{ message: 'must only contain hexadecimal characters', transform: assocPath(['id'], 'not hex'), },
{ message: 'length must be 64 characters long', transform: assocPath(['id'], 'f'.repeat(65)), },
{ message: 'length must be 64 characters long', transform: assocPath(['id'], 'f'.repeat(63)), },
{ message: 'is not allowed to be empty', transform: assocPath(['id'], ''), },
{ message: 'is required', transform: omit(['id']), },
],
pubkey: [
{ message: 'must be a string', transform: assocPath(['pubkey'], null), },
{ message: 'must only contain lowercase characters', transform: assocPath(['pubkey'], 'F'.repeat(64)), },
{ message: 'must only contain hexadecimal characters', transform: assocPath(['pubkey'], 'not hex'), },
{ message: 'length must be 64 characters long', transform: assocPath(['pubkey'], 'f'.repeat(65)), },
{ message: 'length must be 64 characters long', transform: assocPath(['pubkey'], 'f'.repeat(63)), },
{ message: 'is not allowed to be empty', transform: assocPath(['pubkey'], ''), },
{ message: 'is required', transform: omit(['pubkey']), },
],
created_at: [
{ message: 'must be a number', transform: assocPath(['created_at'], null), },
{ message: 'must be greater than or equal to 0', transform: assocPath(['created_at'], -1), },
{ message: 'must be a multiple of 1', transform: assocPath(['created_at'], Math.PI), },
{ message: 'is required', transform: omit(['created_at']), },
],
kind: [
{ message: 'must be a number', transform: assocPath(['kind'], null), },
{ message: 'must be greater than or equal to 0', transform: assocPath(['kind'], -1), },
{ message: 'must be a multiple of 1', transform: assocPath(['kind'], Math.PI), },
{ message: 'is required', transform: omit(['kind']), },
],
content: [
{ message: 'must be a string', transform: assocPath(['content'], null), },
{ message: 'length must be less than or equal to 65536 characters long', transform: assocPath(['content'], ' '.repeat(64 * 1024 + 1)), },
{ message: 'is required', transform: omit(['content']), },
],
sig: [
{ message: 'must be a string', transform: assocPath(['sig'], null), },
{ message: 'must only contain lowercase characters', transform: assocPath(['sig'], 'F'.repeat(128)), },
{ message: 'must only contain hexadecimal characters', transform: assocPath(['sig'], 'not hex'), },
{ message: 'length must be 128 characters long', transform: assocPath(['sig'], 'f'.repeat(129)), },
{ message: 'length must be 128 characters long', transform: assocPath(['sig'], 'f'.repeat(127)), },
{ message: 'is not allowed to be empty', transform: assocPath(['sig'], ''), },
{ message: 'is required', transform: omit(['sig']), },
],
tags: [
{ message: 'must be an array', transform: assocPath(['tags'], null), },
{ message: 'is required', transform: omit(['tags']), },
{ message: 'must contain less than or equal to 500 items', transform: assocPath(['tags'], range(0, 501).map(() => (['x', 'x']))) },
],
'tags[0]': [
{ message: 'must be an array', transform: assocPath(['tags', 0], null), },
{ message: 'must contain less than or equal to 10 items', transform: assocPath(['tags', 0], range(0, 11).map(() => 'x')) },
],
'tags[0][0]': [
{ message: 'must be a string', transform: assocPath(['tags', 0, 0], null), },
{ message: 'length must be less than or equal to 255 characters long', transform: assocPath(['tags', 0, 0], ' '.repeat(256)), },
{ message: 'is not allowed to be empty', transform: assocPath(['tags', 0, 0], ''), },
],
'tags[0][1]': [
{ message: 'must be a string', transform: assocPath(['tags', 0, 1], null), },
{ message: 'length must be less than or equal to 1024 characters long', transform: assocPath(['tags', 0, 1], ' '.repeat(1024 + 1)), },
],
}
for (const prop in cases) {
describe(prop, () => {
cases[prop].forEach(({ transform, message }) => {
it(`${prop} ${message}`, () => expect(
validateSchema(eventSchema)(transform(event))
).to.have.nested.property('error.message', `"${prop}" ${message}`))
})
})
}
})
})