mailisk 2.0.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/test.yml +31 -0
- package/README.md +122 -22
- package/dist/index.d.ts +169 -11
- package/dist/index.js +49 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -6
- package/dist/index.mjs.map +1 -1
- package/jest.config.js +13 -0
- package/package.json +11 -3
- package/private/dist/private/index.js +28 -0
- package/private/dist/private/index.js.map +1 -0
- package/private/dist/src/mailisk.interfaces.js +3 -0
- package/private/dist/src/mailisk.interfaces.js.map +1 -0
- package/private/dist/src/mailisk.js +168 -0
- package/private/dist/src/mailisk.js.map +1 -0
- package/private/index.ts +17 -0
- package/private/node_modules/.package-lock.json +44 -0
- package/private/node_modules/typescript/LICENSE.txt +55 -0
- package/private/node_modules/typescript/README.md +50 -0
- package/private/node_modules/typescript/SECURITY.md +41 -0
- package/private/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
- package/private/node_modules/typescript/bin/tsc +2 -0
- package/private/node_modules/typescript/bin/tsserver +2 -0
- package/private/node_modules/typescript/lib/_tsc.js +133818 -0
- package/private/node_modules/typescript/lib/_tsserver.js +659 -0
- package/private/node_modules/typescript/lib/_typingsInstaller.js +222 -0
- package/private/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/lib.d.ts +22 -0
- package/private/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
- package/private/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
- package/private/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
- package/private/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
- package/private/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
- package/private/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
- package/private/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
- package/private/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
- package/private/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
- package/private/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
- package/private/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
- package/private/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
- package/private/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
- package/private/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
- package/private/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/private/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
- package/private/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
- package/private/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
- package/private/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
- package/private/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
- package/private/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
- package/private/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
- package/private/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
- package/private/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
- package/private/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
- package/private/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
- package/private/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
- package/private/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
- package/private/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
- package/private/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
- package/private/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
- package/private/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
- package/private/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
- package/private/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
- package/private/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
- package/private/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
- package/private/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
- package/private/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
- package/private/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
- package/private/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
- package/private/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
- package/private/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
- package/private/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
- package/private/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
- package/private/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
- package/private/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/private/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
- package/private/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
- package/private/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
- package/private/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
- package/private/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
- package/private/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
- package/private/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
- package/private/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
- package/private/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
- package/private/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
- package/private/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
- package/private/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
- package/private/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
- package/private/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
- package/private/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
- package/private/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
- package/private/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
- package/private/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
- package/private/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
- package/private/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
- package/private/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
- package/private/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
- package/private/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
- package/private/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
- package/private/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
- package/private/node_modules/typescript/lib/lib.es6.d.ts +23 -0
- package/private/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
- package/private/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
- package/private/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
- package/private/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
- package/private/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
- package/private/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.esnext.float16.d.ts +445 -0
- package/private/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
- package/private/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
- package/private/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
- package/private/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
- package/private/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
- package/private/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
- package/private/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
- package/private/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
- package/private/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
- package/private/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
- package/private/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/tsc.js +8 -0
- package/private/node_modules/typescript/lib/tsserver.js +8 -0
- package/private/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
- package/private/node_modules/typescript/lib/tsserverlibrary.js +21 -0
- package/private/node_modules/typescript/lib/typesMap.json +497 -0
- package/private/node_modules/typescript/lib/typescript.d.ts +11437 -0
- package/private/node_modules/typescript/lib/typescript.js +200276 -0
- package/private/node_modules/typescript/lib/typingsInstaller.js +8 -0
- package/private/node_modules/typescript/lib/watchGuard.js +53 -0
- package/private/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
- package/private/node_modules/typescript/package.json +120 -0
- package/private/package-lock.json +53 -0
- package/private/package.json +17 -0
- package/private/tsconfig.json +103 -0
- package/src/mailisk.interfaces.ts +123 -6
- package/src/mailisk.ts +120 -11
- package/tests/mocks/axios-mocks.ts +108 -0
- package/tests/setup.ts +21 -0
- package/tests/unit/mailisk.test.ts +480 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Mock namespace response data
|
|
2
|
+
export const mockNamespacesResponse = {
|
|
3
|
+
total_count: 1,
|
|
4
|
+
data: [
|
|
5
|
+
{
|
|
6
|
+
id: "0fde5afa-a8a8-41a4-9ca4-21d83efc37d8",
|
|
7
|
+
namespace: "test-namespace",
|
|
8
|
+
expires_at: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// Mock email response data
|
|
14
|
+
export const mockEmailsResponse = {
|
|
15
|
+
total_count: 1,
|
|
16
|
+
options: {
|
|
17
|
+
wait: true,
|
|
18
|
+
},
|
|
19
|
+
data: [
|
|
20
|
+
{
|
|
21
|
+
id: "1763808382384-m-m-dEmYI7ic5",
|
|
22
|
+
from: {
|
|
23
|
+
address: "sender@example.com",
|
|
24
|
+
name: "Sender",
|
|
25
|
+
},
|
|
26
|
+
to: [
|
|
27
|
+
{
|
|
28
|
+
address: "recipient@test-namespace.mailisk.net",
|
|
29
|
+
name: "Recipient",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
subject: "test",
|
|
33
|
+
html: "false",
|
|
34
|
+
text: "test",
|
|
35
|
+
received_date: "2025-11-22T10:46:22.000Z",
|
|
36
|
+
received_timestamp: 1763808382,
|
|
37
|
+
expires_timestamp: 1764672382,
|
|
38
|
+
spam_score: null,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Mock attachment response data
|
|
44
|
+
export const mockAttachmentResponse = {
|
|
45
|
+
data: {
|
|
46
|
+
id: "b04730be-9c13-4f23-a2b7-a4a9a943cd31",
|
|
47
|
+
filename: "Sample.png",
|
|
48
|
+
content_type: "image/png",
|
|
49
|
+
size: 140551,
|
|
50
|
+
expires_at: "2025-09-09T10:03:33.000Z",
|
|
51
|
+
download_url: "url",
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Mock SMTP settings response
|
|
56
|
+
export const mockSmtpSettingsResponse = {
|
|
57
|
+
data: {
|
|
58
|
+
host: "smtp.mailisk.net",
|
|
59
|
+
port: 587,
|
|
60
|
+
username: "test-namespace",
|
|
61
|
+
password: "mock-password",
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Mock SMS messages response data
|
|
66
|
+
export const mockSmsMessagesResponse = {
|
|
67
|
+
total_count: 1,
|
|
68
|
+
options: {
|
|
69
|
+
limit: 20,
|
|
70
|
+
offset: 0,
|
|
71
|
+
},
|
|
72
|
+
data: [
|
|
73
|
+
{
|
|
74
|
+
id: "37a2bc57-c2c7-4c08-a9dc-d143bc17643f",
|
|
75
|
+
sms_phone_number_id: "ba548be2-bff9-4e3f-a54b-e034c415e906",
|
|
76
|
+
body: "test newline \\n\\n test2",
|
|
77
|
+
from_number: "+18777804236",
|
|
78
|
+
to_number: "+19285639871",
|
|
79
|
+
provider_message_id: "SMf72eb72b6281a02e60a0114f38e34e36",
|
|
80
|
+
created_at: "2020-11-24T16:48:22.170Z",
|
|
81
|
+
direction: "inbound",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Mock SMS numbers response data
|
|
87
|
+
export const mockSmsNumbersResponse = {
|
|
88
|
+
total_count: 2,
|
|
89
|
+
data: [
|
|
90
|
+
{
|
|
91
|
+
id: "13c4551e-a5be-4959-9ea5-82931dcfc74d",
|
|
92
|
+
organisation_id: "c02bdb84-22df-4c18-85ba-2defdd04eccb",
|
|
93
|
+
status: "requested",
|
|
94
|
+
country: "US",
|
|
95
|
+
created_at: "2020-11-22T16:59:25.462Z",
|
|
96
|
+
updated_at: "2020-11-22T16:59:25.462Z",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
id: "6bf073d6-d333-45c9-b009-c77f0cac7657",
|
|
100
|
+
organisation_id: "ddec2c7b-b087-45b6-a81d-b195f25d457f",
|
|
101
|
+
status: "active",
|
|
102
|
+
country: "US",
|
|
103
|
+
phone_number: "+19285639871",
|
|
104
|
+
created_at: "2020-11-22T16:41:40.329Z",
|
|
105
|
+
updated_at: "2020-11-22T16:41:40.329Z",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
package/tests/setup.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import dotenv from "dotenv";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
dotenv.config({ path: path.resolve(process.cwd(), ".env.test") });
|
|
5
|
+
|
|
6
|
+
jest.setTimeout(10000);
|
|
7
|
+
|
|
8
|
+
process.env.TEST_MODE = "true";
|
|
9
|
+
|
|
10
|
+
export const createTestClient = (mockResponses = {}) => {
|
|
11
|
+
const { MailiskClient } = require("../src/mailisk");
|
|
12
|
+
|
|
13
|
+
return new MailiskClient({
|
|
14
|
+
apiKey: "test-api-key",
|
|
15
|
+
baseUrl: "https://test-api.mailisk.com/",
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
jest.resetAllMocks();
|
|
21
|
+
});
|
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
jest.mock("axios");
|
|
2
|
+
jest.mock("nodemailer");
|
|
3
|
+
|
|
4
|
+
import axios from "axios";
|
|
5
|
+
import nodemailer from "nodemailer";
|
|
6
|
+
import { MailiskClient } from "../../src/mailisk";
|
|
7
|
+
import {
|
|
8
|
+
mockNamespacesResponse,
|
|
9
|
+
mockEmailsResponse,
|
|
10
|
+
mockSmtpSettingsResponse,
|
|
11
|
+
mockAttachmentResponse,
|
|
12
|
+
mockSmsMessagesResponse,
|
|
13
|
+
mockSmsNumbersResponse,
|
|
14
|
+
} from "../mocks/axios-mocks";
|
|
15
|
+
|
|
16
|
+
const setupMockAxios = () => {
|
|
17
|
+
jest.clearAllMocks();
|
|
18
|
+
|
|
19
|
+
const mockGet = jest.fn();
|
|
20
|
+
const mockPost = jest.fn();
|
|
21
|
+
const mockPut = jest.fn();
|
|
22
|
+
const mockDelete = jest.fn();
|
|
23
|
+
|
|
24
|
+
const mockInstance = {
|
|
25
|
+
get: mockGet,
|
|
26
|
+
post: mockPost,
|
|
27
|
+
put: mockPut,
|
|
28
|
+
delete: mockDelete,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
(axios.create as jest.Mock).mockReturnValue(mockInstance);
|
|
32
|
+
(axios.get as jest.Mock).mockImplementation(jest.fn());
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
mockInstance,
|
|
36
|
+
mockGet,
|
|
37
|
+
mockPost,
|
|
38
|
+
mockPut,
|
|
39
|
+
mockDelete,
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
describe("MailiskClient", () => {
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
jest.clearAllMocks();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
describe("constructor", () => {
|
|
49
|
+
it("should initialize with default baseURL when not provided", () => {
|
|
50
|
+
setupMockAxios();
|
|
51
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
52
|
+
expect(axios.create).toHaveBeenCalledWith({
|
|
53
|
+
headers: {
|
|
54
|
+
"X-Api-Key": "test-key",
|
|
55
|
+
},
|
|
56
|
+
baseURL: "https://api.mailisk.com/",
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("should initialize with custom baseURL when provided", () => {
|
|
61
|
+
setupMockAxios();
|
|
62
|
+
const client = new MailiskClient({
|
|
63
|
+
apiKey: "test-key",
|
|
64
|
+
baseUrl: "https://custom-api.mailisk.com/",
|
|
65
|
+
});
|
|
66
|
+
expect(axios.create).toHaveBeenCalledWith({
|
|
67
|
+
headers: {
|
|
68
|
+
"X-Api-Key": "test-key",
|
|
69
|
+
},
|
|
70
|
+
baseURL: "https://custom-api.mailisk.com/",
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe("listNamespaces", () => {
|
|
76
|
+
it("should fetch and return namespaces", async () => {
|
|
77
|
+
const { mockGet } = setupMockAxios();
|
|
78
|
+
mockGet.mockResolvedValueOnce({ data: mockNamespacesResponse });
|
|
79
|
+
|
|
80
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
81
|
+
const result = await client.listNamespaces();
|
|
82
|
+
|
|
83
|
+
expect(mockGet).toHaveBeenCalledWith("api/namespaces");
|
|
84
|
+
expect(result).toEqual(mockNamespacesResponse);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should handle errors correctly", async () => {
|
|
88
|
+
const { mockGet } = setupMockAxios();
|
|
89
|
+
const error = new Error("API Error");
|
|
90
|
+
mockGet.mockRejectedValueOnce(error);
|
|
91
|
+
|
|
92
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
93
|
+
|
|
94
|
+
await expect(client.listNamespaces()).rejects.toThrow("API Error");
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
describe("getSmtpSettings", () => {
|
|
99
|
+
it("should fetch and return SMTP settings for a namespace", async () => {
|
|
100
|
+
const { mockGet } = setupMockAxios();
|
|
101
|
+
mockGet.mockResolvedValueOnce({ data: mockSmtpSettingsResponse });
|
|
102
|
+
|
|
103
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
104
|
+
const result = await client.getSmtpSettings("test-namespace");
|
|
105
|
+
|
|
106
|
+
expect(mockGet).toHaveBeenCalledWith("api/smtp/test-namespace");
|
|
107
|
+
expect(result).toEqual(mockSmtpSettingsResponse);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should handle errors correctly", async () => {
|
|
111
|
+
const { mockGet } = setupMockAxios();
|
|
112
|
+
const error = new Error("SMTP Settings Error");
|
|
113
|
+
mockGet.mockRejectedValueOnce(error);
|
|
114
|
+
|
|
115
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
116
|
+
|
|
117
|
+
await expect(client.getSmtpSettings("test-namespace")).rejects.toThrow("SMTP Settings Error");
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
describe("getAttachment", () => {
|
|
122
|
+
it("should fetch and return attachment data", async () => {
|
|
123
|
+
const { mockGet } = setupMockAxios();
|
|
124
|
+
mockGet.mockResolvedValueOnce({ data: mockAttachmentResponse });
|
|
125
|
+
|
|
126
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
127
|
+
const result = await client.getAttachment("attachment-123");
|
|
128
|
+
|
|
129
|
+
expect(mockGet).toHaveBeenCalledWith("api/attachments/attachment-123");
|
|
130
|
+
expect(result).toEqual(mockAttachmentResponse);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("downloadAttachment", () => {
|
|
135
|
+
it("should download and return attachment data", async () => {
|
|
136
|
+
const getAttachmentSpy = jest.spyOn(MailiskClient.prototype, "getAttachment");
|
|
137
|
+
getAttachmentSpy.mockResolvedValueOnce(mockAttachmentResponse);
|
|
138
|
+
|
|
139
|
+
const mockBuffer = Buffer.from("test content");
|
|
140
|
+
(axios.get as jest.Mock).mockResolvedValueOnce({ data: mockBuffer });
|
|
141
|
+
|
|
142
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
143
|
+
const result = await client.downloadAttachment("attachment-123");
|
|
144
|
+
|
|
145
|
+
expect(axios.get).toHaveBeenCalledWith(mockAttachmentResponse.data.download_url, { responseType: "arraybuffer" });
|
|
146
|
+
expect(result).toEqual(mockBuffer);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("searchSmsMessages", () => {
|
|
151
|
+
it("should fetch and return SMS messages with default parameters", async () => {
|
|
152
|
+
const { mockGet } = setupMockAxios();
|
|
153
|
+
mockGet.mockResolvedValueOnce({ data: mockSmsMessagesResponse });
|
|
154
|
+
|
|
155
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
156
|
+
const result = await client.searchSmsMessages("1234567890");
|
|
157
|
+
|
|
158
|
+
expect(mockGet).toHaveBeenCalledWith("api/sms/1234567890/messages", {
|
|
159
|
+
maxRedirects: 99999,
|
|
160
|
+
timeout: 1000 * 60 * 5,
|
|
161
|
+
params: {
|
|
162
|
+
from_date: expect.any(String),
|
|
163
|
+
wait: true,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
expect(result).toEqual(mockSmsMessagesResponse);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("should use custom parameters if provided", async () => {
|
|
171
|
+
const { mockGet } = setupMockAxios();
|
|
172
|
+
mockGet.mockResolvedValueOnce({ data: mockSmsMessagesResponse });
|
|
173
|
+
|
|
174
|
+
const customParams = {
|
|
175
|
+
limit: 5,
|
|
176
|
+
offset: 2,
|
|
177
|
+
body: "verification",
|
|
178
|
+
from_number: "+18005550123",
|
|
179
|
+
from_date: "2023-01-01T00:00:00.000Z",
|
|
180
|
+
to_date: "2023-02-01T00:00:00.000Z",
|
|
181
|
+
wait: false,
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
185
|
+
const result = await client.searchSmsMessages("+1234567890", customParams);
|
|
186
|
+
|
|
187
|
+
const expectedParams = { ...customParams };
|
|
188
|
+
|
|
189
|
+
expect(mockGet).toHaveBeenCalledWith("api/sms/+1234567890/messages", {
|
|
190
|
+
maxRedirects: 99999,
|
|
191
|
+
params: expectedParams,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
expect(result).toEqual(mockSmsMessagesResponse);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it("should use custom axios config if provided", async () => {
|
|
198
|
+
const { mockGet } = setupMockAxios();
|
|
199
|
+
mockGet.mockResolvedValueOnce({ data: mockSmsMessagesResponse });
|
|
200
|
+
|
|
201
|
+
const customConfig = {
|
|
202
|
+
timeout: 10000,
|
|
203
|
+
maxRedirects: 5,
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
207
|
+
const result = await client.searchSmsMessages("+1234567890", undefined, customConfig);
|
|
208
|
+
|
|
209
|
+
expect(mockGet).toHaveBeenCalledWith("api/sms/+1234567890/messages", {
|
|
210
|
+
...customConfig,
|
|
211
|
+
params: {
|
|
212
|
+
from_date: expect.any(String),
|
|
213
|
+
wait: true,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
expect(result).toEqual(mockSmsMessagesResponse);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("should handle errors correctly", async () => {
|
|
221
|
+
const { mockGet } = setupMockAxios();
|
|
222
|
+
const error = new Error("Search SMS Error");
|
|
223
|
+
mockGet.mockRejectedValueOnce(error);
|
|
224
|
+
|
|
225
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
226
|
+
|
|
227
|
+
await expect(client.searchSmsMessages("+1234567890")).rejects.toThrow("Search SMS Error");
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe("listSmsNumbers", () => {
|
|
232
|
+
it("should fetch and return SMS numbers", async () => {
|
|
233
|
+
const { mockGet } = setupMockAxios();
|
|
234
|
+
mockGet.mockResolvedValueOnce({ data: mockSmsNumbersResponse });
|
|
235
|
+
|
|
236
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
237
|
+
const result = await client.listSmsNumbers();
|
|
238
|
+
|
|
239
|
+
expect(mockGet).toHaveBeenCalledWith("api/sms/numbers");
|
|
240
|
+
expect(result).toEqual(mockSmsNumbersResponse);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it("should handle errors correctly", async () => {
|
|
244
|
+
const { mockGet } = setupMockAxios();
|
|
245
|
+
const error = new Error("List SMS Numbers Error");
|
|
246
|
+
mockGet.mockRejectedValueOnce(error);
|
|
247
|
+
|
|
248
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
249
|
+
|
|
250
|
+
await expect(client.listSmsNumbers()).rejects.toThrow("List SMS Numbers Error");
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
describe("sendVirtualSms", () => {
|
|
255
|
+
it("should send an SMS through the API", async () => {
|
|
256
|
+
const { mockPost } = setupMockAxios();
|
|
257
|
+
mockPost.mockResolvedValueOnce({ data: {} });
|
|
258
|
+
|
|
259
|
+
const smsParams = {
|
|
260
|
+
from_number: "15551234567",
|
|
261
|
+
to_number: "15557654321",
|
|
262
|
+
body: "Test message",
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
266
|
+
await client.sendVirtualSms(smsParams);
|
|
267
|
+
|
|
268
|
+
expect(mockPost).toHaveBeenCalledWith("api/sms/virtual", smsParams);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it("should handle errors when sending SMS", async () => {
|
|
272
|
+
const { mockPost } = setupMockAxios();
|
|
273
|
+
const error = new Error("Send SMS Error");
|
|
274
|
+
mockPost.mockRejectedValueOnce(error);
|
|
275
|
+
|
|
276
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
277
|
+
|
|
278
|
+
await expect(
|
|
279
|
+
client.sendVirtualSms({ from_number: "+15551234567", to_number: "+15557654321", body: "Test message" })
|
|
280
|
+
).rejects.toThrow("Send SMS Error");
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
describe("searchInbox", () => {
|
|
285
|
+
it("should fetch and return emails with default parameters", async () => {
|
|
286
|
+
const { mockGet } = setupMockAxios();
|
|
287
|
+
mockGet.mockResolvedValueOnce({ data: mockEmailsResponse });
|
|
288
|
+
|
|
289
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
290
|
+
const result = await client.searchInbox("test-namespace");
|
|
291
|
+
|
|
292
|
+
expect(mockGet).toHaveBeenCalledWith("api/emails/test-namespace/inbox", {
|
|
293
|
+
maxRedirects: 99999,
|
|
294
|
+
timeout: 1000 * 60 * 5,
|
|
295
|
+
params: {
|
|
296
|
+
from_timestamp: expect.any(Number),
|
|
297
|
+
wait: true,
|
|
298
|
+
},
|
|
299
|
+
});
|
|
300
|
+
expect(result).toEqual(mockEmailsResponse);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("should use custom parameters if provided", async () => {
|
|
304
|
+
const { mockGet } = setupMockAxios();
|
|
305
|
+
mockGet.mockResolvedValueOnce({ data: mockEmailsResponse });
|
|
306
|
+
|
|
307
|
+
const customParams = {
|
|
308
|
+
limit: 10,
|
|
309
|
+
offset: 5,
|
|
310
|
+
from_timestamp: 1234567890,
|
|
311
|
+
to_timestamp: 1234567899,
|
|
312
|
+
to_addr_prefix: "john",
|
|
313
|
+
from_addr_includes: "@example.com",
|
|
314
|
+
subject_includes: "test",
|
|
315
|
+
wait: false,
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
319
|
+
const result = await client.searchInbox("test-namespace", customParams);
|
|
320
|
+
|
|
321
|
+
expect(mockGet).toHaveBeenCalledWith("api/emails/test-namespace/inbox", {
|
|
322
|
+
maxRedirects: 99999,
|
|
323
|
+
params: customParams,
|
|
324
|
+
});
|
|
325
|
+
expect(result).toEqual(mockEmailsResponse);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it("should use custom axios config if provided", async () => {
|
|
329
|
+
const { mockGet } = setupMockAxios();
|
|
330
|
+
mockGet.mockResolvedValueOnce({ data: mockEmailsResponse });
|
|
331
|
+
|
|
332
|
+
const customParams = {
|
|
333
|
+
wait: true,
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
const customConfig = {
|
|
337
|
+
timeout: 10000,
|
|
338
|
+
maxRedirects: 5,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
342
|
+
const result = await client.searchInbox("test-namespace", customParams, customConfig);
|
|
343
|
+
|
|
344
|
+
expect(mockGet).toHaveBeenCalledWith("api/emails/test-namespace/inbox", {
|
|
345
|
+
...customConfig,
|
|
346
|
+
params: {
|
|
347
|
+
from_timestamp: expect.any(Number),
|
|
348
|
+
wait: true,
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
expect(result).toEqual(mockEmailsResponse);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it("should handle errors correctly", async () => {
|
|
355
|
+
const { mockGet } = setupMockAxios();
|
|
356
|
+
const error = new Error("Search Inbox Error");
|
|
357
|
+
mockGet.mockRejectedValueOnce(error);
|
|
358
|
+
|
|
359
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
360
|
+
|
|
361
|
+
await expect(client.searchInbox("test-namespace")).rejects.toThrow("Search Inbox Error");
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
describe("sendVirtualEmail", () => {
|
|
366
|
+
// Setup for nodemailer mock
|
|
367
|
+
const mockSendMail = jest.fn();
|
|
368
|
+
const mockClose = jest.fn();
|
|
369
|
+
const mockTransport = {
|
|
370
|
+
sendMail: mockSendMail,
|
|
371
|
+
close: mockClose,
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
beforeEach(() => {
|
|
375
|
+
(nodemailer.createTransport as jest.Mock).mockReturnValue(mockTransport);
|
|
376
|
+
mockSendMail.mockReset().mockResolvedValue({});
|
|
377
|
+
mockClose.mockReset();
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it("should send an email using nodemailer", async () => {
|
|
381
|
+
const { mockGet } = setupMockAxios();
|
|
382
|
+
mockGet.mockResolvedValueOnce({
|
|
383
|
+
data: {
|
|
384
|
+
data: {
|
|
385
|
+
host: "smtp.mailisk.com",
|
|
386
|
+
port: 25,
|
|
387
|
+
username: "test-namespace",
|
|
388
|
+
password: "mock-password",
|
|
389
|
+
},
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
const emailParams = {
|
|
394
|
+
from: "sender@example.com",
|
|
395
|
+
to: "recipient@test-namespace.mailisk.net",
|
|
396
|
+
subject: "Test Subject",
|
|
397
|
+
text: "Test Content",
|
|
398
|
+
html: "<p>Test HTML Content</p>",
|
|
399
|
+
headers: { "X-Custom-Header": "Custom Value" },
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
403
|
+
await client.sendVirtualEmail("test-namespace", emailParams);
|
|
404
|
+
|
|
405
|
+
expect(mockGet).toHaveBeenCalledWith("api/smtp/test-namespace");
|
|
406
|
+
|
|
407
|
+
expect(nodemailer.createTransport).toHaveBeenCalledWith({
|
|
408
|
+
host: "smtp.mailisk.com",
|
|
409
|
+
port: 25,
|
|
410
|
+
secure: false,
|
|
411
|
+
auth: {
|
|
412
|
+
user: "test-namespace",
|
|
413
|
+
pass: "mock-password",
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
expect(mockSendMail).toHaveBeenCalledWith({
|
|
418
|
+
from: "sender@example.com",
|
|
419
|
+
to: "recipient@test-namespace.mailisk.net",
|
|
420
|
+
subject: "Test Subject",
|
|
421
|
+
text: "Test Content",
|
|
422
|
+
html: "<p>Test HTML Content</p>",
|
|
423
|
+
headers: { "X-Custom-Header": "Custom Value" },
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
expect(mockClose).toHaveBeenCalled();
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
it("should handle errors from SMTP settings fetch", async () => {
|
|
430
|
+
const { mockGet } = setupMockAxios();
|
|
431
|
+
const error = new Error("SMTP Settings Error");
|
|
432
|
+
mockGet.mockRejectedValueOnce(error);
|
|
433
|
+
|
|
434
|
+
const emailParams = {
|
|
435
|
+
from: "sender@example.com",
|
|
436
|
+
to: "recipient@test-namespace.mailisk.net",
|
|
437
|
+
subject: "Test Subject",
|
|
438
|
+
text: "Test Content",
|
|
439
|
+
};
|
|
440
|
+
|
|
441
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
442
|
+
|
|
443
|
+
await expect(client.sendVirtualEmail("test-namespace", emailParams)).rejects.toThrow("SMTP Settings Error");
|
|
444
|
+
|
|
445
|
+
expect(nodemailer.createTransport).not.toHaveBeenCalled();
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it("should handle errors from nodemailer sendMail", async () => {
|
|
449
|
+
const { mockGet } = setupMockAxios();
|
|
450
|
+
mockGet.mockResolvedValueOnce({
|
|
451
|
+
data: {
|
|
452
|
+
data: {
|
|
453
|
+
host: "smtp.mailisk.com",
|
|
454
|
+
port: 25,
|
|
455
|
+
username: "test-namespace",
|
|
456
|
+
password: "mock-password",
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
const sendMailError = new Error("Failed to send email");
|
|
462
|
+
mockSendMail.mockRejectedValueOnce(sendMailError);
|
|
463
|
+
|
|
464
|
+
const emailParams = {
|
|
465
|
+
from: "sender@example.com",
|
|
466
|
+
to: "recipient@test-namespace.mailisk.net",
|
|
467
|
+
subject: "Test Subject",
|
|
468
|
+
text: "Test Content",
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
const client = new MailiskClient({ apiKey: "test-key" });
|
|
472
|
+
|
|
473
|
+
await expect(client.sendVirtualEmail("test-namespace", emailParams)).rejects.toThrow("Failed to send email");
|
|
474
|
+
|
|
475
|
+
// In the actual implementation, if sendMail throws an error, close won't be called
|
|
476
|
+
// We just verify that sendMail was called
|
|
477
|
+
expect(mockSendMail).toHaveBeenCalled();
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
});
|