Skip to content

Commit 6d5ba68

Browse files
Merge pull request #67 from railsware/template-api-integration
Template api integration
2 parents abaea8a + e092605 commit 6d5ba68

File tree

9 files changed

+548
-16
lines changed

9 files changed

+548
-16
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ Refer to the [`examples`](examples) folder for the source code of this and other
6767

6868
- [Contact Lists](examples/contact-lists/everything.ts)
6969

70+
### Templates API
71+
72+
- [Templates](examples/templates/everything.ts)
73+
7074
### Sending API
7175

7276
- [Advanced](examples/sending/everything.ts)
@@ -76,10 +80,10 @@ Refer to the [`examples`](examples) folder for the source code of this and other
7680

7781
### Batch Sending API
7882

79-
- [Send a batch of transactional emails](examples/batch/transactional.ts)
80-
- [Send a batch of bulk emails](examples/batch/bulk.ts)
81-
- [Send a batch of sandbox emails](examples/batch/sandbox.ts)
82-
- [Send a batch of emails from template](examples/batch/template.ts)
83+
- [Transactional emails](examples/batch/transactional.ts)
84+
- [Bulk emails](examples/batch/bulk.ts)
85+
- [Sandbox emails](examples/batch/sandbox.ts)
86+
- [Emails from template](examples/batch/template.ts)
8387

8488
### Email testing API
8589

@@ -92,6 +96,7 @@ Refer to the [`examples`](examples) folder for the source code of this and other
9296
### Bulk sending API
9397

9498
- [Send mail](examples/bulk/send-mail.ts)
99+
- [Nodemailer Transport](examples/bulk/transport.ts)
95100

96101
### Nodemailer Transport
97102

examples/templates/everything.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { MailtrapClient } from "mailtrap";
2+
3+
const TOKEN = "<YOUR-TOKEN-HERE>";
4+
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>";
5+
6+
const client = new MailtrapClient({
7+
token: TOKEN,
8+
accountId: ACCOUNT_ID
9+
});
10+
11+
async function templatesFlow() {
12+
// Create a new template
13+
const newTemplate = await client.templates.create({
14+
name: "Welcome Email",
15+
subject: "Welcome to Our Service!",
16+
category: "Promotional",
17+
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
18+
body_text: "Welcome! Thank you for joining our service."
19+
});
20+
console.log("Created template:", newTemplate);
21+
22+
// Get all templates
23+
const allTemplates = await client.templates.getList();
24+
console.log("All templates:", allTemplates);
25+
26+
// Get a specific template
27+
const template = await client.templates.get(newTemplate.id);
28+
console.log("Template details:", template);
29+
30+
// Update the template
31+
const updatedTemplate = await client.templates.update(newTemplate.id, {
32+
name: "Updated Welcome Email",
33+
subject: "Welcome to Our Amazing Service!",
34+
body_html: "<h1>Welcome!</h1><p>Thank you for joining our amazing service.</p>"
35+
});
36+
console.log("Updated template:", updatedTemplate);
37+
38+
// Delete the template
39+
await client.templates.delete(newTemplate.id);
40+
console.log("Template deleted successfully");
41+
}
42+
43+
templatesFlow().catch(console.error);
44+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import axios from "axios";
2+
3+
import TemplatesBaseAPI from "../../../lib/api/Templates";
4+
5+
describe("lib/api/Templates: ", () => {
6+
const accountId = 100;
7+
const templatesAPI = new TemplatesBaseAPI(axios, accountId);
8+
9+
describe("class TemplatesBaseAPI(): ", () => {
10+
describe("init: ", () => {
11+
it("initalizes with all necessary params.", () => {
12+
expect(templatesAPI).toHaveProperty("create");
13+
expect(templatesAPI).toHaveProperty("getList");
14+
expect(templatesAPI).toHaveProperty("get");
15+
expect(templatesAPI).toHaveProperty("update");
16+
expect(templatesAPI).toHaveProperty("delete");
17+
});
18+
});
19+
});
20+
});
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
import axios from "axios";
2+
import AxiosMockAdapter from "axios-mock-adapter";
3+
4+
import TemplatesApi from "../../../../lib/api/resources/Templates";
5+
import handleSendingError from "../../../../lib/axios-logger";
6+
import MailtrapError from "../../../../lib/MailtrapError";
7+
import {
8+
Template,
9+
TemplateCreateParams,
10+
TemplateUpdateParams,
11+
} from "../../../../types/api/templates";
12+
13+
import CONFIG from "../../../../config";
14+
15+
const { CLIENT_SETTINGS } = CONFIG;
16+
const { GENERAL_ENDPOINT } = CLIENT_SETTINGS;
17+
18+
describe("lib/api/resources/Templates: ", () => {
19+
let mock: AxiosMockAdapter;
20+
const accountId = 100;
21+
const templatesAPI = new TemplatesApi(axios, accountId);
22+
23+
const createTemplateRequest: TemplateCreateParams = {
24+
name: "Welcome Email",
25+
subject: "Welcome to Our Service!",
26+
category: "Promotional",
27+
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
28+
body_text: "Welcome! Thank you for joining our service.",
29+
};
30+
31+
const createTemplateResponse: Template = {
32+
id: 1,
33+
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
34+
name: "Welcome Email",
35+
subject: "Welcome to Our Service!",
36+
category: "Promotional",
37+
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
38+
body_text: "Welcome! Thank you for joining our service.",
39+
created_at: "2023-01-01T00:00:00Z",
40+
updated_at: "2023-01-01T00:00:00Z",
41+
};
42+
43+
const updateTemplateRequest: TemplateUpdateParams = {
44+
name: "Updated Welcome Email",
45+
subject: "Welcome to Our Amazing Service!",
46+
body_html:
47+
"<h1>Welcome!</h1><p>Thank you for joining our amazing service.</p>",
48+
};
49+
50+
const updateTemplateResponse: Template = {
51+
id: 1,
52+
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
53+
name: "Updated Welcome Email",
54+
subject: "Welcome to Our Amazing Service!",
55+
category: "Promotional",
56+
body_html:
57+
"<h1>Welcome!</h1><p>Thank you for joining our amazing service.</p>",
58+
body_text: "Welcome! Thank you for joining our service.",
59+
created_at: "2023-01-01T00:00:00Z",
60+
updated_at: "2023-01-01T00:00:00Z",
61+
};
62+
63+
describe("class TemplatesApi(): ", () => {
64+
describe("init: ", () => {
65+
it("initializes with all necessary params.", () => {
66+
expect(templatesAPI).toHaveProperty("create");
67+
expect(templatesAPI).toHaveProperty("update");
68+
expect(templatesAPI).toHaveProperty("delete");
69+
expect(templatesAPI).toHaveProperty("get");
70+
expect(templatesAPI).toHaveProperty("getList");
71+
});
72+
});
73+
});
74+
75+
beforeAll(() => {
76+
axios.interceptors.response.use(
77+
(response) => response.data,
78+
handleSendingError
79+
);
80+
mock = new AxiosMockAdapter(axios);
81+
});
82+
83+
afterEach(() => {
84+
mock.reset();
85+
});
86+
87+
describe("getList(): ", () => {
88+
it("successfully gets all templates.", async () => {
89+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
90+
const expectedResponseData: Template[] = [
91+
{
92+
id: 1,
93+
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
94+
name: "Welcome Email",
95+
subject: "Welcome to Our Service!",
96+
category: "Promotional",
97+
body_html:
98+
"<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
99+
body_text: "Welcome! Thank you for joining our service.",
100+
created_at: "2023-01-01T00:00:00Z",
101+
updated_at: "2023-01-01T00:00:00Z",
102+
},
103+
{
104+
id: 2,
105+
uuid: "923e39db-c74a-4830-b037-0e6ba8b1fe89",
106+
name: "Password Reset",
107+
subject: "Reset Your Password",
108+
category: "Transactional",
109+
body_html:
110+
"<h1>Password Reset</h1><p>Click here to reset your password.</p>",
111+
body_text: "Password Reset. Click here to reset your password.",
112+
created_at: "2023-01-01T00:00:00Z",
113+
updated_at: "2023-01-01T00:00:00Z",
114+
},
115+
];
116+
117+
expect.assertions(2);
118+
119+
mock.onGet(endpoint).reply(200, expectedResponseData);
120+
const result = await templatesAPI.getList();
121+
122+
expect(mock.history.get[0].url).toEqual(endpoint);
123+
expect(result).toEqual(expectedResponseData);
124+
});
125+
126+
it("fails with error.", async () => {
127+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
128+
const expectedErrorMessage = "Request failed with status code 400";
129+
130+
expect.assertions(2);
131+
132+
mock.onGet(endpoint).reply(400, { error: expectedErrorMessage });
133+
134+
try {
135+
await templatesAPI.getList();
136+
} catch (error) {
137+
expect(error).toBeInstanceOf(MailtrapError);
138+
if (error instanceof MailtrapError) {
139+
expect(error.message).toEqual(expectedErrorMessage);
140+
}
141+
}
142+
});
143+
});
144+
145+
describe("get(): ", () => {
146+
it("successfully gets a template by ID.", async () => {
147+
const templateId = 1;
148+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
149+
const expectedResponseData: Template = {
150+
id: templateId,
151+
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
152+
name: "Welcome Email",
153+
subject: "Welcome to Our Service!",
154+
category: "Promotional",
155+
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
156+
body_text: "Welcome! Thank you for joining our service.",
157+
created_at: "2023-01-01T00:00:00Z",
158+
updated_at: "2023-01-01T00:00:00Z",
159+
};
160+
161+
expect.assertions(2);
162+
163+
mock.onGet(endpoint).reply(200, expectedResponseData);
164+
const result = await templatesAPI.get(templateId);
165+
166+
expect(mock.history.get[0].url).toEqual(endpoint);
167+
expect(result).toEqual(expectedResponseData);
168+
});
169+
170+
it("fails with error when getting a template.", async () => {
171+
const templateId = 999;
172+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
173+
const expectedErrorMessage = "Template not found";
174+
175+
expect.assertions(2);
176+
177+
mock.onGet(endpoint).reply(404, { error: expectedErrorMessage });
178+
179+
try {
180+
await templatesAPI.get(templateId);
181+
} catch (error) {
182+
expect(error).toBeInstanceOf(MailtrapError);
183+
if (error instanceof MailtrapError) {
184+
expect(error.message).toEqual(expectedErrorMessage);
185+
}
186+
}
187+
});
188+
});
189+
190+
describe("create(): ", () => {
191+
it("successfully creates a template.", async () => {
192+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
193+
const expectedResponseData = createTemplateResponse;
194+
195+
expect.assertions(2);
196+
197+
mock
198+
.onPost(endpoint, { email_template: createTemplateRequest })
199+
.reply(200, expectedResponseData);
200+
const result = await templatesAPI.create(createTemplateRequest);
201+
202+
expect(mock.history.post[0].url).toEqual(endpoint);
203+
expect(result).toEqual(expectedResponseData);
204+
});
205+
206+
it("fails with error.", async () => {
207+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
208+
const expectedErrorMessage = "Request failed with status code 400";
209+
210+
expect.assertions(2);
211+
212+
mock.onPost(endpoint).reply(400, { error: expectedErrorMessage });
213+
214+
try {
215+
await templatesAPI.create(createTemplateRequest);
216+
} catch (error) {
217+
expect(error).toBeInstanceOf(MailtrapError);
218+
if (error instanceof MailtrapError) {
219+
expect(error.message).toEqual(expectedErrorMessage);
220+
}
221+
}
222+
});
223+
});
224+
225+
describe("update(): ", () => {
226+
const templateId = 1;
227+
228+
it("successfully updates a template.", async () => {
229+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
230+
const expectedResponseData = updateTemplateResponse;
231+
232+
expect.assertions(2);
233+
234+
mock
235+
.onPatch(endpoint, { email_template: updateTemplateRequest })
236+
.reply(200, expectedResponseData);
237+
const result = await templatesAPI.update(
238+
templateId,
239+
updateTemplateRequest
240+
);
241+
242+
expect(mock.history.patch[0].url).toEqual(endpoint);
243+
expect(result).toEqual(expectedResponseData);
244+
});
245+
246+
it("fails with error.", async () => {
247+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
248+
const expectedErrorMessage = "Request failed with status code 404";
249+
250+
expect.assertions(2);
251+
252+
mock.onPatch(endpoint).reply(404, { error: expectedErrorMessage });
253+
254+
try {
255+
await templatesAPI.update(templateId, updateTemplateRequest);
256+
} catch (error) {
257+
expect(error).toBeInstanceOf(MailtrapError);
258+
if (error instanceof MailtrapError) {
259+
expect(error.message).toEqual(expectedErrorMessage);
260+
}
261+
}
262+
});
263+
});
264+
265+
describe("delete(): ", () => {
266+
const templateId = 1;
267+
268+
it("successfully deletes a template.", async () => {
269+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
270+
271+
expect.assertions(1);
272+
273+
mock.onDelete(endpoint).reply(204);
274+
await templatesAPI.delete(templateId);
275+
276+
expect(mock.history.delete[0].url).toEqual(endpoint);
277+
});
278+
279+
it("fails with error.", async () => {
280+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
281+
const expectedErrorMessage = "Request failed with status code 404";
282+
283+
expect.assertions(2);
284+
285+
mock.onDelete(endpoint).reply(404, { error: expectedErrorMessage });
286+
287+
try {
288+
await templatesAPI.delete(templateId);
289+
} catch (error) {
290+
expect(error).toBeInstanceOf(MailtrapError);
291+
if (error instanceof MailtrapError) {
292+
expect(error.message).toEqual(expectedErrorMessage);
293+
}
294+
}
295+
});
296+
});
297+
});

0 commit comments

Comments
 (0)