aboutsummaryrefslogtreecommitdiffstats
path: root/test/format.test.js
blob: 0eb5bf9503b3bea0c8bf66e21ef64c2d966d9856 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import test from 'node:test';
import { format } from '../src/format/index.js';
import { messages } from './fixtures.js';

// Validates with the Python mail parser (the same kind of strict parser MUAs use).
function parseMbox(text) {
    const py = `
import sys, json, mailbox, email.policy, tempfile, os
f = tempfile.NamedTemporaryFile('w', delete=False, suffix='.mbox'); f.write(sys.stdin.read()); f.close()
out = []
for m in mailbox.mbox(f.name, factory=lambda fp: email.message_from_binary_file(fp, policy=email.policy.default)):
    body = m.get_body(('plain',))
    atts = [(a.get_filename(), a.get_content_type(), len(a.get_content())) for a in m.iter_attachments()]
    out.append({k: str(m[k]) for k in ('From','To','Reply-To','Subject','Message-ID','In-Reply-To','X-WA-Id','X-WA-Chat-Name')} | {'body': body.get_content(), 'atts': atts, 'defects': [str(d) for d in m.defects]})
os.unlink(f.name)
print(json.dumps(out))`;
    return JSON.parse(execFileSync('python3', ['-c', py], { input: text, encoding: 'utf8' }));
}

test('mbox: headers, QP body, attachments and threads', () => {
    const parsed = parseMbox(format(messages, 'mbox') + '\n');
    assert.equal(parsed.length, 3);
    const [a, b, c] = parsed;

    assert.equal(a.From, 'Juan Pérez <5491122334455@c.us>');
    assert.equal(a['Message-ID'], '<3EB0AAA1@wa>');
    assert.equal(a.body.trimEnd(), messages[0].body);         // QP round trip, including the "From " line
    assert.match(a.Subject, /^Hola! ¿venís mañana\? 🎉$/);
    assert.deepEqual(a.defects, []);

    assert.equal(b['In-Reply-To'], '<3EB0AAA1@wa>');
    assert.equal(b.To, 'Juan Pérez <5491122334455@c.us>');
    assert.deepEqual(b.atts, [['captura año.png', 'image/png', 70]]);
    assert.equal(b.body.trimEnd(), 'la foto');

    assert.equal(c['Reply-To'], 'Familia <120363000000@g.us>');
    assert.equal(c.From, '5491133334444@c.us');
    assert.match(c.body, /attachment not downloaded: application\/pdf, 20 KB/);
    assert.equal(c['X-WA-Id'], messages[2].id);
});

test('eml: a single message; with several it asks for mbox', () => {
    assert.match(format(messages[0], 'eml'), /^From: =\?UTF-8\?B\?/);
    assert.throws(() => format(messages, 'eml'), /use --format mbox/);
    assert.throws(() => format([{ id: 1 }], 'mbox'), /only apply to messages/);
});

test('table / csv / yaml / text', () => {
    process.stdout.columns = 80;
    const t = format(messages, 'table', { columns: ['date', 'senderName', 'body'] });
    assert.ok(t.split('\n').every((l) => l.length <= 80), t);
    assert.match(t.split('\n')[0], /^DATE\s+SENDERNAME\s+BODY$/);

    const csv = format([{ a: 'x,y', b: 'di "hola"', c: { d: 1 } }], 'csv', { columns: ['a', 'b', 'c.d'] });
    assert.equal(csv, 'a,b,c.d\n"x,y","di ""hola""",1');

    assert.equal(format({ a: 'yes', b: [1, { c: 'x: y' }], e: {} }, 'yaml'), 'a: "yes"\nb:\n  - 1\n  - c: "x: y"\ne: {}');

    const txt = format(messages, 'text');
    assert.match(txt, /\] Juan Pérez: Hola!/);
    assert.match(txt, /\] me: ↩ \[image captura año.png\] la foto/);
    assert.match(txt, /\] 5491133334444@c.us: \[document boleta.pdf\]/);
    assert.equal(format({ x: 1 }, 'ndjson'), '{"x":1}');
});