summaryrefslogtreecommitdiff
path: root/spec/frontend
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-25 12:08:48 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-25 12:08:48 +0000
commitf7dae0cdcb70ecb71c1d65f099e9d96b27a4548c (patch)
treee53baffa847c4fd37c8e335e4d93d603c75f9f02 /spec/frontend
parentb98fa9ef3d5bead417ae2f325cb64637883264e9 (diff)
downloadgitlab-ce-f7dae0cdcb70ecb71c1d65f099e9d96b27a4548c.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/confirm_modal_spec.js127
-rw-r--r--spec/frontend/lib/utils/datetime_utility_spec.js22
-rw-r--r--spec/frontend/vue_shared/components/confirm_modal_spec.js84
3 files changed, 233 insertions, 0 deletions
diff --git a/spec/frontend/confirm_modal_spec.js b/spec/frontend/confirm_modal_spec.js
new file mode 100644
index 00000000000..f133cef675f
--- /dev/null
+++ b/spec/frontend/confirm_modal_spec.js
@@ -0,0 +1,127 @@
+import Vue from 'vue';
+import initConfirmModal from '~/confirm_modal';
+import { TEST_HOST } from 'helpers/test_constants';
+
+describe('ConfirmModal', () => {
+ const buttons = [
+ {
+ path: `${TEST_HOST}/1`,
+ method: 'delete',
+ modalAttributes: {
+ modalId: 'geo-entry-removal-modal',
+ title: 'Remove tracking database entry',
+ message: 'Tracking database entry will be removed. Are you sure?',
+ okVariant: 'danger',
+ okTitle: 'Remove entry',
+ },
+ },
+ {
+ path: `${TEST_HOST}/1`,
+ method: 'post',
+ modalAttributes: {
+ modalId: 'geo-entry-removal-modal',
+ title: 'Update tracking database entry',
+ message: 'Tracking database entry will be updated. Are you sure?',
+ okVariant: 'success',
+ okTitle: 'Update entry',
+ },
+ },
+ ];
+
+ beforeEach(() => {
+ const buttonContainer = document.createElement('div');
+
+ buttons.forEach(x => {
+ const button = document.createElement('button');
+ button.setAttribute('class', 'js-confirm-modal-button');
+ button.setAttribute('data-path', x.path);
+ button.setAttribute('data-method', x.method);
+ button.setAttribute('data-modal-attributes', JSON.stringify(x.modalAttributes));
+ button.innerHTML = 'Action';
+ buttonContainer.appendChild(button);
+ });
+
+ document.body.appendChild(buttonContainer);
+ });
+
+ afterEach(() => {
+ document.body.innerHTML = '';
+ });
+
+ const findJsHooks = () => document.querySelectorAll('.js-confirm-modal-button');
+ const findModal = () => document.querySelector('.gl-modal');
+ const findModalOkButton = (modal, variant) =>
+ modal.querySelector(`.modal-footer .btn-${variant}`);
+ const findModalCancelButton = modal => modal.querySelector('.modal-footer .btn-secondary');
+
+ const serializeModal = (modal, buttonIndex) => {
+ const { modalAttributes } = buttons[buttonIndex];
+
+ return {
+ path: modal.querySelector('form').action,
+ method: modal.querySelector('input[name="_method"]').value,
+ modalAttributes: {
+ modalId: modal.id,
+ title: modal.querySelector('.modal-title').innerHTML,
+ message: modal.querySelector('.modal-body div').innerHTML,
+ okVariant: [...findModalOkButton(modal, modalAttributes.okVariant).classList]
+ .find(x => x.match('btn-'))
+ .replace('btn-', ''),
+ okTitle: findModalOkButton(modal, modalAttributes.okVariant).innerHTML,
+ },
+ };
+ };
+
+ it('starts with only JsHooks', () => {
+ expect(findJsHooks()).toHaveLength(buttons.length);
+ expect(findModal()).not.toExist();
+ });
+
+ describe('when button clicked', () => {
+ beforeEach(() => {
+ initConfirmModal();
+ findJsHooks()
+ .item(0)
+ .click();
+ });
+
+ it('does not replace JsHook with GlModal', () => {
+ expect(findJsHooks()).toHaveLength(buttons.length);
+ });
+
+ describe('GlModal', () => {
+ it('is rendered', () => {
+ expect(findModal()).toExist();
+ });
+
+ describe('Cancel Button', () => {
+ beforeEach(() => {
+ findModalCancelButton(findModal()).click();
+
+ return Vue.nextTick();
+ });
+
+ it('closes the modal', () => {
+ expect(findModal()).not.toExist();
+ });
+ });
+ });
+ });
+
+ describe.each`
+ index
+ ${0}
+ ${1}
+ `(`when multiple buttons exist`, ({ index }) => {
+ beforeEach(() => {
+ initConfirmModal();
+ findJsHooks()
+ .item(index)
+ .click();
+ });
+
+ it('correct props are passed to gl-modal', () => {
+ expect(serializeModal(findModal(), index)).toEqual(buttons[index]);
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/datetime_utility_spec.js b/spec/frontend/lib/utils/datetime_utility_spec.js
index e584150ba70..27b88d78ff0 100644
--- a/spec/frontend/lib/utils/datetime_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime_utility_spec.js
@@ -1,4 +1,6 @@
import { __, s__ } from '~/locale';
+import $ from 'jquery';
+import '~/commons/bootstrap';
import * as datetimeUtility from '~/lib/utils/datetime_utility';
describe('Date time utils', () => {
@@ -563,3 +565,23 @@ describe('approximateDuration', () => {
expect(datetimeUtility.approximateDuration(seconds)).toBe(approximation);
});
});
+
+describe('localTimeAgo', () => {
+ beforeEach(() => {
+ document.body.innerHTML = `<time title="some time" datetime="2020-02-18T22:22:32Z">1 hour ago</time>`;
+ });
+
+ it.each`
+ timeagoArg | title | dataOriginalTitle
+ ${false} | ${'some time'} | ${null}
+ ${true} | ${''} | ${'Feb 18, 2020 10:22pm GMT+0000'}
+ `('converts $seconds seconds to $approximation', ({ timeagoArg, title, dataOriginalTitle }) => {
+ const element = document.querySelector('time');
+ datetimeUtility.localTimeAgo($(element), timeagoArg);
+
+ jest.runAllTimers();
+
+ expect(element.getAttribute('data-original-title')).toBe(dataOriginalTitle);
+ expect(element.getAttribute('title')).toBe(title);
+ });
+});
diff --git a/spec/frontend/vue_shared/components/confirm_modal_spec.js b/spec/frontend/vue_shared/components/confirm_modal_spec.js
new file mode 100644
index 00000000000..722380d3383
--- /dev/null
+++ b/spec/frontend/vue_shared/components/confirm_modal_spec.js
@@ -0,0 +1,84 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import { TEST_HOST } from 'helpers/test_constants';
+import ConfirmModal from '~/vue_shared/components/confirm_modal.vue';
+
+describe('vue_shared/components/confirm_modal', () => {
+ const testModalProps = {
+ path: `${TEST_HOST}/1`,
+ method: 'delete',
+ modalAttributes: {
+ modalId: 'test-confirm-modal',
+ title: 'Are you sure?',
+ message: 'This will remove item 1',
+ okVariant: 'danger',
+ okTitle: 'Remove item',
+ },
+ };
+
+ const actionSpies = {
+ openModal: jest.fn(),
+ };
+
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(ConfirmModal, {
+ propsData: {
+ ...testModalProps,
+ ...props,
+ },
+ methods: {
+ ...actionSpies,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findModal = () => wrapper.find(GlModal);
+
+ describe('template', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('calls openModal on mount', () => {
+ expect(actionSpies.openModal).toHaveBeenCalled();
+ });
+
+ it('renders GlModal', () => {
+ expect(findModal().exists()).toBeTruthy();
+ });
+ });
+
+ describe('methods', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ describe('submitModal', () => {
+ beforeEach(() => {
+ wrapper.vm.$refs.form.requestSubmit = jest.fn();
+ });
+
+ it('calls requestSubmit', () => {
+ wrapper.vm.submitModal();
+ expect(wrapper.vm.$refs.form.requestSubmit).toHaveBeenCalled();
+ });
+ });
+
+ describe('dismiss', () => {
+ it('removes gl-modal', () => {
+ expect(findModal().exists()).toBeTruthy();
+ wrapper.vm.dismiss();
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findModal().exists()).toBeFalsy();
+ });
+ });
+ });
+ });
+});