Skip to content

Commit 1ad0109

Browse files
test: add comprehensive unit tests for ContactImportsApi class, covering create and get methods with various scenarios
1 parent 1622a36 commit 1ad0109

File tree

1 file changed

+251
-0
lines changed

1 file changed

+251
-0
lines changed
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
import axios from "axios";
2+
import AxiosMockAdapter from "axios-mock-adapter";
3+
4+
import ContactImportsApi from "../../../../lib/api/resources/ContactImports";
5+
import handleSendingError from "../../../../lib/axios-logger";
6+
import MailtrapError from "../../../../lib/MailtrapError";
7+
import {
8+
ContactImportResponse,
9+
ImportContactsRequest,
10+
} from "../../../../types/api/contact-imports";
11+
12+
import CONFIG from "../../../../config";
13+
14+
const { CLIENT_SETTINGS } = CONFIG;
15+
const { GENERAL_ENDPOINT } = CLIENT_SETTINGS;
16+
17+
describe("lib/api/resources/ContactImports: ", () => {
18+
let mock: AxiosMockAdapter;
19+
const accountId = 100;
20+
const contactImportsAPI = new ContactImportsApi(axios, accountId);
21+
22+
const createImportRequest: ImportContactsRequest = {
23+
contacts: [
24+
{
25+
26+
fields: {
27+
first_name: "John",
28+
last_name: "Doe",
29+
},
30+
list_ids_included: [1, 2],
31+
},
32+
{
33+
34+
fields: {
35+
first_name: "Jane",
36+
zip_code: 12345,
37+
},
38+
list_ids_excluded: [3],
39+
},
40+
],
41+
};
42+
43+
const createImportResponse: ContactImportResponse = {
44+
id: 1,
45+
status: "created",
46+
created_contacts_count: 2,
47+
updated_contacts_count: 0,
48+
contacts_over_limit_count: 0,
49+
};
50+
51+
const getImportResponse: ContactImportResponse = {
52+
id: 1,
53+
status: "finished",
54+
created_contacts_count: 2,
55+
updated_contacts_count: 0,
56+
contacts_over_limit_count: 0,
57+
};
58+
59+
describe("class ContactImportsApi(): ", () => {
60+
describe("init: ", () => {
61+
it("initializes with all necessary params.", () => {
62+
expect(contactImportsAPI).toHaveProperty("create");
63+
expect(contactImportsAPI).toHaveProperty("get");
64+
});
65+
});
66+
});
67+
68+
beforeAll(() => {
69+
axios.interceptors.response.use(
70+
(response) => response.data,
71+
handleSendingError
72+
);
73+
mock = new AxiosMockAdapter(axios);
74+
});
75+
76+
afterEach(() => {
77+
mock.reset();
78+
});
79+
80+
describe("create(): ", () => {
81+
it("successfully creates a contact import.", async () => {
82+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports`;
83+
const expectedResponseData = createImportResponse;
84+
85+
expect.assertions(2);
86+
87+
mock
88+
.onPost(endpoint, createImportRequest)
89+
.reply(200, expectedResponseData);
90+
const result = await contactImportsAPI.create(createImportRequest);
91+
92+
expect(mock.history.post[0].url).toEqual(endpoint);
93+
expect(result).toEqual(expectedResponseData);
94+
});
95+
96+
it("successfully creates a contact import with minimal data.", async () => {
97+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports`;
98+
const minimalRequest: ImportContactsRequest = {
99+
contacts: [
100+
{
101+
102+
},
103+
],
104+
};
105+
const expectedResponseData: ContactImportResponse = {
106+
id: 2,
107+
status: "created",
108+
};
109+
110+
expect.assertions(2);
111+
112+
mock.onPost(endpoint, minimalRequest).reply(200, expectedResponseData);
113+
const result = await contactImportsAPI.create(minimalRequest);
114+
115+
expect(mock.history.post[0].url).toEqual(endpoint);
116+
expect(result).toEqual(expectedResponseData);
117+
});
118+
119+
it("fails with error.", async () => {
120+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports`;
121+
const expectedErrorMessage = "Request failed with status code 400";
122+
123+
expect.assertions(2);
124+
125+
mock.onPost(endpoint).reply(400, { error: expectedErrorMessage });
126+
127+
try {
128+
await contactImportsAPI.create(createImportRequest);
129+
} catch (error) {
130+
expect(error).toBeInstanceOf(MailtrapError);
131+
if (error instanceof MailtrapError) {
132+
expect(error.message).toEqual(expectedErrorMessage);
133+
}
134+
}
135+
});
136+
137+
it("fails with validation error.", async () => {
138+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports`;
139+
const invalidRequest: ImportContactsRequest = {
140+
contacts: [
141+
{
142+
email: "invalid-email",
143+
},
144+
],
145+
};
146+
const expectedErrorMessage = "Invalid email format";
147+
148+
expect.assertions(2);
149+
150+
mock.onPost(endpoint).reply(422, { error: expectedErrorMessage });
151+
152+
try {
153+
await contactImportsAPI.create(invalidRequest);
154+
} catch (error) {
155+
expect(error).toBeInstanceOf(MailtrapError);
156+
if (error instanceof MailtrapError) {
157+
expect(error.message).toEqual(expectedErrorMessage);
158+
}
159+
}
160+
});
161+
162+
it("fails with array of validation errors.", async () => {
163+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports`;
164+
const invalidRequest: ImportContactsRequest = {
165+
contacts: [
166+
{
167+
email: "invalid-email-1",
168+
},
169+
{
170+
email: "invalid-email-2",
171+
},
172+
],
173+
};
174+
175+
expect.assertions(2);
176+
177+
// API returns errors as an array in data.errors
178+
mock.onPost(endpoint).reply(422, {
179+
errors: {
180+
name: ["is invalid", "is required"],
181+
base: ["Contact limit exceeded"],
182+
},
183+
});
184+
185+
try {
186+
await contactImportsAPI.create(invalidRequest);
187+
} catch (error) {
188+
expect(error).toBeInstanceOf(MailtrapError);
189+
if (error instanceof MailtrapError) {
190+
// axios-logger joins name errors with ", "
191+
expect(error.message).toBe("is invalid, is required");
192+
}
193+
}
194+
});
195+
});
196+
197+
describe("get(): ", () => {
198+
it("successfully gets a contact import by ID.", async () => {
199+
const importId = 1;
200+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports/${importId}`;
201+
const expectedResponseData = getImportResponse;
202+
203+
expect.assertions(2);
204+
205+
mock.onGet(endpoint).reply(200, expectedResponseData);
206+
const result = await contactImportsAPI.get(importId);
207+
208+
expect(mock.history.get[0].url).toEqual(endpoint);
209+
expect(result).toEqual(expectedResponseData);
210+
});
211+
212+
it("successfully gets a contact import with all status fields.", async () => {
213+
const importId = 2;
214+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports/${importId}`;
215+
const expectedResponseData: ContactImportResponse = {
216+
id: importId,
217+
status: "failed",
218+
created_contacts_count: 5,
219+
updated_contacts_count: 3,
220+
contacts_over_limit_count: 2,
221+
};
222+
223+
expect.assertions(2);
224+
225+
mock.onGet(endpoint).reply(200, expectedResponseData);
226+
const result = await contactImportsAPI.get(importId);
227+
228+
expect(mock.history.get[0].url).toEqual(endpoint);
229+
expect(result).toEqual(expectedResponseData);
230+
});
231+
232+
it("fails with error when getting a contact import.", async () => {
233+
const importId = 999;
234+
const endpoint = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/contacts/imports/${importId}`;
235+
const expectedErrorMessage = "Contact import not found";
236+
237+
expect.assertions(2);
238+
239+
mock.onGet(endpoint).reply(404, { error: expectedErrorMessage });
240+
241+
try {
242+
await contactImportsAPI.get(importId);
243+
} catch (error) {
244+
expect(error).toBeInstanceOf(MailtrapError);
245+
if (error instanceof MailtrapError) {
246+
expect(error.message).toEqual(expectedErrorMessage);
247+
}
248+
}
249+
});
250+
});
251+
});

0 commit comments

Comments
 (0)