Skip to content

Commit 0e4e4e5

Browse files
authored
Merge pull request #9 from icdocsoc/feat-test-email
feat: test email mode
2 parents 371d764 + dd03b99 commit 0e4e4e5

File tree

6 files changed

+157
-34
lines changed

6 files changed

+157
-34
lines changed

CHANGELOG.md

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,38 @@
11
## 1.3.0 (2024-08-12)
22

3-
43
### 🩹 Fixes
54

6-
- ignore collection dirs ([d26eb66](https://github.com/icdocsoc/docsoc-tools/commit/d26eb66))
5+
- ignore collection dirs ([d26eb66](https://github.com/icdocsoc/docsoc-tools/commit/d26eb66))
6+
- Add --only & moving of drafts [396b645](https://github.com/icdocsoc/docsoc-tools/commit/396b645)
77

8-
### ❤️ Thank You
8+
### ❤️ Thank You
99

10-
- Kishan Sambhi @Gum-Joe
10+
- Kishan Sambhi @Gum-Joe
1111

1212
## 1.2.1 (2024-08-06)
1313

1414
This was a version bump only, there were no code changes.
1515

1616
## 1.2.0 (2024-08-06)
1717

18-
1918
### 🩹 Fixes
2019

21-
- build cli in place so oclif won't complain ([596a78c](https://github.com/icdocsoc/docsoc-tools/commit/596a78c))
22-
- tests breaking because ESM ([49823c9](https://github.com/icdocsoc/docsoc-tools/commit/49823c9))
20+
- build cli in place so oclif won't complain ([596a78c](https://github.com/icdocsoc/docsoc-tools/commit/596a78c))
21+
- tests breaking because ESM ([49823c9](https://github.com/icdocsoc/docsoc-tools/commit/49823c9))
2322

24-
### ❤️ Thank You
23+
### ❤️ Thank You
2524

26-
- Kishan Sambhi @Gum-Joe
25+
- Kishan Sambhi @Gum-Joe
2726

2827
## 1.1.2 (2024-08-06)
2928

30-
3129
### 🩹 Fixes
3230

33-
- add bin to mailmerge cli bundle ([8fec651](https://github.com/icdocsoc/docsoc-tools/commit/8fec651))
31+
- add bin to mailmerge cli bundle ([8fec651](https://github.com/icdocsoc/docsoc-tools/commit/8fec651))
3432

35-
### ❤️ Thank You
33+
### ❤️ Thank You
3634

37-
- Kishan Sambhi @Gum-Joe
35+
- Kishan Sambhi @Gum-Joe
3836

3937
## 1.1.1 (2024-08-06)
4038

@@ -46,20 +44,19 @@ This was a version bump only, there were no code changes.
4644

4745
# 1.0.0 (2024-08-06)
4846

49-
5047
### 🚀 Features
5148

52-
- scaffold up full preview renderer ([a41320e](https://github.com/icdocsoc/docsoc-tools/commit/a41320e))
53-
- rerendering of templates ([ea21d57](https://github.com/icdocsoc/docsoc-tools/commit/ea21d57))
54-
- init command fix: issue where nunjucks didn't pass it all ([5eb8b75](https://github.com/icdocsoc/docsoc-tools/commit/5eb8b75))
55-
- **nx:** Added Nx Cloud token to your nx.json ([646eb34](https://github.com/icdocsoc/docsoc-tools/commit/646eb34))
56-
- **nx:** Generated CI workflow ([abf6ea5](https://github.com/icdocsoc/docsoc-tools/commit/abf6ea5))
49+
- scaffold up full preview renderer ([a41320e](https://github.com/icdocsoc/docsoc-tools/commit/a41320e))
50+
- rerendering of templates ([ea21d57](https://github.com/icdocsoc/docsoc-tools/commit/ea21d57))
51+
- init command fix: issue where nunjucks didn't pass it all ([5eb8b75](https://github.com/icdocsoc/docsoc-tools/commit/5eb8b75))
52+
- **nx:** Added Nx Cloud token to your nx.json ([646eb34](https://github.com/icdocsoc/docsoc-tools/commit/646eb34))
53+
- **nx:** Generated CI workflow ([abf6ea5](https://github.com/icdocsoc/docsoc-tools/commit/abf6ea5))
5754

5855
### 🩹 Fixes
5956

60-
- throw error on undefined value ([15c45ab](https://github.com/icdocsoc/docsoc-tools/commit/15c45ab))
61-
- stop if uploaded ([ea0b979](https://github.com/icdocsoc/docsoc-tools/commit/ea0b979))
57+
- throw error on undefined value ([15c45ab](https://github.com/icdocsoc/docsoc-tools/commit/15c45ab))
58+
- stop if uploaded ([ea0b979](https://github.com/icdocsoc/docsoc-tools/commit/ea0b979))
6259

63-
### ❤️ Thank You
60+
### ❤️ Thank You
6461

65-
- Kishan Sambhi @Gum-Joe
62+
- Kishan Sambhi @Gum-Joe

email/mailmerge-cli/src/commands/send.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
getDefaultMailer,
55
getDefaultDoCSocFromLine,
66
ENGINES_MAP,
7+
EmailString,
8+
Mailer,
79
} from "@docsoc/mailmerge";
810
import { Args, Command, Flags } from "@oclif/core";
911

@@ -33,6 +35,10 @@ export default class Send extends Command {
3335
char: "n",
3436
description: "Only send this many emails (i.e. the first X emails)",
3537
}),
38+
testSendTo: Flags.string({
39+
char: "t",
40+
description: "Send the top X emails to this email as a test. Requires --only to be set",
41+
}),
3642
};
3743

3844
public async run(): Promise<void> {
@@ -44,6 +50,21 @@ export default class Send extends Command {
4450
/// @ts-expect-error: Required for fileNamer
4551
namer: (record) => record[DEFAULT_FIELD_NAMES.to],
4652
});
53+
54+
if (flags.testSendTo && !flags.only) {
55+
this.error("You must set --only to use --testSendTo");
56+
}
57+
58+
let testSendTo: EmailString | undefined;
59+
60+
if (flags.testSendTo) {
61+
if (Mailer.validateEmail(flags.testSendTo)) {
62+
testSendTo = flags.testSendTo;
63+
} else {
64+
throw new Error("Invalid email address provided for --testSendTo");
65+
}
66+
}
67+
4768
// Rerender previews
4869
await sendEmails(
4970
storageBackend,
@@ -54,6 +75,7 @@ export default class Send extends Command {
5475
{
5576
sleepBetween: flags.sleepBetween,
5677
onlySend: flags.only,
78+
testSendTo,
5779
},
5880
);
5981
}

email/mailmerge/src/pipelines/send.spec.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,84 @@ describe("sendEmails", () => {
123123
expect(mockMailer.sendMail).toHaveBeenCalledTimes(1);
124124
});
125125

126+
it("should send to test email if given and not cc or bcc anyone in", async () => {
127+
const mergeResults: MergeResultWithMetadata<unknown>[] = [
128+
{
129+
record: { field1: "value1" },
130+
/// @ts-expect-error: Mocking previews
131+
previews: ["preview"],
132+
engineInfo: { name: "testEngine", options: {} },
133+
email: {
134+
to: ["test@example.com"],
135+
subject: "Test Subject",
136+
cc: ["cc@cc.com"],
137+
bcc: ["bcc@bcc.com"],
138+
},
139+
attachmentPaths: [],
140+
},
141+
];
142+
(mockStorageBackend.loadMergeResults as jest.Mock).mockReturnValue(mergeResults);
143+
144+
const enginesMap = {
145+
testEngine: mockEngineConstructor,
146+
};
147+
148+
await sendEmails(
149+
mockStorageBackend,
150+
mockMailer,
151+
'"From" <from@example.com>',
152+
enginesMap,
153+
true,
154+
{
155+
onlySend: 1,
156+
testSendTo: "test@example.com",
157+
},
158+
);
159+
160+
expect(mockMailer.sendMail).toHaveBeenCalledWith(
161+
'"From" <from@example.com>',
162+
["test@example.com"],
163+
"(TEST) Test Subject",
164+
expect.any(String),
165+
[],
166+
{
167+
cc: [],
168+
bcc: [],
169+
},
170+
);
171+
});
172+
173+
it("should refuse test send if onlySend is not set", async () => {
174+
const mergeResults: MergeResultWithMetadata<unknown>[] = [
175+
{
176+
record: { field1: "value1" },
177+
/// @ts-expect-error: Mocking previews
178+
previews: ["preview"],
179+
engineInfo: { name: "testEngine", options: {} },
180+
email: { to: ["test@example.com"], subject: "Test Subject", cc: [], bcc: [] },
181+
attachmentPaths: [],
182+
},
183+
];
184+
(mockStorageBackend.loadMergeResults as jest.Mock).mockReturnValue(mergeResults);
185+
186+
const enginesMap = {
187+
testEngine: mockEngineConstructor,
188+
};
189+
190+
await expect(
191+
sendEmails(
192+
mockStorageBackend,
193+
mockMailer,
194+
'"From" <from@example.com>',
195+
enginesMap,
196+
true,
197+
{
198+
testSendTo: "test@example.com",
199+
},
200+
),
201+
).rejects.toThrow("You must set onlySend to a number to use test mode.");
202+
});
203+
126204
it("should send no emails if only send 0", async () => {
127205
const mergeResults: MergeResultWithMetadata<unknown>[] = [
128206
{

email/mailmerge/src/pipelines/send.ts

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ interface SendEmailsOptions {
1515
sleepBetween?: number;
1616
/** Only send this many emails (i.e. the first X emails) */
1717
onlySend?: number;
18+
/** Send the top {@link onlySend} emails to this email as a test */
19+
testSendTo?: EmailString;
1820
}
1921

2022
const DEFAULT_SLEEP_BETWEEN = 0;
@@ -53,6 +55,20 @@ export async function sendEmails(
5355
logger.info("Loading merge results...");
5456
const results = storageBackend.loadMergeResults();
5557

58+
if (options.testSendTo) {
59+
logger.warn("");
60+
logger.warn("=======================");
61+
logger.warn("TEST MODE ACTIVATED.");
62+
logger.warn("=======================");
63+
if (!options.onlySend) {
64+
logger.error("You must set onlySend to a number to use test mode.");
65+
throw new Error("You must set onlySend to a number to use test mode.");
66+
}
67+
logger.warn("");
68+
logger.warn(`Will send ${options.onlySend} emails to ${options.testSendTo} as a test.`);
69+
logger.warn("");
70+
}
71+
5672
// For each sidecar, send the previews
5773
const pendingEmails: {
5874
to: EmailString[];
@@ -83,21 +99,26 @@ export async function sendEmails(
8399

84100
// Add to pending emails
85101
pendingEmails.push({
86-
to: email.to,
87-
subject: email.subject,
102+
to: options.testSendTo ? [options.testSendTo] : email.to,
103+
subject: options.testSendTo ? "(TEST) " + email.subject : email.subject,
88104
html,
89105
attachments: attachmentPaths,
90-
cc: email.cc,
91-
bcc: email.bcc,
106+
cc: options.testSendTo ? [] : email.cc,
107+
bcc: options.testSendTo ? [] : email.bcc,
92108
originalResult: result,
93109
});
94110
}
95111

96112
// Print the warning
97113

114+
const emailsNumberDisplay = Math.min(
115+
pendingEmails.length,
116+
options.onlySend ?? Number.MAX_SAFE_INTEGER,
117+
);
118+
98119
console.log(
99120
chalk.yellow(`⚠️ --- WARNING --- ⚠️
100-
You are about to send ${pendingEmails.length} emails.
121+
You are about to send ${emailsNumberDisplay} emails.
101122
This action is IRREVERSIBLE.
102123
103124
If the system crashes, restarting will NOT necessarily send already-sent emails again.
@@ -108,8 +129,8 @@ Check that:
108129
3. You have tested the system beforehand
109130
4. All indications this is a test have been removed
110131
111-
You are about to send ${pendingEmails.length} emails. The esitmated time for this is ${
112-
((3 + (options.sleepBetween ?? DEFAULT_SLEEP_BETWEEN)) * pendingEmails.length) / 60 / 60
132+
You are about to send ${emailsNumberDisplay} emails. The esitmated time for this is ${
133+
((3 + (options.sleepBetween ?? DEFAULT_SLEEP_BETWEEN)) * emailsNumberDisplay) / 60 / 60
113134
} hours.
114135
115136
If you are happy to proceed, please type "Yes, send emails" below.`),
@@ -123,10 +144,15 @@ You are about to send ${pendingEmails.length} emails. The esitmated time for thi
123144

124145
// Send the emails
125146
logger.info("Sending emails...");
126-
const total = pendingEmails.length;
147+
const total = emailsNumberDisplay;
127148
let sent = 0;
128149
for (const { to, subject, html, attachments, cc, bcc, originalResult } of pendingEmails) {
129150
logger.info(`(${++sent} / ${total}) Sending email to ${to} with subject ${subject}...`);
151+
if (options.testSendTo && to[0] !== options.testSendTo) {
152+
throw new Error(
153+
"Test mode is on, but the email is not the test email! This is a bug in the code, crashing to prevent sending emails to the wrong person.",
154+
);
155+
}
130156
await mailer.sendMail(
131157
fromAddress,
132158
to,

email/workspace/data/names.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
name,to,subject,attachment1,attachment2,bcc,cc
2-
Kishan,kss22@ic.ac.uk kishansambhi@hotmail.co.uk,DoCSoc x Kishan,./attachments/DoCSoc Sponsorship Proposal 24-25.pdf,./attachments/munch.jpg,kishansambhi@hotmail.co.uk,jaskishansaran@gmail.com kishansambhi@outlook.com
2+
Kishan,kishansambhi@hotmail.co.uk,DoCSoc x Kishan,./attachments/DoCSoc Sponsorship Proposal 24-25.pdf,./attachments/munch.jpg,kishansambhi@hotmail.co.uk,jaskishansaran@gmail.com kishansambhi@outlook.com
33
NotKishan,kishansambhi@hotmail.co.uk," DoCSoc x NotKishan",./attachments/DoCSoc Sponsorship Proposal 24-25.pdf,./attachments/munch.jpg,,

email/workspace/quick-run.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
docsoc-mailmerge generate nunjucks ./data/names.csv -o ./output -n test -b -c
22
docsoc-mailmerge regenerate ./output/test
3-
docsoc-mailmerge upload-drafts ./output/test -y -s 2 -n 1
4-
docsoc-mailmerge send ./output/test -s 5 -n 1
3+
# docsoc-mailmerge upload-drafts ./output/test -y -s 2 -n 1
4+
docsoc-mailmerge send ./output/test -s 5 -n 2 -t "kss22@ic.ac.uk"

0 commit comments

Comments
 (0)