nostream/test/unit/schemas/event-schema.spec.ts
Ricardo Arturo Cabral Mejía 85ac61cc93 chore: remove schema limits for tag/content
Signed-off-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
2022-11-22 19:36:42 -05:00

141 lines
6.2 KiB
TypeScript

import { assocPath, omit, range } from 'ramda'
import { expect } from 'chai'
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)
})
it('returns error if unknown key is provided', () => {
Object.assign(event, { unknown: 1 })
expect(validateSchema(eventSchema)(event)).to.have.nested.property('error.message', '"unknown" is not allowed')
})
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: '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']) },
],
tag: [
{ 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')) },
],
identifier: [
{ 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], '') },
],
value: [
{ 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}`))
})
})
}
})
})