Golden-master tests pinning the CURRENT behavior of high-value modules that had no coverage — integration seams, security helpers, two API route handlers, and complex pure utils. 111 tests across 12 files. New tests: - auth-crypto / session-cookie: AES-256-GCM session encryption roundtrip, tamper/version/missing-secret handling; cookie-slot naming. - unified-mailbox: multi-account fan-out, sort, totals, per-account error isolation, personal-vs-shared JMAP target resolution, counts/roles. - account-state-manager: snapshot/restore across the six real Zustand stores; clearAllStores reset shape; evict. - mdn: RFC 5322 MDN assembly (CRLF, RFC2047, base64 wrap, headers). - tnef: winmail.dat binary parsing from hand-built fixtures. - download-filename / subject-prefix / birthday-calendar / eml-import: filename templating, multilingual prefix stripping, birthday event generation, .eml/.zip import. - webdav / caldav-discover route handlers: auth guards, path validation, upstream URL construction, candidate probing. - helpers/factories.ts: shared makeEmail/makeMailbox/makeFakeJmapClient. Tests follow the repo's existing patterns (route-import, fake IJMAPClient, fetch spy, real store singletons). Where current behavior looks buggy it is pinned and flagged with a // CHARACTERISATION: comment (see PR for the suspected-bugs list); no production code is changed.
113 lines
4.2 KiB
TypeScript
113 lines
4.2 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
import { parseTnef, isTnefAttachment } from '@/lib/tnef';
|
|
|
|
vi.mock('@/lib/debug', () => ({
|
|
debug: { group: () => {}, groupEnd: () => {}, log: () => {}, warn: () => {}, table: () => {} },
|
|
}));
|
|
|
|
// ── tiny little-endian writer mirroring the parser's BinaryReader ─────────────
|
|
class W {
|
|
private bytes: number[] = [];
|
|
u8(n: number) { this.bytes.push(n & 0xff); return this; }
|
|
u16(n: number) { return this.u8(n).u8(n >>> 8); }
|
|
u32(n: number) { return this.u8(n).u8(n >>> 8).u8(n >>> 16).u8(n >>> 24); }
|
|
raw(arr: number[]) { for (const b of arr) this.u8(b); return this; }
|
|
build() { return new Uint8Array(this.bytes); }
|
|
}
|
|
|
|
const TNEF_SIGNATURE = 0x223e9f78;
|
|
const LVL_MESSAGE = 0x01;
|
|
const LVL_ATTACHMENT = 0x02;
|
|
const attBody = 0x0002800c;
|
|
const attMAPIProps = 0x00069003;
|
|
const attAttachRenddata = 0x00069002;
|
|
const attAttachData = 0x0006800f;
|
|
const attAttachTitle = 0x00018010;
|
|
const PR_BODY_HTML = 0x1013;
|
|
const PT_STRING8 = 0x001e;
|
|
|
|
const enc = (s: string) => [...new TextEncoder().encode(s)];
|
|
|
|
function header(w: W) { return w.u32(TNEF_SIGNATURE).u16(0); }
|
|
|
|
function record(w: W, level: number, attrID: number, data: number[]) {
|
|
w.u8(level).u32(attrID).u32(data.length).raw(data).u16(0); // ...data + 2-byte checksum
|
|
return w;
|
|
}
|
|
|
|
/** One length-prefixed STRING8 MAPI property block. */
|
|
function mapiStringProp(propID: number, str: string): number[] {
|
|
const w = new W();
|
|
w.u32(1); // property count
|
|
w.u16(PT_STRING8).u16(propID);
|
|
const val = enc(str);
|
|
w.u32(1); // value count
|
|
w.u32(val.length).raw(val);
|
|
for (let i = 0; i < (4 - (val.length % 4)) % 4; i++) w.u8(0); // pad to 4
|
|
return [...w.build()];
|
|
}
|
|
|
|
describe('parseTnef', () => {
|
|
it('returns an empty result for data smaller than 6 bytes', () => {
|
|
expect(parseTnef(new Uint8Array([1, 2, 3]))).toEqual({ body: null, htmlBody: null, attachments: [] });
|
|
});
|
|
|
|
it('returns an empty result for an invalid signature', () => {
|
|
const buf = new W().u32(0xdeadbeef).u16(0).build();
|
|
expect(parseTnef(buf)).toEqual({ body: null, htmlBody: null, attachments: [] });
|
|
});
|
|
|
|
it('extracts a plain-text body from an attBody attribute', () => {
|
|
const w = header(new W());
|
|
record(w, LVL_MESSAGE, attBody, enc('Hello body'));
|
|
const r = parseTnef(w.build());
|
|
expect(r.body).toBe('Hello body');
|
|
expect(r.htmlBody).toBeNull();
|
|
expect(r.attachments).toEqual([]);
|
|
});
|
|
|
|
it('extracts an HTML body from PR_BODY_HTML in MAPI props', () => {
|
|
const w = header(new W());
|
|
record(w, LVL_MESSAGE, attMAPIProps, mapiStringProp(PR_BODY_HTML, '<b>hi</b> |