import assert from 'node:assert/strict'
import { describe, it } from 'node:test'
import {
assertEndpointId,
requireSessionizeView,
sessionizeViewUrl,
} from '../src/client.ts'
import {
flattenSessionGroups,
matchSession,
matchSpeaker,
projectEvent,
projectSchedule,
slimSpeakerFromListed,
} from '../src/project.ts'
import describeSessionize from '../src/index.ts'
import { fixtureAll, fixtureSchedule, fixtureSessionGroups } from './fixtures.ts'
describe('endpoint validation', () => {
it('accepts the official demo id', () => {
assert.equal(assertEndpointId('jl4ktls0'), 'jl4ktls0')
})
it('rejects empty or malformed ids', () => {
assert.throws(() => assertEndpointId(''), /Invalid Sessionize endpointId/)
assert.throws(() => assertEndpointId('../oops'), /Invalid Sessionize endpointId/)
})
it('builds view urls and rejects unknown views', () => {
assert.equal(
sessionizeViewUrl('jl4ktls0', 'All'),
'https://sessionize.com/api/v2/jl4ktls0/view/All',
)
assert.throws(() => requireSessionizeView('Rooms'), /Unsupported Sessionize view/)
})
})
describe('event projection', () => {
it('joins rooms, speakers, and categories onto sessions', () => {
const event = projectEvent('jl4ktls0', fixtureAll)
assert.equal(event.sessionCount, 2)
assert.equal(event.speakerCount, 1)
const keynote = event.sessions.find((session) => session.id === '14022')
assert.ok(keynote)
assert.equal(keynote.room, 'Green Room')
assert.deepEqual(keynote.speakers, [
{ id: '00000000-0000-0000-0000-000000000004', name: 'Aiden Test' },
])
assert.deepEqual(keynote.categories, [
{ name: 'Session format', values: ['Session'] },
{ name: 'Track', values: ['Technical'] },
])
assert.deepEqual(event.speakers[0]?.sessionTitles, ["Aiden's Keynote"])
})
it('flattens grouped sessions without duplicating ids', () => {
const items = flattenSessionGroups(fixtureSessionGroups)
assert.equal(items.length, 1)
assert.equal(items[0]?.room, 'Green Room')
assert.equal(items[0]?.speakers[0]?.name, 'Aiden Test')
})
it('projects schedule slots from room sessions', () => {
const schedule = projectSchedule('jl4ktls0', fixtureSchedule)
assert.equal(schedule.days.length, 1)
assert.equal(schedule.days[0]?.slots.length, 1)
assert.equal(schedule.days[0]?.slots[0]?.session.title, "Aiden's Keynote")
assert.equal(schedule.days[0]?.slots[0]?.room, 'Green Room')
})
})
describe('search', () => {
it('matches sessions by title, id, or speaker', () => {
const event = projectEvent('jl4ktls0', fixtureAll)
const keynote = event.sessions[0]
assert.ok(keynote)
assert.equal(matchSession(keynote, '14022'), true)
assert.equal(matchSession(keynote, 'aiden'), true)
assert.equal(matchSession(keynote, 'Lunch'), false)
})
it('matches speakers by name and session title', () => {
const speaker = slimSpeakerFromListed({
id: 'abc',
firstName: 'Sophia',
lastName: 'Test',
fullName: 'Sophia Test',
bio: null,
tagLine: 'CEO / Contoso',
profilePicture: null,
isTopSpeaker: true,
links: [],
sessions: [{ id: 14018, name: "Sophia's Session" }],
questionAnswers: [],
})
assert.equal(matchSpeaker(speaker, 'sophia'), true)
assert.equal(matchSpeaker(speaker, 'contoso'), true)
assert.equal(matchSpeaker(speaker, 'nope'), false)
})
})
describe('package index', () => {
it('describes the documented export surface', () => {
const info = describeSessionize()
assert.equal(info.name, '@kody/sessionize')
assert.equal(info.demoEndpointId, 'jl4ktls0')
assert.ok(info.exports.some((item) => item.subpath === './get-event'))
})
})