summaryrefslogtreecommitdiff
path: root/spec/frontend/jira_connect
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /spec/frontend/jira_connect
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
downloadgitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/frontend/jira_connect')
-rw-r--r--spec/frontend/jira_connect/branches/components/project_dropdown_spec.js180
-rw-r--r--spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js192
-rw-r--r--spec/frontend/jira_connect/components/groups_list_spec.js6
3 files changed, 377 insertions, 1 deletions
diff --git a/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js b/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
new file mode 100644
index 00000000000..ec4cb2739f8
--- /dev/null
+++ b/spec/frontend/jira_connect/branches/components/project_dropdown_spec.js
@@ -0,0 +1,180 @@
+import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
+import { mount, 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 ProjectDropdown from '~/jira_connect/branches/components/project_dropdown.vue';
+import { PROJECTS_PER_PAGE } from '~/jira_connect/branches/constants';
+import getProjectsQuery from '~/jira_connect/branches/graphql/queries/get_projects.query.graphql';
+
+const localVue = createLocalVue();
+
+const mockProjects = [
+ {
+ id: 'test',
+ name: 'test',
+ nameWithNamespace: 'test',
+ avatarUrl: 'https://gitlab.com',
+ path: 'test-path',
+ fullPath: 'test-path',
+ repository: {
+ empty: false,
+ },
+ },
+ {
+ id: 'gitlab',
+ name: 'GitLab',
+ nameWithNamespace: 'gitlab-org/gitlab',
+ avatarUrl: 'https://gitlab.com',
+ path: 'gitlab',
+ fullPath: 'gitlab-org/gitlab',
+ repository: {
+ empty: false,
+ },
+ },
+];
+
+const mockProjectsQueryResponse = {
+ data: {
+ projects: {
+ nodes: mockProjects,
+ pageInfo: {
+ hasNextPage: false,
+ hasPreviousPage: false,
+ startCursor: '',
+ endCursor: '',
+ },
+ },
+ },
+};
+const mockGetProjectsQuerySuccess = jest.fn().mockResolvedValue(mockProjectsQueryResponse);
+const mockGetProjectsQueryFailed = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+const mockQueryLoading = jest.fn().mockReturnValue(new Promise(() => {}));
+
+describe('ProjectDropdown', () => {
+ let wrapper;
+
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findDropdownItemByText = (text) =>
+ findAllDropdownItems().wrappers.find((item) => item.text() === text);
+ const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
+
+ function createMockApolloProvider({ mockGetProjectsQuery = mockGetProjectsQuerySuccess } = {}) {
+ localVue.use(VueApollo);
+
+ const mockApollo = createMockApollo([[getProjectsQuery, mockGetProjectsQuery]]);
+
+ return mockApollo;
+ }
+
+ function createComponent({ mockApollo, props, mountFn = shallowMount } = {}) {
+ wrapper = mountFn(ProjectDropdown, {
+ localVue,
+ apolloProvider: mockApollo || createMockApolloProvider(),
+ propsData: props,
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when loading projects', () => {
+ beforeEach(() => {
+ createComponent({
+ mockApollo: createMockApolloProvider({ mockGetProjectsQuery: mockQueryLoading }),
+ });
+ });
+
+ it('sets dropdown `loading` prop to `true`', () => {
+ expect(findDropdown().props('loading')).toBe(true);
+ });
+
+ it('renders loading icon in dropdown', () => {
+ expect(findLoadingIcon().isVisible()).toBe(true);
+ });
+ });
+
+ describe('when projects query succeeds', () => {
+ beforeEach(async () => {
+ createComponent();
+ await waitForPromises();
+ await wrapper.vm.$nextTick();
+ });
+
+ it('sets dropdown `loading` prop to `false`', () => {
+ expect(findDropdown().props('loading')).toBe(false);
+ });
+
+ it('renders dropdown items', () => {
+ const dropdownItems = findAllDropdownItems();
+ expect(dropdownItems.wrappers).toHaveLength(mockProjects.length);
+ expect(dropdownItems.wrappers.map((item) => item.text())).toEqual(
+ mockProjects.map((project) => project.nameWithNamespace),
+ );
+ });
+
+ describe('when selecting a dropdown item', () => {
+ it('emits `change` event with the selected project name', async () => {
+ const mockProject = mockProjects[0];
+ const itemToSelect = findDropdownItemByText(mockProject.nameWithNamespace);
+ await itemToSelect.vm.$emit('click');
+
+ expect(wrapper.emitted('change')[0]).toEqual([mockProject]);
+ });
+ });
+
+ describe('when `selectedProject` prop is specified', () => {
+ const mockProject = mockProjects[0];
+
+ beforeEach(async () => {
+ wrapper.setProps({
+ selectedProject: mockProject,
+ });
+ });
+
+ it('sets `isChecked` prop of the corresponding dropdown item to `true`', () => {
+ expect(findDropdownItemByText(mockProject.nameWithNamespace).props('isChecked')).toBe(true);
+ });
+
+ it('sets dropdown text to `selectedBranchName` value', () => {
+ expect(findDropdown().props('text')).toBe(mockProject.nameWithNamespace);
+ });
+ });
+ });
+
+ describe('when projects query fails', () => {
+ beforeEach(async () => {
+ createComponent({
+ mockApollo: createMockApolloProvider({ mockGetProjectsQuery: mockGetProjectsQueryFailed }),
+ });
+ await waitForPromises();
+ });
+
+ it('emits `error` event', () => {
+ expect(wrapper.emitted('error')).toBeTruthy();
+ });
+ });
+
+ describe('when searching branches', () => {
+ it('triggers a refetch', async () => {
+ createComponent({ mountFn: mount });
+ await waitForPromises();
+ jest.clearAllMocks();
+
+ const mockSearchTerm = 'gitl';
+ await findSearchBox().vm.$emit('input', mockSearchTerm);
+
+ expect(mockGetProjectsQuerySuccess).toHaveBeenCalledWith({
+ after: '',
+ first: PROJECTS_PER_PAGE,
+ membership: true,
+ search: mockSearchTerm,
+ searchNamespaces: true,
+ sort: 'similarity',
+ });
+ });
+ });
+});
diff --git a/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js b/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js
new file mode 100644
index 00000000000..9dd11dd6345
--- /dev/null
+++ b/spec/frontend/jira_connect/branches/components/source_branch_dropdown_spec.js
@@ -0,0 +1,192 @@
+import { GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
+import { mount, 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 SourceBranchDropdown from '~/jira_connect/branches/components/source_branch_dropdown.vue';
+import { BRANCHES_PER_PAGE } from '~/jira_connect/branches/constants';
+import getProjectQuery from '~/jira_connect/branches/graphql/queries/get_project.query.graphql';
+
+const localVue = createLocalVue();
+
+const mockProject = {
+ id: 'test',
+ fullPath: 'test-path',
+ repository: {
+ branchNames: ['main', 'f-test', 'release'],
+ rootRef: 'main',
+ },
+};
+
+const mockProjectQueryResponse = {
+ data: {
+ project: mockProject,
+ },
+};
+const mockGetProjectQuery = jest.fn().mockResolvedValue(mockProjectQueryResponse);
+const mockQueryLoading = jest.fn().mockReturnValue(new Promise(() => {}));
+
+describe('SourceBranchDropdown', () => {
+ let wrapper;
+
+ const findDropdown = () => wrapper.findComponent(GlDropdown);
+ const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findDropdownItemByText = (text) =>
+ findAllDropdownItems().wrappers.find((item) => item.text() === text);
+ const findSearchBox = () => wrapper.findComponent(GlSearchBoxByType);
+
+ const assertDropdownItems = () => {
+ const dropdownItems = findAllDropdownItems();
+ expect(dropdownItems.wrappers).toHaveLength(mockProject.repository.branchNames.length);
+ expect(dropdownItems.wrappers.map((item) => item.text())).toEqual(
+ mockProject.repository.branchNames,
+ );
+ };
+
+ function createMockApolloProvider({ getProjectQueryLoading = false } = {}) {
+ localVue.use(VueApollo);
+
+ const mockApollo = createMockApollo([
+ [getProjectQuery, getProjectQueryLoading ? mockQueryLoading : mockGetProjectQuery],
+ ]);
+
+ return mockApollo;
+ }
+
+ function createComponent({ mockApollo, props, mountFn = shallowMount } = {}) {
+ wrapper = mountFn(SourceBranchDropdown, {
+ localVue,
+ apolloProvider: mockApollo || createMockApolloProvider(),
+ propsData: props,
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when `selectedProject` prop is not specified', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('sets dropdown `disabled` prop to `true`', () => {
+ expect(findDropdown().props('disabled')).toBe(true);
+ });
+
+ describe('when `selectedProject` becomes specified', () => {
+ beforeEach(async () => {
+ wrapper.setProps({
+ selectedProject: mockProject,
+ });
+
+ await waitForPromises();
+ });
+
+ it('sets dropdown props correctly', () => {
+ expect(findDropdown().props()).toMatchObject({
+ loading: false,
+ disabled: false,
+ text: 'Select a branch',
+ });
+ });
+
+ it('renders available source branches as dropdown items', () => {
+ assertDropdownItems();
+ });
+ });
+ });
+
+ describe('when `selectedProject` prop is specified', () => {
+ describe('when branches are loading', () => {
+ it('renders loading icon in dropdown', () => {
+ createComponent({
+ mockApollo: createMockApolloProvider({ getProjectQueryLoading: true }),
+ props: { selectedProject: mockProject },
+ });
+
+ expect(findLoadingIcon().isVisible()).toBe(true);
+ });
+ });
+
+ describe('when branches have loaded', () => {
+ describe('when searching branches', () => {
+ it('triggers a refetch', async () => {
+ createComponent({ mountFn: mount, props: { selectedProject: mockProject } });
+ await waitForPromises();
+ jest.clearAllMocks();
+
+ const mockSearchTerm = 'mai';
+ await findSearchBox().vm.$emit('input', mockSearchTerm);
+
+ expect(mockGetProjectQuery).toHaveBeenCalledWith({
+ branchNamesLimit: BRANCHES_PER_PAGE,
+ branchNamesOffset: 0,
+ branchNamesSearchPattern: `*${mockSearchTerm}*`,
+ projectPath: 'test-path',
+ });
+ });
+ });
+
+ describe('template', () => {
+ beforeEach(async () => {
+ createComponent({ props: { selectedProject: mockProject } });
+ await waitForPromises();
+ });
+
+ it('sets dropdown props correctly', () => {
+ expect(findDropdown().props()).toMatchObject({
+ loading: false,
+ disabled: false,
+ text: 'Select a branch',
+ });
+ });
+
+ it('omits monospace styling from dropdown', () => {
+ expect(findDropdown().classes()).not.toContain('gl-font-monospace');
+ });
+
+ it('renders available source branches as dropdown items', () => {
+ assertDropdownItems();
+ });
+
+ it("emits `change` event with the repository's `rootRef` by default", () => {
+ expect(wrapper.emitted('change')[0]).toEqual([mockProject.repository.rootRef]);
+ });
+
+ describe('when selecting a dropdown item', () => {
+ it('emits `change` event with the selected branch name', async () => {
+ const mockBranchName = mockProject.repository.branchNames[1];
+ const itemToSelect = findDropdownItemByText(mockBranchName);
+ await itemToSelect.vm.$emit('click');
+
+ expect(wrapper.emitted('change')[1]).toEqual([mockBranchName]);
+ });
+ });
+
+ describe('when `selectedBranchName` prop is specified', () => {
+ const mockBranchName = mockProject.repository.branchNames[2];
+
+ beforeEach(async () => {
+ wrapper.setProps({
+ selectedBranchName: mockBranchName,
+ });
+ });
+
+ it('sets `isChecked` prop of the corresponding dropdown item to `true`', () => {
+ expect(findDropdownItemByText(mockBranchName).props('isChecked')).toBe(true);
+ });
+
+ it('sets dropdown text to `selectedBranchName` value', () => {
+ expect(findDropdown().props('text')).toBe(mockBranchName);
+ });
+
+ it('adds monospace styling to dropdown', () => {
+ expect(findDropdown().classes()).toContain('gl-font-monospace');
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/jira_connect/components/groups_list_spec.js b/spec/frontend/jira_connect/components/groups_list_spec.js
index 4b875928a90..d583fb68771 100644
--- a/spec/frontend/jira_connect/components/groups_list_spec.js
+++ b/spec/frontend/jira_connect/components/groups_list_spec.js
@@ -160,9 +160,13 @@ describe('GroupsList', () => {
expect(findGroupsList().classes()).toContain('gl-opacity-5');
});
- it('sets loading prop of ths search box', () => {
+ it('sets loading prop of the search box', () => {
expect(findSearchBox().props('isLoading')).toBe(true);
});
+
+ it('sets value prop of the search box to the search term', () => {
+ expect(findSearchBox().props('value')).toBe(mockSearchTeam);
+ });
});
describe('when group search finishes loading', () => {