From f14b4fe5f1a5c0c9626e1f2f0ac1267a65c2de7e Mon Sep 17 00:00:00 2001 From: Jan Drewniak Date: Tue, 16 Aug 2022 17:09:02 -0400 Subject: [PATCH] Add tests for dropdownMenu.js Adds tests for the addPortletLinkHandler, which should add an icon element to items added via 'mw.util.addPortletLink' and conditionally move elements from the toolbar into the more menu at narrow widths. - Adds tests for dropdownMenu.js - Adds associated Jest snapshots - Stubs the mediawiki.page.ready module - Updates mockMediawiki.js to 4.6.0 - Adds global mock for mw.util.showPortlet() - Cleans up tests using local versions of these mocks Bug: T314798 Change-Id: I81394d840321916756a41a23c40d96c4b6341931 --- jest.setup.js | 1 + package-lock.json | 6 +- package.json | 2 +- tests/jest/AB.test.js | 10 +-- tests/jest/__mocks__/mediawiki.page.ready.js | 3 + .../__snapshots__/dropdownMenu.test.js.snap | 52 +++++++++++++ tests/jest/dropdownMenu.test.js | 76 +++++++++++++++++++ tests/jest/tableOfContents.test.js | 10 +-- 8 files changed, 142 insertions(+), 18 deletions(-) create mode 100644 tests/jest/__mocks__/mediawiki.page.ready.js create mode 100644 tests/jest/__snapshots__/dropdownMenu.test.js.snap create mode 100644 tests/jest/dropdownMenu.test.js diff --git a/jest.setup.js b/jest.setup.js index f7cfa62f..a2309966 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -3,3 +3,4 @@ var mockMediaWiki = require( '@wikimedia/mw-node-qunit/src/mockMediaWiki.js' ); global.mw = mockMediaWiki(); global.$ = require('jquery'); +global.mw.util.showPortlet = function() {}; diff --git a/package-lock.json b/package-lock.json index 70806437..ffe5176a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3538,9 +3538,9 @@ "dev": true }, "@wikimedia/mw-node-qunit": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@wikimedia/mw-node-qunit/-/mw-node-qunit-6.3.0.tgz", - "integrity": "sha512-d2Wwu4RnzVbRJIBQOLm0WnhJjuPq61ALoeJUVPVfsCv9HdbeuTqG1gyBzZk6L1Jyg80jDPq19OGyyush9CftkA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@wikimedia/mw-node-qunit/-/mw-node-qunit-6.4.0.tgz", + "integrity": "sha512-WrAPZGsvUTb0LYG1U4S1KP8FB1+zPIYpCG2IDkJ0AyLnjXxM/AsyLFQnG+RLG3aQN3LSfbSECGWyPP4ITQocXQ==", "dev": true, "requires": { "eslint-config-wikimedia": "0.21.0", diff --git a/package.json b/package.json index fde2cda0..4fd3d269 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@wikimedia/codex": "0.1.0-alpha.8", "@wikimedia/codex-icons": "0.1.0-alpha.8", "@wikimedia/codex-search": "0.1.0-alpha.8", - "@wikimedia/mw-node-qunit": "6.3.0", + "@wikimedia/mw-node-qunit": "6.4.0", "@wikimedia/types-wikimedia": "0.3.3", "babel-loader": "8.0.6", "commander": "9.1.0", diff --git a/tests/jest/AB.test.js b/tests/jest/AB.test.js index baf6fdbc..4572477e 100644 --- a/tests/jest/AB.test.js +++ b/tests/jest/AB.test.js @@ -45,11 +45,10 @@ describe( 'AB.js', () => { } ); describe( 'initialization when body tag does not contain bucket', () => { - let /** @type {jest.Mock} */ hookMock; + let /** @type {jest.SpyInstance} */ hookMock; beforeEach( () => { - hookMock = jest.fn().mockReturnValue( { fire: () => {} } ); - mw.hook = hookMock; + hookMock = jest.spyOn( mw, 'hook' ); } ); it( 'sends data to WikimediaEvents when the bucket is part of sample (e.g. control)', () => { @@ -70,11 +69,10 @@ describe( 'AB.js', () => { } ); describe( 'initialization when body tag contains bucket', () => { - let /** @type {jest.Mock} */ hookMock; + let /** @type {jest.SpyInstance} */ hookMock; beforeEach( () => { - hookMock = jest.fn().mockReturnValue( { fire: () => {} } ); - mw.hook = hookMock; + hookMock = jest.spyOn( mw, 'hook' ); } ); it( 'sends data to WikimediaEvents when the bucket is part of sample (e.g. control)', () => { diff --git a/tests/jest/__mocks__/mediawiki.page.ready.js b/tests/jest/__mocks__/mediawiki.page.ready.js new file mode 100644 index 00000000..765a9660 --- /dev/null +++ b/tests/jest/__mocks__/mediawiki.page.ready.js @@ -0,0 +1,3 @@ +module.exports = { + checkboxHack: () => {} +}; diff --git a/tests/jest/__snapshots__/dropdownMenu.test.js.snap b/tests/jest/__snapshots__/dropdownMenu.test.js.snap new file mode 100644 index 00000000..dab5e8dc --- /dev/null +++ b/tests/jest/__snapshots__/dropdownMenu.test.js.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`addPortletLinkHandler Adds a span with icon class to dropdown menus 1`] = ` +" + " +`; + +exports[`addPortletLinkHandler Does not add an icon when noicon class is present 1`] = ` +" + " +`; + +exports[`addPortletLinkHandler JS portlet should be moved to more menu (#p-cactions) at narrow widths 1`] = ` +" +
+ +
+ +
+ + + + +
" +`; diff --git a/tests/jest/dropdownMenu.test.js b/tests/jest/dropdownMenu.test.js new file mode 100644 index 00000000..ff351d46 --- /dev/null +++ b/tests/jest/dropdownMenu.test.js @@ -0,0 +1,76 @@ +const { addPortletLinkHandler } = require( '../../resources/skins.vector.js/dropdownMenus.js' ); + +describe( 'addPortletLinkHandler', () => { + + test( 'Adds a span with icon class to dropdown menus', () => { + + //
  • element is the assumed HTML output of mw.util.addPortlet + document.body.innerHTML = ` + `; + + const mockPortletItem = document.getElementById( 'test-id' ); + // @ts-ignore: mockPortletItem possibly 'null'. + addPortletLinkHandler( mockPortletItem, { id: 'test-id' } ); + expect( document.body.innerHTML ).toMatchSnapshot(); + } ); + + test( 'Does not add an icon when noicon class is present', () => { + + //
  • element is the assumed HTML output of mw.util.addPortlet + document.body.innerHTML = ` + `; + + const mockPortletItem = document.getElementById( 'test-id' ); + // @ts-ignore: mockPortletItem possibly 'null'. + addPortletLinkHandler( mockPortletItem, { id: 'test-id' } ); + expect( document.body.innerHTML ).toMatchSnapshot(); + } ); + + test( 'JS portlet should be moved to more menu (#p-cactions) at narrow widths', () => { + + //
  • element is the assumed HTML output of mw.util.addPortlet + document.body.innerHTML = ` +
    + +
    + +
    + +
    +
      +
    +
    + + +
    `; + + const mockPortletItem = document.getElementById( 'test-id' ); + // @ts-ignore: mockPortletItem possibly 'null'. + addPortletLinkHandler( mockPortletItem, { id: 'test-id' } ); + expect( document.body.innerHTML ).toMatchSnapshot(); + } ); +} ); diff --git a/tests/jest/tableOfContents.test.js b/tests/jest/tableOfContents.test.js index 1719b241..74c8e4db 100644 --- a/tests/jest/tableOfContents.test.js +++ b/tests/jest/tableOfContents.test.js @@ -97,13 +97,6 @@ describe( 'Table of contents', () => { beforeEach( () => { // @ts-ignore global.window.matchMedia = jest.fn( () => ( {} ) ); - - // @ts-ignore - global.mw = { - hook: jest.fn( () => ( { - add: () => {} - } ) ) - }; } ); describe( 'renders', () => { @@ -195,11 +188,12 @@ describe( 'Table of contents', () => { describe( 'applies the correct aria attributes', () => { test( 'when initialized', () => { + const spy = jest.spyOn( mw, 'hook' ); const toc = mount(); const toggleButton = /** @type {HTMLElement} */ ( barSection.querySelector( `.${toc.TOGGLE_CLASS}` ) ); expect( toggleButton.getAttribute( 'aria-expanded' ) ).toEqual( 'true' ); - expect( mw.hook ).toBeCalledWith( 'wikipage.tableOfContents' ); + expect( spy ).toBeCalledWith( 'wikipage.tableOfContents' ); } ); test( 'when expanding sections', () => {