← Public packages
@kody/mailroom
Offline-first PWA for your Kody mailbox: sent and received threads, copy-prompt for agents, no send.
src/threads.node.test.ts
68 lines · 2.1 KB · TypeScriptimport assert from 'node:assert/strict'
import test from 'node:test'
import { filterThreads, groupMessages, threadKey } from './threads.ts'
import type { MailSummary } from './types.ts'
function msg(partial: Partial<MailSummary> & { id: string }): MailSummary {
return {
direction: 'inbound',
inbox_id: null,
thread_id: null,
from_address: 'ada@example.com',
envelope_from: 'ada@example.com',
to_addresses: ['me@kody.codes'],
subject: 'Hello',
message_id_header: null,
processing_status: 'stored',
classification: 'accepted',
delivery_status: null,
received_at: '2026-09-02T18:00:00.000Z',
sent_at: null,
created_at: '2026-09-02T18:00:00.000Z',
updated_at: '2026-09-02T18:00:00.000Z',
...partial,
}
}
test('groups by thread_id and keeps sent vs received separate', () => {
const messages = [
msg({ id: 'a', thread_id: 't1', subject: 'Hi', received_at: '2026-09-02T18:00:00.000Z' }),
msg({
id: 'b',
thread_id: 't1',
direction: 'outbound',
subject: 'Re: Hi',
from_address: 'me@kody.codes',
to_addresses: ['ada@example.com'],
received_at: null,
sent_at: '2026-09-02T18:05:00.000Z',
}),
msg({
id: 'c',
thread_id: 't1',
subject: 'Hi again',
received_at: '2026-09-02T18:10:00.000Z',
}),
msg({ id: 'd', thread_id: null, subject: 'Solo' }),
]
const received = groupMessages(messages, 'inbound')
const sent = groupMessages(messages, 'outbound')
assert.equal(received.length, 2)
assert.equal(received[0]?.id, 't1')
assert.equal(received[0]?.messageCount, 2)
assert.equal(received[0]?.subject, 'Hi again')
assert.equal(received[1]?.id, 'd')
assert.equal(sent.length, 1)
assert.equal(sent[0]?.direction, 'outbound')
assert.equal(threadKey(messages[3]!), 'd')
})
test('filterThreads matches subject and participants', () => {
const threads = groupMessages(
[msg({ id: 'a', subject: 'Invoice 42', from_address: 'billing@acme.test' })],
'inbound',
)
assert.equal(filterThreads(threads, 'invoice').length, 1)
assert.equal(filterThreads(threads, 'acme').length, 1)
assert.equal(filterThreads(threads, 'nope').length, 0)
})