Skip to content
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

js: Add Jest testing #801

Merged
merged 5 commits into from
Mar 21, 2022
Merged
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
42 changes: 42 additions & 0 deletions isso/js/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* https://jestjs.io/docs/configuration
*
* Best practices by mailchimp:
* https://mailchimp.com/developer/open-commerce/docs/testing-requirements/
* When writing your test:
* - Do not add extra describe blocks. Jest tests are automatically file-scoped,
* so a file that performs a single test does not need a describe block in it.
* You may add multiple describe blocks to group related tests within one
* file, but you should not have a file with only a single describe block in
* it.
* - Always use test() instead of it() to define test functions.
* - Do not import describe, test, jest, jasmine, or expect. They are automatic
* globals in all test files.
* - Use arrow functions for all describe and test functions.
* - Use Jest’s built-in expect function for assertions.
* - You might need to test asynchronous code: functions that either return a
* Promise or take a callback argument. You should use Promises unless you
* need to use a callback, such as when the API of another package requires
* it. When using callbacks, make sure to add a done argument to your test
* function and call done when all testing is complete.
*/

const config = {
/* modulePaths:
* An alternative API to setting the NODE_PATH env variable, modulePaths is
* an array of absolute paths to additional locations to search when
* resolving modules. Use the <rootDir> string token to include the path to
* your project's root directory. Example: ["<rootDir>/app/"].
*/
modulePaths: ["<rootDir>"],
/* rootDir already set to pwd when running jest with this config as arg */
moduleNameMapper: {
"\.svg$": "<rootDir>/tests/mocks/fileMock.js",
},

/* Run tests in a virtual DOM environment
* See https://jestjs.io/docs/tutorial-jquery
*/
testEnvironment: "jsdom",
};

module.exports = config;
1 change: 1 addition & 0 deletions isso/js/tests/mocks/fileMock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'test-file-stub';
ix5 marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions isso/js/tests/unit/__snapshots__/isso.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Create Postbox 1`] = `"<div id=\\"isso-root\\"></div><div class=\\"isso-postbox\\"><div class=\\"form-wrapper\\"><div class=\\"textarea-wrapper\\"><div class=\\"textarea placeholder\\" contenteditable=\\"true\\">Type Comment Here (at least 3 chars)</div><div class=\\"preview\\"><div class=\\"isso-comment\\"><div class=\\"text-wrapper\\"><div class=\\"text\\"></div></div></div></div></div><section class=\\"auth-section\\"><p class=\\"input-wrapper\\"><input type=\\"text\\" name=\\"author\\" placeholder=\\"Name (optional)\\" value=\\"\\"></p><p class=\\"input-wrapper\\"><input type=\\"email\\" name=\\"email\\" placeholder=\\"E-mail (optional)\\" value=\\"\\"></p><p class=\\"input-wrapper\\"><input type=\\"text\\" name=\\"website\\" placeholder=\\"Website (optional)\\" value=\\"\\"></p><p class=\\"post-action\\"><input type=\\"submit\\" value=\\"Submit\\"></p><p class=\\"post-action\\"><input type=\\"button\\" name=\\"preview\\" value=\\"Preview\\"></p><p class=\\"post-action\\"><input type=\\"button\\" name=\\"edit\\" value=\\"Edit\\"></p></section><section class=\\"notification-section\\" style=\\"display: none;\\"><label><input type=\\"checkbox\\" name=\\"notification\\">Subscribe to email notification of replies</label></section></div></div>"`;
28 changes: 28 additions & 0 deletions isso/js/tests/unit/config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"use strict";

test("Client configuration - no languages", () => {
// Mock navigator.languages = []
global.languages = jest.spyOn(navigator, "languages", "get")
global.languages.mockReturnValue([]);

// Mock navigator.language = null
global.language = jest.spyOn(navigator, "language", "get")
global.language.mockReturnValue(null);

let config = require("app/config");

/* Expected:
* - no config["lang"]
* - navigator.languages empty
* - fall back on navigator.language
* - navigator.language empty
* - fall back on navigator.userLanguage
* - navigator.userLanguage empty
* (jsdom doesn't set it)
* - config["default-lang"] = "en"
* - final manual insertion of "en"
*/
let expected_langs = ["en", "en"];

expect(config["langs"]).toStrictEqual(expected_langs);
});
32 changes: 32 additions & 0 deletions isso/js/tests/unit/isso.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"use strict";

test('Create Postbox', () => {
// Set up our document body
document.body.innerHTML =
'<div id=isso-thread></div>' +
// Note: `src` and `data-isso` need to be set,
// else `api` fails to initialize!
'<script src="http://isso.api/js/embed.min.js" data-isso="/"></script>';

const isso = require("app/isso");
const $ = require("app/dom");

const config = require("app/config");
const i18n = require("app/i18n");
const svg = require("app/svg");

const template = require("app/template");

template.set("conf", config);
template.set("i18n", i18n.translate);
template.set("pluralize", i18n.pluralize);
template.set("svg", svg);

var isso_thread = $('#isso-thread');
isso_thread.append('<div id="isso-root"></div>');
isso_thread.append(new isso.Postbox(null));

// Will create a `.snap` file in `./__snapshots__/`.
// Don't forget to check in those files when changing anything!
expect(isso_thread.innerHTML).toMatchSnapshot();
});
9 changes: 9 additions & 0 deletions isso/js/tests/unit/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const utils = require("app/utils");

test("Pad string with zeros", function() {
let to_be_padded = "12345";
let pad_to = 10;
let padding_char = "0";
let expected = "0000012345"
expect(utils.pad(to_be_padded, pad_to, padding_char)).toStrictEqual(expected);
});
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
"repository": "github:posativ/isso",
"dependencies": {},
"scripts": {
"test": "jest --config isso/js/jest.config.js isso/js/tests/" ,
"test-unit": "jest --config isso/js/jest.config.js isso/js/tests/unit/",
"build-dev": "webpack --config isso/js/webpack.config.js --config-name dev",
"watch-dev": "webpack --config isso/js/webpack.config.js --config-name dev --watch",
"build-prod": "webpack --config isso/js/webpack.config.js --merge --config-name dev --config-name prod"
},
"devDependencies": {
"jest": "^27.5.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"jest-puppeteer" is missing ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding jest-puppeteer to devDependencies will automatically pull in a 400Mb+ download of headless chrome, as explained earlier. That's why I'm a bit hesitant to add it here.

Imo it should be up to the user whether they need to run the end-to-end tests.

Maybe there's an option to configure the package before installing to not pull in the chrome download automatically?

"webpack": "^5.68.0",
"webpack-cli": "^4.9.2"
}
Expand Down