summaryrefslogtreecommitdiff
path: root/spec/frontend/helpers
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 14:34:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-20 14:34:42 +0000
commit9f46488805e86b1bc341ea1620b866016c2ce5ed (patch)
treef9748c7e287041e37d6da49e0a29c9511dc34768 /spec/frontend/helpers
parentdfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff)
downloadgitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'spec/frontend/helpers')
-rw-r--r--spec/frontend/helpers/class_spec_helper.js1
-rw-r--r--spec/frontend/helpers/event_hub_factory_spec.js94
-rw-r--r--spec/frontend/helpers/filtered_search_spec_helper.js69
-rw-r--r--spec/frontend/helpers/fixtures.js5
-rw-r--r--spec/frontend/helpers/set_window_location_helper.js40
-rw-r--r--spec/frontend/helpers/set_window_location_helper_spec.js40
-rw-r--r--spec/frontend/helpers/vue_mount_component_helper.js25
-rw-r--r--spec/frontend/helpers/web_worker_mock.js10
8 files changed, 282 insertions, 2 deletions
diff --git a/spec/frontend/helpers/class_spec_helper.js b/spec/frontend/helpers/class_spec_helper.js
index 7a60d33b471..b26f087f0c5 100644
--- a/spec/frontend/helpers/class_spec_helper.js
+++ b/spec/frontend/helpers/class_spec_helper.js
@@ -1,3 +1,4 @@
+// eslint-disable-next-line jest/no-export
export default class ClassSpecHelper {
static itShouldBeAStaticMethod(base, method) {
return it('should be a static method', () => {
diff --git a/spec/frontend/helpers/event_hub_factory_spec.js b/spec/frontend/helpers/event_hub_factory_spec.js
new file mode 100644
index 00000000000..dcfec6b836a
--- /dev/null
+++ b/spec/frontend/helpers/event_hub_factory_spec.js
@@ -0,0 +1,94 @@
+import createEventHub from '~/helpers/event_hub_factory';
+
+describe('event bus factory', () => {
+ let eventBus;
+
+ beforeEach(() => {
+ eventBus = createEventHub();
+ });
+
+ afterEach(() => {
+ eventBus = null;
+ });
+
+ describe('underlying module', () => {
+ let mitt;
+
+ beforeEach(() => {
+ jest.resetModules();
+ jest.mock('mitt');
+
+ // eslint-disable-next-line global-require
+ mitt = require('mitt');
+ mitt.mockReturnValue(() => ({}));
+
+ const createEventHubActual = jest.requireActual('~/helpers/event_hub_factory').default;
+ eventBus = createEventHubActual();
+ });
+
+ it('creates an emitter', () => {
+ expect(mitt).toHaveBeenCalled();
+ });
+ });
+
+ describe('instance', () => {
+ it.each`
+ method
+ ${'on'}
+ ${'once'}
+ ${'off'}
+ ${'emit'}
+ `('binds $$method to $method ', ({ method }) => {
+ expect(typeof eventBus[method]).toBe('function');
+ expect(eventBus[method]).toBe(eventBus[`$${method}`]);
+ });
+ });
+
+ describe('once', () => {
+ const event = 'foobar';
+ let handler;
+
+ beforeEach(() => {
+ jest.spyOn(eventBus, 'on');
+ jest.spyOn(eventBus, 'off');
+ handler = jest.fn();
+ eventBus.once(event, handler);
+ });
+
+ it('calls on internally', () => {
+ expect(eventBus.on).toHaveBeenCalled();
+ });
+
+ it('calls handler when event is emitted', () => {
+ eventBus.emit(event);
+ expect(handler).toHaveBeenCalled();
+ });
+
+ it('calls off when event is emitted', () => {
+ eventBus.emit(event);
+ expect(eventBus.off).toHaveBeenCalled();
+ });
+
+ it('calls the handler only once when event is emitted multiple times', () => {
+ eventBus.emit(event);
+ eventBus.emit(event);
+ expect(handler).toHaveBeenCalledTimes(1);
+ });
+
+ describe('when the handler thows an error', () => {
+ beforeEach(() => {
+ handler = jest.fn().mockImplementation(() => {
+ throw new Error();
+ });
+ eventBus.once(event, handler);
+ });
+
+ it('calls off when event is emitted', () => {
+ expect(() => {
+ eventBus.emit(event);
+ }).toThrow();
+ expect(eventBus.off).toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/helpers/filtered_search_spec_helper.js b/spec/frontend/helpers/filtered_search_spec_helper.js
new file mode 100644
index 00000000000..ceb7982bbc3
--- /dev/null
+++ b/spec/frontend/helpers/filtered_search_spec_helper.js
@@ -0,0 +1,69 @@
+export default class FilteredSearchSpecHelper {
+ static createFilterVisualTokenHTML(name, operator, value, isSelected) {
+ return FilteredSearchSpecHelper.createFilterVisualToken(name, operator, value, isSelected)
+ .outerHTML;
+ }
+
+ static createFilterVisualToken(name, operator, value, isSelected = false) {
+ const li = document.createElement('li');
+ li.classList.add('js-visual-token', 'filtered-search-token', `search-token-${name}`);
+
+ li.innerHTML = `
+ <div class="selectable ${isSelected ? 'selected' : ''}" role="button">
+ <div class="name">${name}</div>
+ <div class="operator">${operator}</div>
+ <div class="value-container">
+ <div class="value">${value}</div>
+ <div class="remove-token" role="button">
+ <i class="fa fa-close"></i>
+ </div>
+ </div>
+ </div>
+ `;
+
+ return li;
+ }
+
+ static createNameFilterVisualTokenHTML(name) {
+ return `
+ <li class="js-visual-token filtered-search-token">
+ <div class="name">${name}</div>
+ </li>
+ `;
+ }
+
+ static createNameOperatorFilterVisualTokenHTML(name, operator) {
+ return `
+ <li class="js-visual-token filtered-search-token">
+ <div class="name">${name}</div>
+ <div class="operator">${operator}</div>
+ </li>
+ `;
+ }
+
+ static createSearchVisualToken(name) {
+ const li = document.createElement('li');
+ li.classList.add('js-visual-token', 'filtered-search-term');
+ li.innerHTML = `<div class="name">${name}</div>`;
+ return li;
+ }
+
+ static createSearchVisualTokenHTML(name) {
+ return FilteredSearchSpecHelper.createSearchVisualToken(name).outerHTML;
+ }
+
+ static createInputHTML(placeholder = '', value = '') {
+ return `
+ <li class="input-token">
+ <input type='text' class='filtered-search' placeholder='${placeholder}' value='${value}'/>
+ </li>
+ `;
+ }
+
+ static createTokensContainerHTML(html, inputPlaceholder) {
+ return `
+ ${html}
+ ${FilteredSearchSpecHelper.createInputHTML(inputPlaceholder)}
+ `;
+ }
+}
diff --git a/spec/frontend/helpers/fixtures.js b/spec/frontend/helpers/fixtures.js
index 778196843db..a89ceab3f8e 100644
--- a/spec/frontend/helpers/fixtures.js
+++ b/spec/frontend/helpers/fixtures.js
@@ -23,11 +23,12 @@ Did you run bin/rake frontend:fixtures?`,
export const getJSONFixture = relativePath => JSON.parse(getFixture(relativePath));
export const resetHTMLFixture = () => {
- document.body.textContent = '';
+ document.head.innerHTML = '';
+ document.body.innerHTML = '';
};
export const setHTMLFixture = (htmlContent, resetHook = afterEach) => {
- document.body.outerHTML = htmlContent;
+ document.body.innerHTML = htmlContent;
resetHook(resetHTMLFixture);
};
diff --git a/spec/frontend/helpers/set_window_location_helper.js b/spec/frontend/helpers/set_window_location_helper.js
new file mode 100644
index 00000000000..a94e73762c9
--- /dev/null
+++ b/spec/frontend/helpers/set_window_location_helper.js
@@ -0,0 +1,40 @@
+/**
+ * setWindowLocation allows for setting `window.location`
+ * (doing so directly is causing an error in jsdom)
+ *
+ * Example usage:
+ * assert(window.location.hash === undefined);
+ * setWindowLocation('http://example.com#foo')
+ * assert(window.location.hash === '#foo');
+ *
+ * More information:
+ * https://github.com/facebook/jest/issues/890
+ *
+ * @param url
+ */
+export default function setWindowLocation(url) {
+ const parsedUrl = new URL(url);
+
+ const newLocationValue = [
+ 'hash',
+ 'host',
+ 'hostname',
+ 'href',
+ 'origin',
+ 'pathname',
+ 'port',
+ 'protocol',
+ 'search',
+ ].reduce(
+ (location, prop) => ({
+ ...location,
+ [prop]: parsedUrl[prop],
+ }),
+ {},
+ );
+
+ Object.defineProperty(window, 'location', {
+ value: newLocationValue,
+ writable: true,
+ });
+}
diff --git a/spec/frontend/helpers/set_window_location_helper_spec.js b/spec/frontend/helpers/set_window_location_helper_spec.js
new file mode 100644
index 00000000000..2a2c024c824
--- /dev/null
+++ b/spec/frontend/helpers/set_window_location_helper_spec.js
@@ -0,0 +1,40 @@
+import setWindowLocation from './set_window_location_helper';
+
+describe('setWindowLocation', () => {
+ const originalLocation = window.location;
+
+ afterEach(() => {
+ window.location = originalLocation;
+ });
+
+ it.each`
+ url | property | value
+ ${'https://gitlab.com#foo'} | ${'hash'} | ${'#foo'}
+ ${'http://gitlab.com'} | ${'host'} | ${'gitlab.com'}
+ ${'http://gitlab.org'} | ${'hostname'} | ${'gitlab.org'}
+ ${'http://gitlab.org/foo#bar'} | ${'href'} | ${'http://gitlab.org/foo#bar'}
+ ${'http://gitlab.com'} | ${'origin'} | ${'http://gitlab.com'}
+ ${'http://gitlab.com/foo/bar/baz'} | ${'pathname'} | ${'/foo/bar/baz'}
+ ${'https://gitlab.com'} | ${'protocol'} | ${'https:'}
+ ${'http://gitlab.com#foo'} | ${'protocol'} | ${'http:'}
+ ${'http://gitlab.com:8080'} | ${'port'} | ${'8080'}
+ ${'http://gitlab.com?foo=bar&bar=foo'} | ${'search'} | ${'?foo=bar&bar=foo'}
+ `(
+ 'sets "window.location.$property" to be "$value" when called with: "$url"',
+ ({ url, property, value }) => {
+ expect(window.location).toBe(originalLocation);
+
+ setWindowLocation(url);
+
+ expect(window.location[property]).toBe(value);
+ },
+ );
+
+ it.each([null, 1, undefined, false, '', 'gitlab.com'])(
+ 'throws an error when called with an invalid url: "%s"',
+ invalidUrl => {
+ expect(() => setWindowLocation(invalidUrl)).toThrow(new TypeError('Invalid URL'));
+ expect(window.location).toBe(originalLocation);
+ },
+ );
+});
diff --git a/spec/frontend/helpers/vue_mount_component_helper.js b/spec/frontend/helpers/vue_mount_component_helper.js
index 6848c95d95d..615ff69a01c 100644
--- a/spec/frontend/helpers/vue_mount_component_helper.js
+++ b/spec/frontend/helpers/vue_mount_component_helper.js
@@ -1,22 +1,38 @@
import Vue from 'vue';
+/**
+ * Deprecated. Please do not use.
+ * Please see https://gitlab.com/groups/gitlab-org/-/epics/2445
+ */
const mountComponent = (Component, props = {}, el = null) =>
new Component({
propsData: props,
}).$mount(el);
+/**
+ * Deprecated. Please do not use.
+ * Please see https://gitlab.com/groups/gitlab-org/-/epics/2445
+ */
export const createComponentWithStore = (Component, store, propsData = {}) =>
new Component({
store,
propsData,
});
+/**
+ * Deprecated. Please do not use.
+ * Please see https://gitlab.com/groups/gitlab-org/-/epics/2445
+ */
export const mountComponentWithStore = (Component, { el, props, store }) =>
new Component({
store,
propsData: props || {},
}).$mount(el);
+/**
+ * Deprecated. Please do not use.
+ * Please see https://gitlab.com/groups/gitlab-org/-/epics/2445
+ */
export const mountComponentWithSlots = (Component, { props, slots }) => {
const component = new Component({
propsData: props || {},
@@ -30,9 +46,18 @@ export const mountComponentWithSlots = (Component, { props, slots }) => {
/**
* Mount a component with the given render method.
*
+ * -----------------------------
+ * Deprecated. Please do not use.
+ * Please see https://gitlab.com/groups/gitlab-org/-/epics/2445
+ * -----------------------------
+ *
* This helps with inserting slots that need to be compiled.
*/
export const mountComponentWithRender = (render, el = null) =>
mountComponent(Vue.extend({ render }), {}, el);
+/**
+ * Deprecated. Please do not use.
+ * Please see https://gitlab.com/groups/gitlab-org/-/epics/2445
+ */
export default mountComponent;
diff --git a/spec/frontend/helpers/web_worker_mock.js b/spec/frontend/helpers/web_worker_mock.js
new file mode 100644
index 00000000000..2b4a391e1d2
--- /dev/null
+++ b/spec/frontend/helpers/web_worker_mock.js
@@ -0,0 +1,10 @@
+/* eslint-disable class-methods-use-this */
+export default class WebWorkerMock {
+ addEventListener() {}
+
+ removeEventListener() {}
+
+ terminate() {}
+
+ postMessage() {}
+}