summaryrefslogtreecommitdiff
path: root/tst/email.test.ts
blob: dfab0ff581b10afa0866522a6eca10f0812c4870 (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import { test, expect, jest } from '@jest/globals';
import { Email, Outbox, Inbox, IRecv, ISend } from '@emprespresso/uptime';
import { LogMetricTraceable, Either } from '@emprespresso/pengueno';
import { FetchMessageObject, MailboxLockObject } from 'imapflow';

const createMockRecv = (): IRecv => ({
    connect: jest.fn(),
    logout: jest.fn(),
    getMailboxLock: jest.fn(),
    mailboxClose: jest.fn(),
    fetchAll: jest.fn(),
    messageDelete: jest.fn(),
});

const createMockSend = (): ISend => ({
    sendMail: jest.fn(),
});

const from = {
    send_port: 465,
    email: 'test@localhost',
    username: 'test',
    password: 'password',
    send_host: 'localhost',
};

const to = {
    read_port: 993,
    email: 'test@localhost',
    username: 'test',
    password: 'password',
    read_host: 'localhost',
};

test('failure to send message goes left', async () => {
    const send = createMockSend();

    send.sendMail.mockRejectedValue(new Error('fail'));

    const outbox = new Outbox(send);

    const email = LogMetricTraceable.of<Email>({
        from: from.email,
        to: to.email,
        subject: 'test',
        text: 'test',
    });

    const result = await outbox.send(email);

    expect(result.left().present()).toBe(true);
    expect(result.left().get().message).toBe('fail');
});

test('goes left when message not ever received', async () => {
    const recv = createMockRecv();

    recv.fetchAll.mockResolvedValue([]);
    const lock: MailboxLockObject = { path: 'INBOX', release: jest.fn() };

    const inbox = new Inbox(recv, LogMetricTraceable.of(lock));

    const email = LogMetricTraceable.of<Email>({
        from: from.email,
        to: to.email,
        subject: 'test',
        text: 'test',
    });

    const result = await inbox.find(email);

    expect(result.left().present()).toBe(true);
});

test('releases lock on failure', async () => {
    const recv = createMockRecv();

    recv.fetchAll.mockResolvedValue([]);
    const lock: MailboxLockObject = { path: 'INBOX', release: jest.fn() };

    // Mock mailboxClose and logout to resolve properly
    recv.mailboxClose.mockResolvedValue(true);
    recv.logout.mockResolvedValue();

    const inbox = new Inbox(recv, LogMetricTraceable.of(lock));

    const email = LogMetricTraceable.of<Email>({
        from: from.email,
        to: to.email,
        subject: 'test',
        text: 'test',
    });

    await inbox.find(email);
    await inbox.close();

    expect(lock.release).toHaveBeenCalledTimes(1);
    expect(recv.mailboxClose).toHaveBeenCalledTimes(1);
    expect(recv.logout).toHaveBeenCalledTimes(1);
});