Skip to content

Commit

Permalink
other: Add tests for esm imports
Browse files Browse the repository at this point in the history
  • Loading branch information
olexandr-mazepa committed Feb 14, 2025
1 parent 207d5fd commit 81af7fb
Show file tree
Hide file tree
Showing 16 changed files with 628 additions and 16 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"rules": {
"import/extensions": 0,
"@typescript-eslint/no-shadow": "error",
"import/no-unresolved": "error"
"import/no-unresolved": "error",
"import/no-extraneous-dependencies" :["error", {"devDependencies": true, "optionalDependencies": false, "peerDependencies": false}]
},
"settings": {
"import/parsers": {
Expand Down
11 changes: 6 additions & 5 deletions tests/integration/browser/setup/addPageListeners.cjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* eslint-disable no-console */
/* global page, beforeAll */

const { VERBOSE } = process.env;
beforeAll(async function () {
const isVerbose = VERBOSE === 'true';
// global.MailgunClient = null;
page.on('console', (message) => console.debug(`Browser console -> ${message.type()} ${message.text()}`))
page.on('console', (message) => isVerbose && console.debug(`Browser console -> ${message.type()} ${message.text()}`))
.on('pageerror', ({ message }) => console.error(`Browser page error -> ${message}`))
.on('request', (req) => console.log(`Browser send request -> ${req.url()}`))
.on('response', (response) => console.log(`Browser got response -> ${response.status()} ${response.url()}`))
.on('requestfailed', (request) => console.log(`Browser request failed ->${request.failure().errorText} ${request.url()}`));
.on('request', (req) => isVerbose && console.log(`Browser send request -> ${req.url()}`))
.on('response', (response) => isVerbose && console.log(`Browser got response -> ${response.status()} ${response.url()}`))
.on('requestfailed', (request) => console.error(`Browser request failed ->${request.failure().errorText} ${request.url()}`));
});
13 changes: 6 additions & 7 deletions tests/integration/browser/setup/globalSetup.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ const path = require('path');
module.exports = async function globalSetup(globalConfig) {
const ciEnvValue = process.env.CI;
if (typeof ciEnvValue !== 'string' || ciEnvValue !== 'true') { // local machine
await fs.copyFile(
path.join(__dirname, '../../../../dist/AMD/mailgun.amd.js'),
path.join(__dirname, '../server/dist/mailgun.amd.js')
);
await fs.copyFile(
path.join(__dirname, '../../../../dist/AMD/definitions.amd.js'),
path.join(__dirname, '../server/dist/definitions.amd.js')
await fs.cp(
path.join(__dirname, '../../../../dist/'),
path.join(__dirname, '../server/dist/'),
{
recursive: true
}
);
try {
// set up a web server to server pages
Expand Down
5 changes: 3 additions & 2 deletions tests/integration/browser/setup/globalTeardown.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ module.exports = async function globalTeardown(globalConfig) {
const ciEnvValue = process.env.CI;
if (typeof ciEnvValue !== 'string' || ciEnvValue !== 'true') { // local machine
await teardownDevServer(globalThis.servers);
await fs.rm(path.join(__dirname, '../server/dist/mailgun.amd.js'));
await fs.rm(path.join(__dirname, '../server/dist/definitions.amd.js'));
await fs.rm(path.join(__dirname, '../server/dist/'), { recursive: true });
await fs.mkdir(path.join(__dirname, '../server/dist/'));
await fs.writeFile(path.join(__dirname, '../server/dist/.gitkeep'), '');
}

await teardownPuppeteer(globalConfig);
Expand Down
7 changes: 7 additions & 0 deletions tests/integration/browser/tests/amd/messages.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import {
afterAll,
beforeAll,
describe,
expect,
test
} from '@jest/globals';
import { successResponse } from '../../../tests_data/messageResponses';
import { IMailgunClient } from '../../../../../lib/Interfaces';
import { MailgunMessageData } from '../../../../../lib/Types';
Expand Down
50 changes: 50 additions & 0 deletions tests/integration/browser/tests/esm-dynamic/import.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable tsdoc/syntax */
import {
describe,
expect,
test,
beforeAll
} from '@jest/globals';
import 'jest-puppeteer';
import { IMailgunClient } from '../../../../../lib/Interfaces/index.js';

type Window = globalThis.Window & {
mailgunClient?: IMailgunClient
definitionsExport?: {
Enums: object,
Interfaces: object,
}
packageExport?: Function
};

describe('AMD import validation', () => {
beforeAll(async () => {
await page.goto('http://localhost:3000/pages/ESM.html');
await page.waitForFunction(function () { return typeof (window as Window).mailgunClient !== 'undefined'; });
await page.waitForFunction(function () { return typeof (window as Window).packageExport !== 'undefined'; });
await page.waitForFunction(function () { return typeof (window as Window).definitionsExport !== 'undefined'; });
});

test('AMD package exports function', async () => {
const isFunction = await page.evaluate(() => (typeof (window as Window).packageExport === 'function'));
expect(isFunction).toBe(true);
});

test('AMD definitions exports object', async () => {
const definitionsExport = await page.evaluate(() => (window as Window).definitionsExport);
expect(typeof definitionsExport).toBe('object');
expect(definitionsExport).toEqual(expect.objectContaining({
Enums: expect.any(Object),
Interfaces: expect.any(Object),
}));
});

test('AMD client has expected structure', async () => {
const client = await page.evaluate(() => (window as Window).mailgunClient);
const expected = ['request', 'domains', 'webhooks', 'events', 'stats', 'suppressions', 'messages', 'routes', 'ips', 'ip_pools', 'lists', 'validate'];
expect(client).toBeDefined();
expect(typeof client).toBe('object');
expect(Object.keys(client as IMailgunClient)).toEqual(expect.arrayContaining(expected));
});
});
120 changes: 120 additions & 0 deletions tests/integration/browser/tests/esm-dynamic/messages.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import {
afterAll,
beforeAll,
describe,
expect,
test
} from '@jest/globals';
import { successResponse } from '../../../tests_data/messageResponses';
import { IMailgunClient } from '../../../../../lib/Interfaces';
import { MailgunMessageData } from '../../../../../lib/Types';
import 'jest-puppeteer';

const serverUrl = 'http://localhost:3000';

type ExtendedWindow = globalThis.Window & {
mailgunClient?: IMailgunClient
packageExport?: object
};

describe('Send message functionality (AMD)', () => {
beforeAll(async () => {
await page.goto('http://localhost:3000/pages/ESM.html');
await page.waitForFunction(function () { return typeof (window as ExtendedWindow).mailgunClient !== 'undefined'; });
await page.setRequestInterception(true);

page.on('request', (request) => {
const isExpectedUrls = [`${serverUrl}/v3/test.domain.com/messages`, `${serverUrl}/v3/test.domain.com/messages.mime`];
if (isExpectedUrls.includes(request.url())) {
request.respond({
status: 200,
contentType: 'application/json',
body: JSON.stringify(successResponse.body)
});
} else {
request.continue();
}
});
});

afterAll(async () => {
await page.setRequestInterception(false);
});

test('Sends plain email (AMD)', async () => {
const result = await page.evaluate(
(domain, messageData) => (window as ExtendedWindow)?.mailgunClient?.messages.create(
domain,
messageData
),
'test.domain.com', {
to: '[email protected]',
from: '[email protected]',
subject: 'howdy!',
text: 'Hello world!'
}
);
expect(typeof result).toBe('object');
expect(result).toEqual({
status: 200,
message: 'Queued. Thank you.',
id: '<[email protected]>'
});
});

test('Sends mime email (AMD)', async () => {
const result = await page.evaluate(
(domain, messageData) => (window as ExtendedWindow).mailgunClient?.messages.create(
domain,
messageData
),
'test.domain.com', {
to: '[email protected]',
from: '[email protected]',
subject: 'howdy!',
message: 'hello world!'
}
);
expect(typeof result).toBe('object');
expect(result).toEqual({
status: 200,
message: 'Queued. Thank you.',
id: '<[email protected]>'
});
});

test('Sends an attachment (AMD)', async () => {
await page.waitForSelector('input[type=file]', { timeout: 3000 });
const input = await page.$('input[type=file]');
expect(input).toBeTruthy();
await input?.uploadFile('../../../tests_data/img/mailgun.png');

const result = await page.evaluate(
async (domain, messageData, pageInput) => {
const messageDataCopy: MailgunMessageData = { ...messageData };
if (pageInput && pageInput.files?.length) {
const mailgunLogo = pageInput.files[0];
messageDataCopy.attachment = [{
filename: mailgunLogo.name,
data: mailgunLogo
}];
}
return (window as ExtendedWindow).mailgunClient?.messages.create(domain, messageDataCopy);
},
'test.domain.com', {
to: '[email protected]',
from: '[email protected]',
subject: 'howdy!',
text: 'test',
attachment: []
},
input
);
expect(typeof result).toBe('object');
expect(result).toEqual({
status: 200,
message: 'Queued. Thank you.',
id: '<[email protected]>'
});
});
});
50 changes: 50 additions & 0 deletions tests/integration/browser/tests/esm/import.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable tsdoc/syntax */
import {
describe,
expect,
test,
beforeAll
} from '@jest/globals';
import 'jest-puppeteer';
import { IMailgunClient } from '../../../../../lib/Interfaces/index.js';

type Window = globalThis.Window & {
mailgunClient?: IMailgunClient
definitionsExport?: {
Enums: object,
Interfaces: object,
}
packageExport?: Function
};

describe('AMD import validation', () => {
beforeAll(async () => {
await page.goto('http://localhost:3000/pages/ESM.html');
await page.waitForFunction(function () { return typeof (window as Window).mailgunClient !== 'undefined'; });
await page.waitForFunction(function () { return typeof (window as Window).packageExport !== 'undefined'; });
await page.waitForFunction(function () { return typeof (window as Window).definitionsExport !== 'undefined'; });
});

test('AMD package exports function', async () => {
const isFunction = await page.evaluate(() => (typeof (window as Window).packageExport === 'function'));
expect(isFunction).toBe(true);
});

test('AMD definitions exports object', async () => {
const definitionsExport = await page.evaluate(() => (window as Window).definitionsExport);
expect(typeof definitionsExport).toBe('object');
expect(definitionsExport).toEqual(expect.objectContaining({
Enums: expect.any(Object),
Interfaces: expect.any(Object),
}));
});

test('AMD client has expected structure', async () => {
const client = await page.evaluate(() => (window as Window).mailgunClient);
const expected = ['request', 'domains', 'webhooks', 'events', 'stats', 'suppressions', 'messages', 'routes', 'ips', 'ip_pools', 'lists', 'validate'];
expect(client).toBeDefined();
expect(typeof client).toBe('object');
expect(Object.keys(client as IMailgunClient)).toEqual(expect.arrayContaining(expected));
});
});
Loading

0 comments on commit 81af7fb

Please sign in to comment.