375 lines
11 KiB
TypeScript
375 lines
11 KiB
TypeScript
import { describe, expect, it } from 'bun:test'
|
|
|
|
import { Event, EventTemplate } from './core.ts'
|
|
import { FileMetadata as FileMetadataKind } from './kinds.ts'
|
|
import { FileMetadataObject, generateEventTemplate, parseEvent, validateEvent } from './nip94.ts'
|
|
import { finalizeEvent, generateSecretKey } from './pure.ts'
|
|
|
|
describe('generateEventTemplate', () => {
|
|
it('should generate the correct event template', () => {
|
|
const fileMetadataObject: FileMetadataObject = {
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
url: 'https://example.com/image.jpg',
|
|
m: 'image/jpeg',
|
|
x: 'image',
|
|
ox: 'original',
|
|
size: '1024',
|
|
dim: '800x600',
|
|
i: 'abc123',
|
|
blurhash: 'abcdefg',
|
|
thumb: 'https://example.com/thumb.jpg',
|
|
image: 'https://example.com/image.jpg',
|
|
summary: 'Lorem ipsum',
|
|
alt: 'Image alt text',
|
|
}
|
|
|
|
const expectedEventTemplate: EventTemplate = {
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: expect.any(Number),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
}
|
|
|
|
const eventTemplate = generateEventTemplate(fileMetadataObject)
|
|
|
|
expect(eventTemplate).toEqual(expectedEventTemplate)
|
|
})
|
|
})
|
|
|
|
describe('validateEvent', () => {
|
|
it('should return true for a valid event', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const event: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(validateEvent(event)).toBe(true)
|
|
})
|
|
|
|
it('should return false if kind is not FileMetadataKind', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const event: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: 0, // not FileMetadataKind
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(validateEvent(event)).toBe(false)
|
|
})
|
|
|
|
it('should return false if content is empty', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const event: Event = finalizeEvent(
|
|
{
|
|
content: '', // empty
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(validateEvent(event)).toBe(false)
|
|
})
|
|
|
|
it('should return false if required tags are missing', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const eventWithoutUrl: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
// missing url
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
const eventWithoutM: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
// missing m
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
const eventWithoutX: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
// missing x
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
const eventWithoutOx: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
// missing ox
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(validateEvent(eventWithoutUrl)).toBe(false)
|
|
expect(validateEvent(eventWithoutM)).toBe(false)
|
|
expect(validateEvent(eventWithoutX)).toBe(false)
|
|
expect(validateEvent(eventWithoutOx)).toBe(false)
|
|
})
|
|
|
|
it('should return false if size is not a number', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const event: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', 'abc'], // not a number
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(validateEvent(event)).toBe(false)
|
|
})
|
|
|
|
it('should return false if dim is not a valid dimension string', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const eventWithInvalidDim: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', 'abc'], // invalid dim
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(validateEvent(eventWithInvalidDim)).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('parseEvent', () => {
|
|
it('should parse a valid event', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const event: Event = finalizeEvent(
|
|
{
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
const parsedEvent = parseEvent(event)
|
|
|
|
expect(parsedEvent).toEqual({
|
|
content: 'Lorem ipsum dolor sit amet',
|
|
url: 'https://example.com/image.jpg',
|
|
m: 'image/jpeg',
|
|
x: 'image',
|
|
ox: 'original',
|
|
size: '1024',
|
|
dim: '800x600',
|
|
i: 'abc123',
|
|
blurhash: 'abcdefg',
|
|
thumb: 'https://example.com/thumb.jpg',
|
|
image: 'https://example.com/image.jpg',
|
|
summary: 'Lorem ipsum',
|
|
alt: 'Image alt text',
|
|
})
|
|
})
|
|
|
|
it('should throw an error if the event is invalid', () => {
|
|
const sk = generateSecretKey()
|
|
|
|
const event: Event = finalizeEvent(
|
|
{
|
|
content: '', // invalid
|
|
created_at: Math.floor(Date.now() / 1000),
|
|
kind: FileMetadataKind,
|
|
tags: [
|
|
['url', 'https://example.com/image.jpg'],
|
|
['m', 'image/jpeg'],
|
|
['x', 'image'],
|
|
['ox', 'original'],
|
|
['size', '1024'],
|
|
['dim', '800x600'],
|
|
['i', 'abc123'],
|
|
['blurhash', 'abcdefg'],
|
|
['thumb', 'https://example.com/thumb.jpg'],
|
|
['image', 'https://example.com/image.jpg'],
|
|
['summary', 'Lorem ipsum'],
|
|
['alt', 'Image alt text'],
|
|
],
|
|
},
|
|
sk,
|
|
)
|
|
|
|
expect(() => parseEvent(event)).toThrow('Invalid event')
|
|
})
|
|
})
|