Skip to content
Open
4 changes: 4 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export MAILTRAP_ACCOUNT_ID="op://Mailtrap Dev/Mailtrap SDK Dev API Key/account_id"
export MAILTRAP_ORGANIZATION_ID="op://Mailtrap Dev/Mailtrap SDK Dev API Key/organization_id"
export MAILTRAP_API_KEY="op://Mailtrap Dev/Mailtrap SDK Dev API Key/account_api_token"
export MAILTRAP_ORGANIZATION_API_KEY="op://Mailtrap Dev/Mailtrap SDK Dev API Key/organization_api_token"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ dist
node_modules
yarn-error.log
coverage
.idea/
11 changes: 11 additions & 0 deletions src/__tests__/lib/api/General.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ describe("lib/api/General: ", () => {
expect(generalAPI).toHaveProperty("accounts");
expect(generalAPI).toHaveProperty("permissions");
expect(generalAPI).toHaveProperty("billing");
expect(generalAPI).toHaveProperty("apiTokens");
});

it("lazily instantiates account-specific APIs via getters when accountId is provided.", () => {
expect(generalAPI.accountAccesses).toBeDefined();
expect(generalAPI.permissions).toBeDefined();
expect(generalAPI.billing).toBeDefined();
expect(generalAPI.accounts).toBeDefined();
expect(generalAPI.apiTokens).toBeDefined();
});
});

Expand Down Expand Up @@ -67,6 +69,15 @@ describe("lib/api/General: ", () => {
"Account ID is required for this operation. Please provide accountId when creating GeneralAPI instance."
);
});

it("throws error when accessing apiTokens without accountId.", () => {
expect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
generalAPI.apiTokens;
}).toThrow(
"Account ID is required for this operation. Please provide accountId when creating GeneralAPI instance."
);
});
});

describe("account discovery functionality: ", () => {
Expand Down
18 changes: 18 additions & 0 deletions src/__tests__/lib/api/Organizations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import axios from "axios";

import OrganizationsBaseAPI from "../../../lib/api/Organizations";

describe("lib/api/Organizations: ", () => {
const organizationId = 1001;
const organizationsAPI = new OrganizationsBaseAPI(axios, organizationId);

describe("class OrganizationsBaseAPI(): ", () => {
describe("init: ", () => {
it("exposes subAccounts resource.", () => {
expect(organizationsAPI).toHaveProperty("subAccounts");
expect(typeof organizationsAPI.subAccounts.getList).toBe("function");
expect(typeof organizationsAPI.subAccounts.create).toBe("function");
});
});
});
});
20 changes: 20 additions & 0 deletions src/__tests__/lib/api/Webhooks.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import axios from "axios";

import WebhooksBaseAPI from "../../../lib/api/Webhooks";

describe("lib/api/Webhooks: ", () => {
const accountId = 100;
const webhooksAPI = new WebhooksBaseAPI(axios, accountId);

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

import ApiTokensApi from "../../../../lib/api/resources/ApiTokens";
import handleSendingError from "../../../../lib/axios-logger";
import MailtrapError from "../../../../lib/MailtrapError";

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

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

describe("lib/api/resources/ApiTokens: ", () => {
let mock: AxiosMockAdapter;
const accountId = 100;
const apiTokensAPI = new ApiTokensApi(axios, accountId);

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

beforeAll(() => {
/**
* Init Axios interceptors for handling response.data, errors.
*/
axios.interceptors.response.use(
(response) => response.data,
handleSendingError
);
mock = new AxiosMockAdapter(axios);
});

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

describe("getList(): ", () => {
const responseData = [
{
id: 12345,
name: "My API Token",
last_4_digits: "x7k9",
created_by: "user@example.com",
expires_at: null,
resources: [
{
resource_type: "account",
resource_id: 3229,
access_level: 100,
},
],
},
];

it("gets the list of API tokens.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/api_tokens`;

expect.assertions(2);

mock.onGet(endpoint).reply(200, responseData);
const result = await apiTokensAPI.getList();

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

it("fails with error.", async () => {
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

try {
await apiTokensAPI.getList();
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);

if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("create(): ", () => {
const params = {
name: "My API Token",
resources: [
{
resource_type: "account" as const,
resource_id: 3229,
access_level: 100 as const,
},
],
};

const responseData = {
id: 12345,
name: "My API Token",
last_4_digits: "x7k9",
created_by: "user@example.com",
expires_at: null,
resources: [
{
resource_type: "account",
resource_id: 3229,
access_level: 100,
},
],
token: "a1b2c3d4e5f6",
};

it("creates an API token and returns the full token value.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/api_tokens`;

expect.assertions(3);

mock.onPost(endpoint, params).reply(200, responseData);
const result = await apiTokensAPI.create(params);

expect(mock.history.post[0].url).toEqual(endpoint);
expect(JSON.parse(mock.history.post[0].data)).toEqual(params);
expect(result).toEqual(responseData);
});

it("fails with error.", async () => {
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

try {
await apiTokensAPI.create(params);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);

if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("get(): ", () => {
const tokenId = 12345;
const responseData = {
id: tokenId,
name: "My API Token",
last_4_digits: "x7k9",
created_by: "user@example.com",
expires_at: null,
resources: [
{
resource_type: "account",
resource_id: 3229,
access_level: 100,
},
],
};

it("gets an API token by id.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/api_tokens/${tokenId}`;

expect.assertions(2);

mock.onGet(endpoint).reply(200, responseData);
const result = await apiTokensAPI.get(tokenId);

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

it("fails with error.", async () => {
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

try {
await apiTokensAPI.get(tokenId);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);

if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("reset(): ", () => {
const tokenId = 12345;
const responseData = {
id: tokenId,
name: "My API Token",
last_4_digits: "p3q4",
created_by: "user@example.com",
expires_at: null,
resources: [
{
resource_type: "account",
resource_id: 3229,
access_level: 100,
},
],
token: "newtokenvalue",
};

it("resets an API token and returns the new token value.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/api_tokens/${tokenId}/reset`;

expect.assertions(2);

mock.onPost(endpoint).reply(200, responseData);
const result = await apiTokensAPI.reset(tokenId);

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

it("fails with error.", async () => {
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

try {
await apiTokensAPI.reset(tokenId);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);

if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});

describe("delete(): ", () => {
const tokenId = 12345;

it("deletes an API token by id.", async () => {
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/api_tokens/${tokenId}`;

expect.assertions(1);

mock.onDelete(endpoint).reply(204);
await apiTokensAPI.delete(tokenId);

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

it("fails with error.", async () => {
const expectedErrorMessage = "Request failed with status code 404";

expect.assertions(2);

try {
await apiTokensAPI.delete(tokenId);
} catch (error) {
expect(error).toBeInstanceOf(MailtrapError);

if (error instanceof MailtrapError) {
expect(error.message).toEqual(expectedErrorMessage);
}
}
});
});
});
Loading
Loading