summaryrefslogtreecommitdiff
path: root/spec/frontend/jira_connect
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/jira_connect')
-rw-r--r--spec/frontend/jira_connect/branches/components/new_branch_form_spec.js236
-rw-r--r--spec/frontend/jira_connect/branches/pages/index_spec.js65
-rw-r--r--spec/frontend/jira_connect/subscriptions/api_spec.js (renamed from spec/frontend/jira_connect/api_spec.js)6
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/__snapshots__/group_item_name_spec.js.snap (renamed from spec/frontend/jira_connect/components/__snapshots__/group_item_name_spec.js.snap)0
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/app_spec.js (renamed from spec/frontend/jira_connect/components/app_spec.js)8
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/group_item_name_spec.js (renamed from spec/frontend/jira_connect/components/group_item_name_spec.js)2
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/groups_list_item_spec.js (renamed from spec/frontend/jira_connect/components/groups_list_item_spec.js)10
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/groups_list_spec.js (renamed from spec/frontend/jira_connect/components/groups_list_spec.js)10
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js (renamed from spec/frontend/jira_connect/components/subscriptions_list_spec.js)12
-rw-r--r--spec/frontend/jira_connect/subscriptions/index_spec.js (renamed from spec/frontend/jira_connect/index_spec.js)4
-rw-r--r--spec/frontend/jira_connect/subscriptions/mock_data.js (renamed from spec/frontend/jira_connect/mock_data.js)0
-rw-r--r--spec/frontend/jira_connect/subscriptions/store/mutations_spec.js (renamed from spec/frontend/jira_connect/store/mutations_spec.js)4
-rw-r--r--spec/frontend/jira_connect/subscriptions/utils_spec.js (renamed from spec/frontend/jira_connect/utils_spec.js)4
13 files changed, 331 insertions, 30 deletions
diff --git a/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js b/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js
new file mode 100644
index 00000000000..7326b84ad54
--- /dev/null
+++ b/spec/frontend/jira_connect/branches/components/new_branch_form_spec.js
@@ -0,0 +1,236 @@
+import { GlAlert, GlForm, GlFormInput, GlButton } from '@gitlab/ui';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import NewBranchForm from '~/jira_connect/branches/components/new_branch_form.vue';
+import ProjectDropdown from '~/jira_connect/branches/components/project_dropdown.vue';
+import SourceBranchDropdown from '~/jira_connect/branches/components/source_branch_dropdown.vue';
+import {
+ CREATE_BRANCH_ERROR_GENERIC,
+ CREATE_BRANCH_ERROR_WITH_CONTEXT,
+} from '~/jira_connect/branches/constants';
+import createBranchMutation from '~/jira_connect/branches/graphql/mutations/create_branch.mutation.graphql';
+
+const mockProject = {
+ id: 'test',
+ fullPath: 'test-path',
+ repository: {
+ branchNames: ['main', 'f-test', 'release'],
+ rootRef: 'main',
+ },
+};
+const mockCreateBranchMutationResponse = {
+ data: {
+ createBranch: {
+ clientMutationId: 1,
+ errors: [],
+ },
+ },
+};
+const mockCreateBranchMutationResponseWithErrors = {
+ data: {
+ createBranch: {
+ clientMutationId: 1,
+ errors: ['everything is broken, sorry.'],
+ },
+ },
+};
+const mockCreateBranchMutationSuccess = jest
+ .fn()
+ .mockResolvedValue(mockCreateBranchMutationResponse);
+const mockCreateBranchMutationWithErrors = jest
+ .fn()
+ .mockResolvedValue(mockCreateBranchMutationResponseWithErrors);
+const mockCreateBranchMutationFailed = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+const mockMutationLoading = jest.fn().mockReturnValue(new Promise(() => {}));
+
+const localVue = createLocalVue();
+
+describe('NewBranchForm', () => {
+ let wrapper;
+
+ const findSourceBranchDropdown = () => wrapper.findComponent(SourceBranchDropdown);
+ const findProjectDropdown = () => wrapper.findComponent(ProjectDropdown);
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findForm = () => wrapper.findComponent(GlForm);
+ const findInput = () => wrapper.findComponent(GlFormInput);
+ const findButton = () => wrapper.findComponent(GlButton);
+
+ const completeForm = async () => {
+ await findInput().vm.$emit('input', 'cool-branch-name');
+ await findProjectDropdown().vm.$emit('change', mockProject);
+ await findSourceBranchDropdown().vm.$emit('change', 'source-branch');
+ };
+
+ function createMockApolloProvider({
+ mockCreateBranchMutation = mockCreateBranchMutationSuccess,
+ } = {}) {
+ localVue.use(VueApollo);
+
+ const mockApollo = createMockApollo([[createBranchMutation, mockCreateBranchMutation]]);
+
+ return mockApollo;
+ }
+
+ function createComponent({ mockApollo, provide } = {}) {
+ wrapper = shallowMount(NewBranchForm, {
+ localVue,
+ apolloProvider: mockApollo || createMockApolloProvider(),
+ provide: {
+ initialBranchName: '',
+ ...provide,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when selecting items from dropdowns', () => {
+ describe('when a project is selected', () => {
+ it('sets the `selectedProject` prop for ProjectDropdown and SourceBranchDropdown', async () => {
+ createComponent();
+
+ const projectDropdown = findProjectDropdown();
+ await projectDropdown.vm.$emit('change', mockProject);
+
+ expect(projectDropdown.props('selectedProject')).toEqual(mockProject);
+ expect(findSourceBranchDropdown().props('selectedProject')).toEqual(mockProject);
+ });
+ });
+
+ describe('when a source branch is selected', () => {
+ it('sets the `selectedBranchName` prop for SourceBranchDropdown', async () => {
+ createComponent();
+
+ const mockBranchName = 'main';
+ const sourceBranchDropdown = findSourceBranchDropdown();
+ await sourceBranchDropdown.vm.$emit('change', mockBranchName);
+
+ expect(sourceBranchDropdown.props('selectedBranchName')).toBe(mockBranchName);
+ });
+ });
+ });
+
+ describe('when submitting form', () => {
+ describe('when form submission is loading', () => {
+ it('sets submit button `loading` prop to `true`', async () => {
+ createComponent({
+ mockApollo: createMockApolloProvider({
+ mockCreateBranchMutation: mockMutationLoading,
+ }),
+ });
+
+ await completeForm();
+
+ await findForm().vm.$emit('submit', new Event('submit'));
+ await waitForPromises();
+
+ expect(findButton().props('loading')).toBe(true);
+ });
+ });
+
+ describe('when form submission is successful', () => {
+ beforeEach(async () => {
+ createComponent();
+
+ await completeForm();
+
+ await findForm().vm.$emit('submit', new Event('submit'));
+ await waitForPromises();
+ });
+
+ it('emits `success` event', () => {
+ expect(wrapper.emitted('success')).toBeTruthy();
+ });
+
+ it('called `createBranch` mutation correctly', () => {
+ expect(mockCreateBranchMutationSuccess).toHaveBeenCalledWith({
+ name: 'cool-branch-name',
+ projectPath: mockProject.fullPath,
+ ref: 'source-branch',
+ });
+ });
+
+ it('sets submit button `loading` prop to `false`', () => {
+ expect(findButton().props('loading')).toBe(false);
+ });
+ });
+
+ describe('when form submission fails', () => {
+ describe.each`
+ scenario | mutation | alertTitle | alertText
+ ${'with errors-as-data'} | ${mockCreateBranchMutationWithErrors} | ${CREATE_BRANCH_ERROR_WITH_CONTEXT} | ${mockCreateBranchMutationResponseWithErrors.data.createBranch.errors[0]}
+ ${'top-level error'} | ${mockCreateBranchMutationFailed} | ${''} | ${CREATE_BRANCH_ERROR_GENERIC}
+ `('', ({ mutation, alertTitle, alertText }) => {
+ beforeEach(async () => {
+ createComponent({
+ mockApollo: createMockApolloProvider({
+ mockCreateBranchMutation: mutation,
+ }),
+ });
+
+ await completeForm();
+
+ await findForm().vm.$emit('submit', new Event('submit'));
+ await waitForPromises();
+ });
+
+ it('displays an alert', () => {
+ const alert = findAlert();
+ expect(alert.exists()).toBe(true);
+ expect(alert.text()).toBe(alertText);
+ expect(alert.props()).toMatchObject({ title: alertTitle, variant: 'danger' });
+ });
+
+ it('sets submit button `loading` prop to `false`', () => {
+ expect(findButton().props('loading')).toBe(false);
+ });
+ });
+ });
+ });
+
+ describe('when `initialBranchName` is specified', () => {
+ it('sets value of branch name input to `initialBranchName` by default', () => {
+ const mockInitialBranchName = 'ap1-test-branch-name';
+
+ createComponent({ provide: { initialBranchName: mockInitialBranchName } });
+ expect(findInput().attributes('value')).toBe(mockInitialBranchName);
+ });
+ });
+
+ describe('error handling', () => {
+ describe.each`
+ component | componentName
+ ${SourceBranchDropdown} | ${'SourceBranchDropdown'}
+ ${ProjectDropdown} | ${'ProjectDropdown'}
+ `('when $componentName emits error', ({ component }) => {
+ const mockErrorMessage = 'oh noes!';
+
+ beforeEach(async () => {
+ createComponent();
+ await wrapper.findComponent(component).vm.$emit('error', { message: mockErrorMessage });
+ });
+
+ it('displays an alert', () => {
+ const alert = findAlert();
+ expect(alert.exists()).toBe(true);
+ expect(alert.text()).toBe(mockErrorMessage);
+ expect(alert.props('variant')).toBe('danger');
+ });
+
+ describe('when alert is dismissed', () => {
+ it('hides alert', async () => {
+ const alert = findAlert();
+ expect(alert.exists()).toBe(true);
+
+ await alert.vm.$emit('dismiss');
+
+ expect(alert.exists()).toBe(false);
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/jira_connect/branches/pages/index_spec.js b/spec/frontend/jira_connect/branches/pages/index_spec.js
new file mode 100644
index 00000000000..92976dd28da
--- /dev/null
+++ b/spec/frontend/jira_connect/branches/pages/index_spec.js
@@ -0,0 +1,65 @@
+import { GlEmptyState } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import NewBranchForm from '~/jira_connect/branches/components/new_branch_form.vue';
+import {
+ I18N_PAGE_TITLE_WITH_BRANCH_NAME,
+ I18N_PAGE_TITLE_DEFAULT,
+} from '~/jira_connect/branches/constants';
+import JiraConnectNewBranchPage from '~/jira_connect/branches/pages/index.vue';
+import { sprintf } from '~/locale';
+
+describe('NewBranchForm', () => {
+ let wrapper;
+
+ const findPageTitle = () => wrapper.find('h1');
+ const findNewBranchForm = () => wrapper.findComponent(NewBranchForm);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+
+ function createComponent({ provide } = {}) {
+ wrapper = shallowMount(JiraConnectNewBranchPage, {
+ provide: {
+ initialBranchName: '',
+ successStateSvgPath: '',
+ ...provide,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('page title', () => {
+ it.each`
+ initialBranchName | pageTitle
+ ${undefined} | ${I18N_PAGE_TITLE_DEFAULT}
+ ${'ap1-test-button'} | ${sprintf(I18N_PAGE_TITLE_WITH_BRANCH_NAME, { jiraIssue: 'ap1-test-button' })}
+ `(
+ 'sets page title to "$pageTitle" when initial branch name is "$initialBranchName"',
+ ({ initialBranchName, pageTitle }) => {
+ createComponent({ provide: { initialBranchName } });
+
+ expect(findPageTitle().text()).toBe(pageTitle);
+ },
+ );
+ });
+
+ it('renders NewBranchForm by default', () => {
+ createComponent();
+
+ expect(findNewBranchForm().exists()).toBe(true);
+ expect(findEmptyState().exists()).toBe(false);
+ });
+
+ describe('when `sucesss` event emitted from NewBranchForm', () => {
+ it('renders the success state', async () => {
+ createComponent();
+
+ const newBranchForm = findNewBranchForm();
+ await newBranchForm.vm.$emit('success');
+
+ expect(findNewBranchForm().exists()).toBe(false);
+ expect(findEmptyState().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/jira_connect/api_spec.js b/spec/frontend/jira_connect/subscriptions/api_spec.js
index 88922999715..57b11bdbc27 100644
--- a/spec/frontend/jira_connect/api_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/api_spec.js
@@ -1,10 +1,10 @@
import MockAdapter from 'axios-mock-adapter';
-import { addSubscription, removeSubscription, fetchGroups } from '~/jira_connect/api';
-import { getJwt } from '~/jira_connect/utils';
+import { addSubscription, removeSubscription, fetchGroups } from '~/jira_connect/subscriptions/api';
+import { getJwt } from '~/jira_connect/subscriptions/utils';
import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
-jest.mock('~/jira_connect/utils', () => ({
+jest.mock('~/jira_connect/subscriptions/utils', () => ({
getJwt: jest.fn().mockResolvedValue('jwt'),
}));
diff --git a/spec/frontend/jira_connect/components/__snapshots__/group_item_name_spec.js.snap b/spec/frontend/jira_connect/subscriptions/components/__snapshots__/group_item_name_spec.js.snap
index 21c903f064d..21c903f064d 100644
--- a/spec/frontend/jira_connect/components/__snapshots__/group_item_name_spec.js.snap
+++ b/spec/frontend/jira_connect/subscriptions/components/__snapshots__/group_item_name_spec.js.snap
diff --git a/spec/frontend/jira_connect/components/app_spec.js b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
index e0d61d8209b..8915a7697a5 100644
--- a/spec/frontend/jira_connect/components/app_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
@@ -1,12 +1,12 @@
import { GlAlert, GlButton, GlModal, GlLink } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import JiraConnectApp from '~/jira_connect/components/app.vue';
-import createStore from '~/jira_connect/store';
-import { SET_ALERT } from '~/jira_connect/store/mutation_types';
+import JiraConnectApp from '~/jira_connect/subscriptions/components/app.vue';
+import createStore from '~/jira_connect/subscriptions/store';
+import { SET_ALERT } from '~/jira_connect/subscriptions/store/mutation_types';
import { __ } from '~/locale';
-jest.mock('~/jira_connect/utils', () => ({
+jest.mock('~/jira_connect/subscriptions/utils', () => ({
retrieveAlert: jest.fn().mockReturnValue({ message: 'error message' }),
getLocation: jest.fn(),
}));
diff --git a/spec/frontend/jira_connect/components/group_item_name_spec.js b/spec/frontend/jira_connect/subscriptions/components/group_item_name_spec.js
index ea0067f8ed1..b5fe08486b1 100644
--- a/spec/frontend/jira_connect/components/group_item_name_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/group_item_name_spec.js
@@ -1,6 +1,6 @@
import { shallowMount } from '@vue/test-utils';
-import GroupItemName from '~/jira_connect/components/group_item_name.vue';
+import GroupItemName from '~/jira_connect/subscriptions/components/group_item_name.vue';
import { mockGroup1 } from '../mock_data';
describe('GroupItemName', () => {
diff --git a/spec/frontend/jira_connect/components/groups_list_item_spec.js b/spec/frontend/jira_connect/subscriptions/components/groups_list_item_spec.js
index bcc27cc2898..b69435df83a 100644
--- a/spec/frontend/jira_connect/components/groups_list_item_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/groups_list_item_spec.js
@@ -2,13 +2,13 @@ import { GlButton } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
-import * as JiraConnectApi from '~/jira_connect/api';
-import GroupItemName from '~/jira_connect/components/group_item_name.vue';
-import GroupsListItem from '~/jira_connect/components/groups_list_item.vue';
-import { persistAlert, reloadPage } from '~/jira_connect/utils';
+import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
+import GroupItemName from '~/jira_connect/subscriptions/components/group_item_name.vue';
+import GroupsListItem from '~/jira_connect/subscriptions/components/groups_list_item.vue';
+import { persistAlert, reloadPage } from '~/jira_connect/subscriptions/utils';
import { mockGroup1 } from '../mock_data';
-jest.mock('~/jira_connect/utils');
+jest.mock('~/jira_connect/subscriptions/utils');
describe('GroupsListItem', () => {
let wrapper;
diff --git a/spec/frontend/jira_connect/components/groups_list_spec.js b/spec/frontend/jira_connect/subscriptions/components/groups_list_spec.js
index d583fb68771..d3a9a3bfd41 100644
--- a/spec/frontend/jira_connect/components/groups_list_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/groups_list_spec.js
@@ -2,10 +2,10 @@ import { GlAlert, GlLoadingIcon, GlSearchBoxByType, GlPagination } from '@gitlab
import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import { fetchGroups } from '~/jira_connect/api';
-import GroupsList from '~/jira_connect/components/groups_list.vue';
-import GroupsListItem from '~/jira_connect/components/groups_list_item.vue';
-import { DEFAULT_GROUPS_PER_PAGE } from '~/jira_connect/constants';
+import { fetchGroups } from '~/jira_connect/subscriptions/api';
+import GroupsList from '~/jira_connect/subscriptions/components/groups_list.vue';
+import GroupsListItem from '~/jira_connect/subscriptions/components/groups_list_item.vue';
+import { DEFAULT_GROUPS_PER_PAGE } from '~/jira_connect/subscriptions/constants';
import { mockGroup1, mockGroup2 } from '../mock_data';
const createMockGroup = (groupId) => {
@@ -19,7 +19,7 @@ const createMockGroups = (count) => {
return [...new Array(count)].map((_, idx) => createMockGroup(idx));
};
-jest.mock('~/jira_connect/api', () => {
+jest.mock('~/jira_connect/subscriptions/api', () => {
return {
fetchGroups: jest.fn(),
};
diff --git a/spec/frontend/jira_connect/components/subscriptions_list_spec.js b/spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
index ff86969367d..32b43765843 100644
--- a/spec/frontend/jira_connect/components/subscriptions_list_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/subscriptions_list_spec.js
@@ -2,14 +2,14 @@ import { GlButton, GlEmptyState, GlTable } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
-import * as JiraConnectApi from '~/jira_connect/api';
-import SubscriptionsList from '~/jira_connect/components/subscriptions_list.vue';
-import createStore from '~/jira_connect/store';
-import { SET_ALERT } from '~/jira_connect/store/mutation_types';
-import { reloadPage } from '~/jira_connect/utils';
+import * as JiraConnectApi from '~/jira_connect/subscriptions/api';
+import SubscriptionsList from '~/jira_connect/subscriptions/components/subscriptions_list.vue';
+import createStore from '~/jira_connect/subscriptions/store';
+import { SET_ALERT } from '~/jira_connect/subscriptions/store/mutation_types';
+import { reloadPage } from '~/jira_connect/subscriptions/utils';
import { mockSubscription } from '../mock_data';
-jest.mock('~/jira_connect/utils');
+jest.mock('~/jira_connect/subscriptions/utils');
describe('SubscriptionsList', () => {
let wrapper;
diff --git a/spec/frontend/jira_connect/index_spec.js b/spec/frontend/jira_connect/subscriptions/index_spec.js
index 0161cfa0273..786f3b4a7d3 100644
--- a/spec/frontend/jira_connect/index_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/index_spec.js
@@ -1,6 +1,6 @@
-import { initJiraConnect } from '~/jira_connect';
+import { initJiraConnect } from '~/jira_connect/subscriptions';
-jest.mock('~/jira_connect/utils', () => ({
+jest.mock('~/jira_connect/subscriptions/utils', () => ({
getLocation: jest.fn().mockResolvedValue('test/location'),
}));
diff --git a/spec/frontend/jira_connect/mock_data.js b/spec/frontend/jira_connect/subscriptions/mock_data.js
index 5247a3dc522..5247a3dc522 100644
--- a/spec/frontend/jira_connect/mock_data.js
+++ b/spec/frontend/jira_connect/subscriptions/mock_data.js
diff --git a/spec/frontend/jira_connect/store/mutations_spec.js b/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
index 584b17b36f7..84a33dbf0b5 100644
--- a/spec/frontend/jira_connect/store/mutations_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/store/mutations_spec.js
@@ -1,5 +1,5 @@
-import mutations from '~/jira_connect/store/mutations';
-import state from '~/jira_connect/store/state';
+import mutations from '~/jira_connect/subscriptions/store/mutations';
+import state from '~/jira_connect/subscriptions/store/state';
describe('JiraConnect store mutations', () => {
let localState;
diff --git a/spec/frontend/jira_connect/utils_spec.js b/spec/frontend/jira_connect/subscriptions/utils_spec.js
index 7eae870478d..2dd95de1b8c 100644
--- a/spec/frontend/jira_connect/utils_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/utils_spec.js
@@ -1,6 +1,6 @@
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
-import { ALERT_LOCALSTORAGE_KEY } from '~/jira_connect/constants';
+import { ALERT_LOCALSTORAGE_KEY } from '~/jira_connect/subscriptions/constants';
import {
persistAlert,
retrieveAlert,
@@ -8,7 +8,7 @@ import {
getLocation,
reloadPage,
sizeToParent,
-} from '~/jira_connect/utils';
+} from '~/jira_connect/subscriptions/utils';
describe('JiraConnect utils', () => {
describe('alert utils', () => {