Skip to content

Template api integration #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Refer to the [`examples`](examples) folder for the source code of this and other

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

### Templates API

- [Templates](examples/templates/everything.ts)

### Sending API

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

### Batch Sending API

- [Send a batch of transactional emails](examples/batch/transactional.ts)
- [Send a batch of bulk emails](examples/batch/bulk.ts)
- [Send a batch of sandbox emails](examples/batch/sandbox.ts)
- [Send a batch of emails from template](examples/batch/template.ts)
- [Transactional emails](examples/batch/transactional.ts)
- [Bulk emails](examples/batch/bulk.ts)
- [Sandbox emails](examples/batch/sandbox.ts)
- [Emails from template](examples/batch/template.ts)

### Email testing API

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

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

### Nodemailer Transport

Expand Down
44 changes: 44 additions & 0 deletions examples/templates/everything.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { MailtrapClient } from "mailtrap";

const TOKEN = "<YOUR-TOKEN-HERE>";
const ACCOUNT_ID = "<YOUR-ACCOUNT-ID-HERE>";

const client = new MailtrapClient({
token: TOKEN,
accountId: ACCOUNT_ID
});

async function templatesFlow() {
// Create a new template
const newTemplate = await client.templates.create({
name: "Welcome Email",
subject: "Welcome to Our Service!",
category: "Promotional",
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
body_text: "Welcome! Thank you for joining our service."
});
console.log("Created template:", newTemplate);

// Get all templates
const allTemplates = await client.templates.getList();
console.log("All templates:", allTemplates);

// Get a specific template
const template = await client.templates.get(newTemplate.id);
console.log("Template details:", template);

// Update the template
const updatedTemplate = await client.templates.update(newTemplate.id, {
name: "Updated Welcome Email",
subject: "Welcome to Our Amazing Service!",
body_html: "<h1>Welcome!</h1><p>Thank you for joining our amazing service.</p>"
});
console.log("Updated template:", updatedTemplate);

// Delete the template
await client.templates.delete(newTemplate.id);
console.log("Template deleted successfully");
}

templatesFlow().catch(console.error);

20 changes: 20 additions & 0 deletions src/__tests__/lib/api/Templates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import axios from "axios";

import TemplatesBaseAPI from "../../../lib/api/Templates";

describe("lib/api/Templates: ", () => {
const accountId = 100;
const templatesAPI = new TemplatesBaseAPI(axios, accountId);

describe("class TemplatesBaseAPI(): ", () => {
describe("init: ", () => {
it("initalizes with all necessary params.", () => {
expect(templatesAPI).toHaveProperty("create");
expect(templatesAPI).toHaveProperty("getList");
expect(templatesAPI).toHaveProperty("get");
expect(templatesAPI).toHaveProperty("update");
expect(templatesAPI).toHaveProperty("delete");
});
});
});
});
297 changes: 297 additions & 0 deletions src/__tests__/lib/api/resources/Templates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
import axios from "axios";
import AxiosMockAdapter from "axios-mock-adapter";

import TemplatesApi from "../../../../lib/api/resources/Templates";
import handleSendingError from "../../../../lib/axios-logger";
import MailtrapError from "../../../../lib/MailtrapError";
import {
Template,
TemplateCreateParams,
TemplateUpdateParams,
} from "../../../../types/api/templates";

import CONFIG from "../../../../config";

const { CLIENT_SETTINGS } = CONFIG;
const { GENERAL_ENDPOINT } = CLIENT_SETTINGS;

describe("lib/api/resources/Templates: ", () => {
let mock: AxiosMockAdapter;
const accountId = 100;
const templatesAPI = new TemplatesApi(axios, accountId);

const createTemplateRequest: TemplateCreateParams = {
name: "Welcome Email",
subject: "Welcome to Our Service!",
category: "Promotional",
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
body_text: "Welcome! Thank you for joining our service.",
};

const createTemplateResponse: Template = {
id: 1,
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
name: "Welcome Email",
subject: "Welcome to Our Service!",
category: "Promotional",
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
body_text: "Welcome! Thank you for joining our service.",
created_at: "2023-01-01T00:00:00Z",
updated_at: "2023-01-01T00:00:00Z",
};

const updateTemplateRequest: TemplateUpdateParams = {
name: "Updated Welcome Email",
subject: "Welcome to Our Amazing Service!",
body_html:
"<h1>Welcome!</h1><p>Thank you for joining our amazing service.</p>",
};

const updateTemplateResponse: Template = {
id: 1,
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
name: "Updated Welcome Email",
subject: "Welcome to Our Amazing Service!",
category: "Promotional",
body_html:
"<h1>Welcome!</h1><p>Thank you for joining our amazing service.</p>",
body_text: "Welcome! Thank you for joining our service.",
created_at: "2023-01-01T00:00:00Z",
updated_at: "2023-01-01T00:00:00Z",
};

describe("class TemplatesApi(): ", () => {
describe("init: ", () => {
it("initializes with all necessary params.", () => {
expect(templatesAPI).toHaveProperty("create");
expect(templatesAPI).toHaveProperty("update");
expect(templatesAPI).toHaveProperty("delete");
expect(templatesAPI).toHaveProperty("get");
expect(templatesAPI).toHaveProperty("getList");
});
});
});

beforeAll(() => {
axios.interceptors.response.use(
(response) => response.data,
handleSendingError
);
mock = new AxiosMockAdapter(axios);
});

afterEach(() => {
mock.reset();
});

describe("getList(): ", () => {
it("successfully gets all templates.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
const expectedResponseData: Template[] = [
{
id: 1,
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
name: "Welcome Email",
subject: "Welcome to Our Service!",
category: "Promotional",
body_html:
"<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
body_text: "Welcome! Thank you for joining our service.",
created_at: "2023-01-01T00:00:00Z",
updated_at: "2023-01-01T00:00:00Z",
},
{
id: 2,
uuid: "923e39db-c74a-4830-b037-0e6ba8b1fe89",
name: "Password Reset",
subject: "Reset Your Password",
category: "Transactional",
body_html:
"<h1>Password Reset</h1><p>Click here to reset your password.</p>",
body_text: "Password Reset. Click here to reset your password.",
created_at: "2023-01-01T00:00:00Z",
updated_at: "2023-01-01T00:00:00Z",
},
];

expect.assertions(2);

mock.onGet(endpoint).reply(200, expectedResponseData);
const result = await templatesAPI.getList();

expect(mock.history.get[0].url).toEqual(endpoint);
expect(result).toEqual(expectedResponseData);
});

it("fails with error.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
const expectedErrorMessage = "Request failed with status code 400";

expect.assertions(2);

mock.onGet(endpoint).reply(400, { error: expectedErrorMessage });

try {
await templatesAPI.getList();
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);
if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("get(): ", () => {
it("successfully gets a template by ID.", async () => {
const templateId = 1;
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
const expectedResponseData: Template = {
id: templateId,
uuid: "813e39db-c74a-4830-b037-0e6ba8b1fe88",
name: "Welcome Email",
subject: "Welcome to Our Service!",
category: "Promotional",
body_html: "<h1>Welcome!</h1><p>Thank you for joining our service.</p>",
body_text: "Welcome! Thank you for joining our service.",
created_at: "2023-01-01T00:00:00Z",
updated_at: "2023-01-01T00:00:00Z",
};

expect.assertions(2);

mock.onGet(endpoint).reply(200, expectedResponseData);
const result = await templatesAPI.get(templateId);

expect(mock.history.get[0].url).toEqual(endpoint);
expect(result).toEqual(expectedResponseData);
});

it("fails with error when getting a template.", async () => {
const templateId = 999;
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
const expectedErrorMessage = "Template not found";

expect.assertions(2);

mock.onGet(endpoint).reply(404, { error: expectedErrorMessage });

try {
await templatesAPI.get(templateId);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);
if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("create(): ", () => {
it("successfully creates a template.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
const expectedResponseData = createTemplateResponse;

expect.assertions(2);

mock
.onPost(endpoint, { email_template: createTemplateRequest })
.reply(200, expectedResponseData);
const result = await templatesAPI.create(createTemplateRequest);

expect(mock.history.post[0].url).toEqual(endpoint);
expect(result).toEqual(expectedResponseData);
});

it("fails with error.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates`;
const expectedErrorMessage = "Request failed with status code 400";

expect.assertions(2);

mock.onPost(endpoint).reply(400, { error: expectedErrorMessage });

try {
await templatesAPI.create(createTemplateRequest);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);
if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("update(): ", () => {
const templateId = 1;

it("successfully updates a template.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
const expectedResponseData = updateTemplateResponse;

expect.assertions(2);

mock
.onPatch(endpoint, { email_template: updateTemplateRequest })
.reply(200, expectedResponseData);
const result = await templatesAPI.update(
templateId,
updateTemplateRequest
);

expect(mock.history.patch[0].url).toEqual(endpoint);
expect(result).toEqual(expectedResponseData);
});

it("fails with error.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

mock.onPatch(endpoint).reply(404, { error: expectedErrorMessage });

try {
await templatesAPI.update(templateId, updateTemplateRequest);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);
if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("delete(): ", () => {
const templateId = 1;

it("successfully deletes a template.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;

expect.assertions(1);

mock.onDelete(endpoint).reply(204);
await templatesAPI.delete(templateId);

expect(mock.history.delete[0].url).toEqual(endpoint);
});

it("fails with error.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/email_templates/${templateId}`;
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

mock.onDelete(endpoint).reply(404, { error: expectedErrorMessage });

try {
await templatesAPI.delete(templateId);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);
if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});
});
Loading