Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 21:42:06 +0300
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /spec/frontend/projects
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'spec/frontend/projects')
-rw-r--r--spec/frontend/projects/commits/components/author_select_spec.js6
-rw-r--r--spec/frontend/projects/commits/store/actions_spec.js4
-rw-r--r--spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap83
-rw-r--r--spec/frontend/projects/components/__snapshots__/remove_modal_spec.js.snap126
-rw-r--r--spec/frontend/projects/components/project_delete_button_spec.js47
-rw-r--r--spec/frontend/projects/components/remove_modal_spec.js62
-rw-r--r--spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap113
-rw-r--r--spec/frontend/projects/components/shared/delete_button_spec.js83
-rw-r--r--spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js2
-rw-r--r--spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js2
-rw-r--r--spec/frontend/projects/project_new_spec.js2
-rw-r--r--spec/frontend/projects/settings/access_dropdown_spec.js140
12 files changed, 474 insertions, 196 deletions
diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js
index dab91d8b37c..d6fac6f5f79 100644
--- a/spec/frontend/projects/commits/components/author_select_spec.js
+++ b/spec/frontend/projects/commits/components/author_select_spec.js
@@ -1,14 +1,14 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
-import * as urlUtility from '~/lib/utils/url_utility';
-import AuthorSelect from '~/projects/commits/components/author_select.vue';
-import { createStore } from '~/projects/commits/store';
import {
GlNewDropdown,
GlNewDropdownHeader,
GlSearchBoxByType,
GlNewDropdownItem,
} from '@gitlab/ui';
+import * as urlUtility from '~/lib/utils/url_utility';
+import AuthorSelect from '~/projects/commits/components/author_select.vue';
+import { createStore } from '~/projects/commits/store';
const localVue = createLocalVue();
localVue.use(Vuex);
diff --git a/spec/frontend/projects/commits/store/actions_spec.js b/spec/frontend/projects/commits/store/actions_spec.js
index 886224252ad..a842aaa2a76 100644
--- a/spec/frontend/projects/commits/store/actions_spec.js
+++ b/spec/frontend/projects/commits/store/actions_spec.js
@@ -1,10 +1,10 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
-import * as types from '~/projects/commits/store/mutation_types';
import testAction from 'helpers/vuex_action_helper';
+import * as types from '~/projects/commits/store/mutation_types';
import actions from '~/projects/commits/store/actions';
import createState from '~/projects/commits/store/state';
-import createFlash from '~/flash';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
jest.mock('~/flash');
diff --git a/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap b/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap
new file mode 100644
index 00000000000..44220bdef64
--- /dev/null
+++ b/spec/frontend/projects/components/__snapshots__/project_delete_button_spec.js.snap
@@ -0,0 +1,83 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Project remove modal initialized matches the snapshot 1`] = `
+<form
+ action="some/path"
+ method="post"
+>
+ <input
+ name="_method"
+ type="hidden"
+ value="delete"
+ />
+
+ <input
+ name="authenticity_token"
+ type="hidden"
+ />
+
+ <gl-button-stub
+ category="primary"
+ icon=""
+ role="button"
+ size="medium"
+ tabindex="0"
+ variant="danger"
+ >
+ Delete project
+ </gl-button-stub>
+
+ <gl-modal-stub
+ actioncancel="[object Object]"
+ actionprimary="[object Object]"
+ footer-class="gl-bg-gray-10 gl-p-5"
+ modalclass=""
+ modalid="fakeUniqueId"
+ ok-variant="danger"
+ size="sm"
+ title-class="gl-text-red-500"
+ titletag="h4"
+ >
+
+ <div>
+ <gl-alert-stub
+ class="gl-mb-5"
+ dismisslabel="Dismiss"
+ primarybuttonlink=""
+ primarybuttontext=""
+ secondarybuttonlink=""
+ secondarybuttontext=""
+ title="You are about to permanently delete this project"
+ variant="danger"
+ >
+ <gl-sprintf-stub
+ message="Once a project is permanently deleted it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its respositories and %{strongStart}all related resources%{strongEnd} including issues, merge requests etc."
+ />
+ </gl-alert-stub>
+
+ <p>
+ This action cannot be undone. You will lose the project's respository and all conent: issues, merge requests, etc.
+ </p>
+
+ <p
+ class="gl-mb-1"
+ >
+ Please type the following to confirm:
+ </p>
+
+ <p>
+ <code>
+ foo
+ </code>
+ </p>
+
+ <gl-form-input-stub
+ id="confirm_name_input"
+ name="confirm_name_input"
+ type="text"
+ />
+
+ </div>
+ </gl-modal-stub>
+</form>
+`;
diff --git a/spec/frontend/projects/components/__snapshots__/remove_modal_spec.js.snap b/spec/frontend/projects/components/__snapshots__/remove_modal_spec.js.snap
deleted file mode 100644
index 4d5b6c56a34..00000000000
--- a/spec/frontend/projects/components/__snapshots__/remove_modal_spec.js.snap
+++ /dev/null
@@ -1,126 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Project remove modal initialized matches the snapshot 1`] = `
-<form
- action="some/path"
- method="post"
->
- <input
- name="_method"
- type="hidden"
- value="delete"
- />
-
- <input
- name="authenticity_token"
- type="hidden"
- />
-
- <b-button-stub
- class="[object Object]"
- event="click"
- role="button"
- routertag="a"
- size="md"
- tabindex="0"
- tag="button"
- type="button"
- variant="danger"
- >
- <!---->
-
- <!---->
-
- <span
- class="gl-button-text"
- >
- Remove project
- </span>
- </b-button-stub>
-
- <b-modal-stub
- canceltitle="Cancel"
- cancelvariant="secondary"
- footerclass="bg-gray-light gl-p-5"
- headerclosecontent="&times;"
- headercloselabel="Close"
- id="remove-project-modal"
- ignoreenforcefocusselector=""
- lazy="true"
- modalclass="gl-modal,"
- oktitle="OK"
- okvariant="danger"
- size="sm"
- title=""
- titletag="h4"
- >
-
- <div>
- <p
- class="gl-text-red-500 gl-font-weight-bold"
- >
- This can lead to data loss.
- </p>
-
- <p
- class="gl-mb-0"
- >
- This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention.
- </p>
-
- <p>
- <gl-sprintf-stub
- message="Please type %{phrase_code} to proceed or close this modal to cancel."
- />
- </p>
-
- <gl-form-input-stub
- id="confirm_name_input"
- name="confirm_name_input"
- type="text"
- />
- </div>
-
- <template />
-
- <template>
- Confirmation required
- </template>
-
- <template />
-
- <template />
-
- <template />
-
- <template>
- <div
- class="gl-w-full gl-display-flex gl-just-content-start gl-m-0"
- >
- <b-button-stub
- class="[object Object]"
- disabled="true"
- event="click"
- routertag="a"
- size="md"
- tag="button"
- type="button"
- variant="danger"
- >
- <!---->
-
- <!---->
-
- <span
- class="gl-button-text"
- >
-
- Confirm
-
- </span>
- </b-button-stub>
- </div>
- </template>
- </b-modal-stub>
-</form>
-`;
diff --git a/spec/frontend/projects/components/project_delete_button_spec.js b/spec/frontend/projects/components/project_delete_button_spec.js
new file mode 100644
index 00000000000..444e465ebaa
--- /dev/null
+++ b/spec/frontend/projects/components/project_delete_button_spec.js
@@ -0,0 +1,47 @@
+import { shallowMount } from '@vue/test-utils';
+import ProjectDeleteButton from '~/projects/components/project_delete_button.vue';
+import SharedDeleteButton from '~/projects/components/shared/delete_button.vue';
+
+jest.mock('lodash/uniqueId', () => () => 'fakeUniqueId');
+
+describe('Project remove modal', () => {
+ let wrapper;
+
+ const findSharedDeleteButton = () => wrapper.find(SharedDeleteButton);
+
+ const defaultProps = {
+ confirmPhrase: 'foo',
+ formPath: 'some/path',
+ };
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(ProjectDeleteButton, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ stubs: {
+ SharedDeleteButton,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('initialized', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('matches the snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('passes confirmPhrase and formPath props to the shared delete button', () => {
+ expect(findSharedDeleteButton().props()).toEqual(defaultProps);
+ });
+ });
+});
diff --git a/spec/frontend/projects/components/remove_modal_spec.js b/spec/frontend/projects/components/remove_modal_spec.js
deleted file mode 100644
index 339aee65b99..00000000000
--- a/spec/frontend/projects/components/remove_modal_spec.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { GlButton, GlModal } from '@gitlab/ui';
-import ProjectRemoveModal from '~/projects/components/remove_modal.vue';
-
-describe('Project remove modal', () => {
- let wrapper;
-
- const findFormElement = () => wrapper.find('form').element;
- const findConfirmButton = () => wrapper.find(GlModal).find(GlButton);
-
- const defaultProps = {
- formPath: 'some/path',
- confirmPhrase: 'foo',
- warningMessage: 'This can lead to data loss.',
- };
-
- const createComponent = (data = {}) => {
- wrapper = shallowMount(ProjectRemoveModal, {
- propsData: defaultProps,
- data: () => data,
- stubs: {
- GlButton,
- GlModal,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('initialized', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('matches the snapshot', () => {
- expect(wrapper.element).toMatchSnapshot();
- });
- });
-
- describe('user input matches the confirmPhrase', () => {
- beforeEach(() => {
- createComponent({ userInput: defaultProps.confirmPhrase });
- });
-
- it('the confirm button is not dislabled', () => {
- expect(findConfirmButton().attributes('disabled')).toBe(undefined);
- });
-
- describe('and when the confirmation button is clicked', () => {
- beforeEach(() => {
- findConfirmButton().vm.$emit('click');
- });
-
- it('submits the form element', () => {
- expect(findFormElement().submit).toHaveBeenCalled();
- });
- });
- });
-});
diff --git a/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap b/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap
new file mode 100644
index 00000000000..a43acc8c002
--- /dev/null
+++ b/spec/frontend/projects/components/shared/__snapshots__/delete_button_spec.js.snap
@@ -0,0 +1,113 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Project remove modal intialized matches the snapshot 1`] = `
+<form
+ action="some/path"
+ method="post"
+>
+ <input
+ name="_method"
+ type="hidden"
+ value="delete"
+ />
+
+ <input
+ name="authenticity_token"
+ type="hidden"
+ value="test-csrf-token"
+ />
+
+ <gl-button-stub
+ category="primary"
+ icon=""
+ role="button"
+ size="medium"
+ tabindex="0"
+ variant="danger"
+ >
+ Delete project
+ </gl-button-stub>
+
+ <b-modal-stub
+ canceltitle="Cancel"
+ cancelvariant="secondary"
+ footerclass="gl-bg-gray-10 gl-p-5"
+ headerclosecontent="&times;"
+ headercloselabel="Close"
+ id="delete-project-modal-2"
+ ignoreenforcefocusselector=""
+ lazy="true"
+ modalclass="gl-modal,"
+ oktitle="OK"
+ okvariant="danger"
+ size="sm"
+ title=""
+ titleclass="gl-text-red-500"
+ titletag="h4"
+ >
+
+ <div>
+
+ <p
+ class="gl-mb-1"
+ >
+ Please type the following to confirm:
+ </p>
+
+ <p>
+ <code>
+ foo
+ </code>
+ </p>
+
+ <gl-form-input-stub
+ id="confirm_name_input"
+ name="confirm_name_input"
+ type="text"
+ />
+
+ </div>
+
+ <template />
+
+ <template>
+ Delete project. Are you ABSOLUTELY SURE?
+ </template>
+
+ <template />
+
+ <template />
+
+ <template />
+
+ <template>
+ <gl-button-stub
+ category="primary"
+ class="js-modal-action-cancel"
+ icon=""
+ size="medium"
+ variant="default"
+ >
+
+ Cancel, keep project
+
+ </gl-button-stub>
+
+ <!---->
+
+ <gl-button-stub
+ category="primary"
+ class="js-modal-action-primary"
+ disabled="true"
+ icon=""
+ size="medium"
+ variant="danger"
+ >
+
+ Yes, delete project
+
+ </gl-button-stub>
+ </template>
+ </b-modal-stub>
+</form>
+`;
diff --git a/spec/frontend/projects/components/shared/delete_button_spec.js b/spec/frontend/projects/components/shared/delete_button_spec.js
new file mode 100644
index 00000000000..a6394a50011
--- /dev/null
+++ b/spec/frontend/projects/components/shared/delete_button_spec.js
@@ -0,0 +1,83 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import SharedDeleteButton from '~/projects/components/shared/delete_button.vue';
+
+jest.mock('~/lib/utils/csrf', () => ({ token: 'test-csrf-token' }));
+
+describe('Project remove modal', () => {
+ let wrapper;
+
+ const findFormElement = () => wrapper.find('form');
+ const findConfirmButton = () => wrapper.find('.js-modal-action-primary');
+ const findAuthenticityTokenInput = () => findFormElement().find('input[name=authenticity_token]');
+ const findModal = () => wrapper.find(GlModal);
+
+ const defaultProps = {
+ confirmPhrase: 'foo',
+ formPath: 'some/path',
+ };
+
+ const createComponent = (data = {}) => {
+ wrapper = shallowMount(SharedDeleteButton, {
+ propsData: defaultProps,
+ data: () => data,
+ stubs: {
+ GlModal,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ describe('intialized', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('matches the snapshot', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('sets a csrf token on the authenticity form input', () => {
+ expect(findAuthenticityTokenInput().element.value).toEqual('test-csrf-token');
+ });
+
+ it('sets the form action to the provided path', () => {
+ expect(findFormElement().attributes('action')).toEqual(defaultProps.formPath);
+ });
+ });
+
+ describe('when the user input does not match the confirmPhrase', () => {
+ beforeEach(() => {
+ createComponent({ userInput: 'bar' });
+ });
+
+ it('the confirm button is disabled', () => {
+ expect(findConfirmButton().attributes('disabled')).toBe('true');
+ });
+ });
+
+ describe('when the user input matches the confirmPhrase', () => {
+ beforeEach(() => {
+ createComponent({ userInput: defaultProps.confirmPhrase });
+ });
+
+ it('the confirm button is not disabled', () => {
+ expect(findConfirmButton().attributes('disabled')).toBe(undefined);
+ });
+ });
+
+ describe('when the modal is confirmed', () => {
+ beforeEach(() => {
+ createComponent();
+ findModal().vm.$emit('ok');
+ });
+
+ it('submits the form element', () => {
+ expect(findFormElement().element.submit).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js
index cd8b39f0426..42a7aa6bc88 100644
--- a/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js
+++ b/spec/frontend/projects/experiment_new_project_creation/components/legacy_container_spec.js
@@ -1,6 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import LegacyContainer from '~/projects/experiment_new_project_creation/components/legacy_container.vue';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import LegacyContainer from '~/projects/experiment_new_project_creation/components/legacy_container.vue';
describe('Legacy container component', () => {
let wrapper;
diff --git a/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js b/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js
index acd142fa5ba..cf23ba281f9 100644
--- a/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js
+++ b/spec/frontend/projects/experiment_new_project_creation/components/welcome_spec.js
@@ -1,6 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import WelcomePage from '~/projects/experiment_new_project_creation/components/welcome.vue';
import { mockTracking } from 'helpers/tracking_helper';
+import WelcomePage from '~/projects/experiment_new_project_creation/components/welcome.vue';
describe('Welcome page', () => {
let wrapper;
diff --git a/spec/frontend/projects/project_new_spec.js b/spec/frontend/projects/project_new_spec.js
index 7aafbd33fc8..c32979dcd74 100644
--- a/spec/frontend/projects/project_new_spec.js
+++ b/spec/frontend/projects/project_new_spec.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
-import projectNew from '~/projects/project_new';
import { TEST_HOST } from 'jest/helpers/test_constants';
+import projectNew from '~/projects/project_new';
describe('New Project', () => {
let $projectImportUrl;
diff --git a/spec/frontend/projects/settings/access_dropdown_spec.js b/spec/frontend/projects/settings/access_dropdown_spec.js
new file mode 100644
index 00000000000..6d323b0408b
--- /dev/null
+++ b/spec/frontend/projects/settings/access_dropdown_spec.js
@@ -0,0 +1,140 @@
+import $ from 'jquery';
+import '~/gl_dropdown';
+import AccessDropdown from '~/projects/settings/access_dropdown';
+import { LEVEL_TYPES } from '~/projects/settings/constants';
+
+describe('AccessDropdown', () => {
+ const defaultLabel = 'dummy default label';
+ let dropdown;
+
+ beforeEach(() => {
+ setFixtures(`
+ <div id="dummy-dropdown">
+ <span class="dropdown-toggle-text"></span>
+ </div>
+ `);
+ const $dropdown = $('#dummy-dropdown');
+ $dropdown.data('defaultLabel', defaultLabel);
+ const options = {
+ $dropdown,
+ accessLevelsData: {
+ roles: [
+ {
+ id: 42,
+ text: 'Dummy Role',
+ },
+ ],
+ },
+ };
+ dropdown = new AccessDropdown(options);
+ });
+
+ describe('toggleLabel', () => {
+ let $dropdownToggleText;
+ const dummyItems = [
+ { type: LEVEL_TYPES.ROLE, access_level: 42 },
+ { type: LEVEL_TYPES.USER },
+ { type: LEVEL_TYPES.USER },
+ { type: LEVEL_TYPES.GROUP },
+ { type: LEVEL_TYPES.GROUP },
+ { type: LEVEL_TYPES.GROUP },
+ ];
+
+ beforeEach(() => {
+ $dropdownToggleText = $('.dropdown-toggle-text');
+ });
+
+ it('displays number of items', () => {
+ dropdown.setSelectedItems(dummyItems);
+ $dropdownToggleText.addClass('is-default');
+
+ const label = dropdown.toggleLabel();
+
+ expect(label).toBe('1 role, 2 users, 3 groups');
+ expect($dropdownToggleText).not.toHaveClass('is-default');
+ });
+
+ describe('without selected items', () => {
+ beforeEach(() => {
+ dropdown.setSelectedItems([]);
+ });
+
+ it('falls back to default label', () => {
+ const label = dropdown.toggleLabel();
+
+ expect(label).toBe(defaultLabel);
+ expect($dropdownToggleText).toHaveClass('is-default');
+ });
+ });
+
+ describe('with only role', () => {
+ beforeEach(() => {
+ dropdown.setSelectedItems(dummyItems.filter(item => item.type === LEVEL_TYPES.ROLE));
+ $dropdownToggleText.addClass('is-default');
+ });
+
+ it('displays the role name', () => {
+ const label = dropdown.toggleLabel();
+
+ expect(label).toBe('Dummy Role');
+ expect($dropdownToggleText).not.toHaveClass('is-default');
+ });
+ });
+
+ describe('with only users', () => {
+ beforeEach(() => {
+ dropdown.setSelectedItems(dummyItems.filter(item => item.type === LEVEL_TYPES.USER));
+ $dropdownToggleText.addClass('is-default');
+ });
+
+ it('displays number of users', () => {
+ const label = dropdown.toggleLabel();
+
+ expect(label).toBe('2 users');
+ expect($dropdownToggleText).not.toHaveClass('is-default');
+ });
+ });
+
+ describe('with only groups', () => {
+ beforeEach(() => {
+ dropdown.setSelectedItems(dummyItems.filter(item => item.type === LEVEL_TYPES.GROUP));
+ $dropdownToggleText.addClass('is-default');
+ });
+
+ it('displays number of groups', () => {
+ const label = dropdown.toggleLabel();
+
+ expect(label).toBe('3 groups');
+ expect($dropdownToggleText).not.toHaveClass('is-default');
+ });
+ });
+
+ describe('with users and groups', () => {
+ beforeEach(() => {
+ const selectedTypes = [LEVEL_TYPES.GROUP, LEVEL_TYPES.USER];
+ dropdown.setSelectedItems(dummyItems.filter(item => selectedTypes.includes(item.type)));
+ $dropdownToggleText.addClass('is-default');
+ });
+
+ it('displays number of groups', () => {
+ const label = dropdown.toggleLabel();
+
+ expect(label).toBe('2 users, 3 groups');
+ expect($dropdownToggleText).not.toHaveClass('is-default');
+ });
+ });
+ });
+
+ describe('userRowHtml', () => {
+ it('escapes users name', () => {
+ const user = {
+ avatar_url: '',
+ name: '<img src=x onerror=alert(document.domain)>',
+ username: 'test',
+ };
+ const template = dropdown.userRowHtml(user);
+
+ expect(template).not.toContain(user.name);
+ });
+ });
+});