diff options
Diffstat (limited to 'spec/frontend/jira_connect')
-rw-r--r-- | spec/frontend/jira_connect/api_spec.js | 2 | ||||
-rw-r--r-- | spec/frontend/jira_connect/components/app_spec.js | 36 | ||||
-rw-r--r-- | spec/frontend/jira_connect/components/groups_list_item_spec.js | 109 | ||||
-rw-r--r-- | spec/frontend/jira_connect/components/groups_list_spec.js | 30 | ||||
-rw-r--r-- | spec/frontend/jira_connect/index_spec.js | 56 | ||||
-rw-r--r-- | spec/frontend/jira_connect/mock_data.js | 2 |
6 files changed, 211 insertions, 24 deletions
diff --git a/spec/frontend/jira_connect/api_spec.js b/spec/frontend/jira_connect/api_spec.js index 8fecbee9ca7..f98d56a6621 100644 --- a/spec/frontend/jira_connect/api_spec.js +++ b/spec/frontend/jira_connect/api_spec.js @@ -14,7 +14,7 @@ describe('JiraConnect API', () => { const mockJwt = 'jwt'; const mockResponse = { success: true }; - const tokenSpy = jest.fn().mockReturnValue(mockJwt); + const tokenSpy = jest.fn((callback) => callback(mockJwt)); window.AP = { context: { diff --git a/spec/frontend/jira_connect/components/app_spec.js b/spec/frontend/jira_connect/components/app_spec.js index be990d5061c..a9194cfc883 100644 --- a/spec/frontend/jira_connect/components/app_spec.js +++ b/spec/frontend/jira_connect/components/app_spec.js @@ -1,19 +1,20 @@ -import Vue from 'vue'; -import Vuex from 'vuex'; import { shallowMount } from '@vue/test-utils'; +import { GlAlert, GlButton, GlModal } from '@gitlab/ui'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import { GlAlert } from '@gitlab/ui'; + import JiraConnectApp from '~/jira_connect/components/app.vue'; import createStore from '~/jira_connect/store'; import { SET_ERROR_MESSAGE } from '~/jira_connect/store/mutation_types'; -Vue.use(Vuex); +jest.mock('~/jira_connect/api'); describe('JiraConnectApp', () => { let wrapper; let store; const findAlert = () => wrapper.findComponent(GlAlert); + const findGlButton = () => wrapper.findComponent(GlButton); + const findGlModal = () => wrapper.findComponent(GlModal); const findHeader = () => wrapper.findByTestId('new-jira-connect-ui-heading'); const findHeaderText = () => findHeader().text(); @@ -44,6 +45,33 @@ describe('JiraConnectApp', () => { expect(findHeaderText()).toBe('Linked namespaces'); }); + describe('when user is not logged in', () => { + beforeEach(() => { + createComponent({ + provide: { + glFeatures: { newJiraConnectUi: true }, + usersPath: '/users', + }, + }); + }); + + it('renders "Sign in" button', () => { + expect(findGlButton().text()).toBe('Sign in to add namespaces'); + expect(findGlModal().exists()).toBe(false); + }); + }); + + describe('when user is logged in', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders "Add" button and modal', () => { + expect(findGlButton().text()).toBe('Add namespace'); + expect(findGlModal().exists()).toBe(true); + }); + }); + describe('newJiraConnectUi is false', () => { it('does not render new UI', () => { createComponent({ diff --git a/spec/frontend/jira_connect/components/groups_list_item_spec.js b/spec/frontend/jira_connect/components/groups_list_item_spec.js index 77577c53cf4..2499be1ea5f 100644 --- a/spec/frontend/jira_connect/components/groups_list_item_spec.js +++ b/spec/frontend/jira_connect/components/groups_list_item_spec.js @@ -1,27 +1,37 @@ -import { shallowMount } from '@vue/test-utils'; -import { GlAvatar } from '@gitlab/ui'; +import { mount, shallowMount } from '@vue/test-utils'; +import { GlAvatar, GlButton } from '@gitlab/ui'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; -import { mockGroup1 } from '../mock_data'; +import waitForPromises from 'helpers/wait_for_promises'; import GroupsListItem from '~/jira_connect/components/groups_list_item.vue'; +import * as JiraConnectApi from '~/jira_connect/api'; +import { mockGroup1 } from '../mock_data'; describe('GroupsListItem', () => { let wrapper; + const mockSubscriptionPath = 'subscriptionPath'; - const createComponent = () => { + const reloadSpy = jest.fn(); + + global.AP = { + navigator: { + reload: reloadSpy, + }, + }; + + const createComponent = ({ mountFn = shallowMount } = {}) => { wrapper = extendedWrapper( - shallowMount(GroupsListItem, { + mountFn(GroupsListItem, { propsData: { group: mockGroup1, }, + provide: { + subscriptionsPath: mockSubscriptionPath, + }, }), ); }; - beforeEach(() => { - createComponent(); - }); - afterEach(() => { wrapper.destroy(); wrapper = null; @@ -30,17 +40,82 @@ describe('GroupsListItem', () => { const findGlAvatar = () => wrapper.find(GlAvatar); const findGroupName = () => wrapper.findByTestId('group-list-item-name'); const findGroupDescription = () => wrapper.findByTestId('group-list-item-description'); + const findLinkButton = () => wrapper.find(GlButton); + const clickLinkButton = () => findLinkButton().trigger('click'); - it('renders group avatar', () => { - expect(findGlAvatar().exists()).toBe(true); - expect(findGlAvatar().props('src')).toBe(mockGroup1.avatar_url); - }); + describe('template', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders group avatar', () => { + expect(findGlAvatar().exists()).toBe(true); + expect(findGlAvatar().props('src')).toBe(mockGroup1.avatar_url); + }); + + it('renders group name', () => { + expect(findGroupName().text()).toBe(mockGroup1.full_name); + }); - it('renders group name', () => { - expect(findGroupName().text()).toBe(mockGroup1.full_name); + it('renders group description', () => { + expect(findGroupDescription().text()).toBe(mockGroup1.description); + }); + + it('renders Link button', () => { + expect(findLinkButton().exists()).toBe(true); + expect(findLinkButton().text()).toBe('Link'); + }); }); - it('renders group description', () => { - expect(findGroupDescription().text()).toBe(mockGroup1.description); + describe('on Link button click', () => { + let addSubscriptionSpy; + + beforeEach(() => { + createComponent({ mountFn: mount }); + + addSubscriptionSpy = jest.spyOn(JiraConnectApi, 'addSubscription').mockResolvedValue(); + }); + + it('sets button to loading and sends request', async () => { + expect(findLinkButton().props('loading')).toBe(false); + + clickLinkButton(); + + await wrapper.vm.$nextTick(); + + expect(findLinkButton().props('loading')).toBe(true); + + expect(addSubscriptionSpy).toHaveBeenCalledWith(mockSubscriptionPath, mockGroup1.full_path); + }); + + describe('when request is successful', () => { + it('reloads the page', async () => { + clickLinkButton(); + + await waitForPromises(); + + expect(reloadSpy).toHaveBeenCalled(); + }); + }); + + describe('when request has errors', () => { + const mockErrorMessage = 'error message'; + const mockError = { response: { data: { error: mockErrorMessage } } }; + + beforeEach(() => { + addSubscriptionSpy = jest + .spyOn(JiraConnectApi, 'addSubscription') + .mockRejectedValue(mockError); + }); + + it('emits `error` event', async () => { + clickLinkButton(); + + await waitForPromises(); + + expect(reloadSpy).not.toHaveBeenCalled(); + expect(wrapper.emitted('error')[0][0]).toBe(mockErrorMessage); + }); + }); }); }); diff --git a/spec/frontend/jira_connect/components/groups_list_spec.js b/spec/frontend/jira_connect/components/groups_list_spec.js index 94f158e6344..b18a913ca6a 100644 --- a/spec/frontend/jira_connect/components/groups_list_spec.js +++ b/spec/frontend/jira_connect/components/groups_list_spec.js @@ -1,5 +1,5 @@ import { shallowMount } from '@vue/test-utils'; -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlAlert, GlLoadingIcon } from '@gitlab/ui'; import waitForPromises from 'helpers/wait_for_promises'; import { fetchGroups } from '~/jira_connect/api'; @@ -28,6 +28,7 @@ describe('GroupsList', () => { wrapper = null; }); + const findGlAlert = () => wrapper.find(GlAlert); const findGlLoadingIcon = () => wrapper.find(GlLoadingIcon); const findAllItems = () => wrapper.findAll(GroupsListItem); const findFirstItem = () => findAllItems().at(0); @@ -45,6 +46,18 @@ describe('GroupsList', () => { }); }); + describe('error fetching groups', () => { + it('renders error message', async () => { + fetchGroups.mockRejectedValue(); + createComponent(); + + await waitForPromises(); + + expect(findGlAlert().exists()).toBe(true); + expect(findGlAlert().text()).toBe('Failed to load namespaces. Please try again.'); + }); + }); + describe('no groups returned', () => { it('renders empty state', async () => { fetchGroups.mockResolvedValue(mockEmptyResponse); @@ -57,15 +70,28 @@ describe('GroupsList', () => { }); describe('with groups returned', () => { - it('renders groups list', async () => { + beforeEach(async () => { fetchGroups.mockResolvedValue({ data: [mockGroup1, mockGroup2] }); createComponent(); await waitForPromises(); + }); + it('renders groups list', () => { expect(findAllItems().length).toBe(2); expect(findFirstItem().props('group')).toBe(mockGroup1); expect(findSecondItem().props('group')).toBe(mockGroup2); }); + + it('shows error message on $emit from item', async () => { + const errorMessage = 'error message'; + + findFirstItem().vm.$emit('error', errorMessage); + + await wrapper.vm.$nextTick(); + + expect(findGlAlert().exists()).toBe(true); + expect(findGlAlert().text()).toContain(errorMessage); + }); }); }); diff --git a/spec/frontend/jira_connect/index_spec.js b/spec/frontend/jira_connect/index_spec.js new file mode 100644 index 00000000000..eb54fe6476f --- /dev/null +++ b/spec/frontend/jira_connect/index_spec.js @@ -0,0 +1,56 @@ +import waitForPromises from 'helpers/wait_for_promises'; +import { initJiraConnect } from '~/jira_connect'; +import { removeSubscription } from '~/jira_connect/api'; + +jest.mock('~/jira_connect/api', () => ({ + removeSubscription: jest.fn().mockResolvedValue(), + getLocation: jest.fn().mockResolvedValue('test/location'), +})); + +describe('initJiraConnect', () => { + window.AP = { + navigator: { + reload: jest.fn(), + }, + }; + + beforeEach(async () => { + setFixtures(` + <a class="js-jira-connect-sign-in" href="https://gitlab.com">Sign In</a> + <a class="js-jira-connect-sign-in" href="https://gitlab.com">Another Sign In</a> + + <a href="https://gitlab.com/sub1" class="js-jira-connect-remove-subscription">Remove</a> + <a href="https://gitlab.com/sub2" class="js-jira-connect-remove-subscription">Remove</a> + <a href="https://gitlab.com/sub3" class="js-jira-connect-remove-subscription">Remove</a> + `); + + await initJiraConnect(); + }); + + describe('Sign in links', () => { + it('have `return_to` query parameter', () => { + Array.from(document.querySelectorAll('.js-jira-connect-sign-in')).forEach((el) => { + expect(el.href).toContain('return_to=test/location'); + }); + }); + }); + + describe('`remove subscription` buttons', () => { + describe('on click', () => { + it('calls `removeSubscription`', () => { + Array.from(document.querySelectorAll('.js-jira-connect-remove-subscription')).forEach( + (removeSubscriptionButton) => { + removeSubscriptionButton.dispatchEvent(new Event('click')); + + waitForPromises(); + + expect(removeSubscription).toHaveBeenCalledWith(removeSubscriptionButton.href); + expect(removeSubscription).toHaveBeenCalledTimes(1); + + removeSubscription.mockClear(); + }, + ); + }); + }); + }); +}); diff --git a/spec/frontend/jira_connect/mock_data.js b/spec/frontend/jira_connect/mock_data.js index 31565912489..22255fabc3d 100644 --- a/spec/frontend/jira_connect/mock_data.js +++ b/spec/frontend/jira_connect/mock_data.js @@ -3,6 +3,7 @@ export const mockGroup1 = { avatar_url: 'avatar.png', name: 'Gitlab Org', full_name: 'Gitlab Org', + full_path: 'gitlab-org', description: 'Open source software to collaborate on code', }; @@ -11,5 +12,6 @@ export const mockGroup2 = { avatar_url: 'avatar.png', name: 'Gitlab Com', full_name: 'Gitlab Com', + full_path: 'gitlab-com', description: 'For GitLab company related projects', }; |