diff options
Diffstat (limited to 'spec/frontend/work_items/pages/work_item_detail_spec.js')
-rw-r--r-- | spec/frontend/work_items/pages/work_item_detail_spec.js | 135 |
1 files changed, 129 insertions, 6 deletions
diff --git a/spec/frontend/work_items/pages/work_item_detail_spec.js b/spec/frontend/work_items/pages/work_item_detail_spec.js index b9724034cb4..43869468ad0 100644 --- a/spec/frontend/work_items/pages/work_item_detail_spec.js +++ b/spec/frontend/work_items/pages/work_item_detail_spec.js @@ -1,26 +1,36 @@ -import { GlAlert, GlSkeletonLoader } from '@gitlab/ui'; +import { GlAlert, GlSkeletonLoader, GlButton } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; +import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue'; import WorkItemDetail from '~/work_items/components/work_item_detail.vue'; import WorkItemDescription from '~/work_items/components/work_item_description.vue'; import WorkItemState from '~/work_items/components/work_item_state.vue'; import WorkItemTitle from '~/work_items/components/work_item_title.vue'; import WorkItemAssignees from '~/work_items/components/work_item_assignees.vue'; +import WorkItemLabels from '~/work_items/components/work_item_labels.vue'; import WorkItemWeight from '~/work_items/components/work_item_weight.vue'; +import WorkItemInformation from '~/work_items/components/work_item_information.vue'; import { i18n } from '~/work_items/constants'; import workItemQuery from '~/work_items/graphql/work_item.query.graphql'; import workItemTitleSubscription from '~/work_items/graphql/work_item_title.subscription.graphql'; import { temporaryConfig } from '~/work_items/graphql/provider'; -import { workItemTitleSubscriptionResponse, workItemQueryResponse } from '../mock_data'; +import { useLocalStorageSpy } from 'helpers/local_storage_helper'; +import { + workItemTitleSubscriptionResponse, + workItemResponseFactory, + mockParent, +} from '../mock_data'; describe('WorkItemDetail component', () => { let wrapper; + useLocalStorageSpy(); Vue.use(VueApollo); + const workItemQueryResponse = workItemResponseFactory(); const successHandler = jest.fn().mockResolvedValue(workItemQueryResponse); const initialSubscriptionHandler = jest.fn().mockResolvedValue(workItemTitleSubscriptionResponse); @@ -30,9 +40,17 @@ describe('WorkItemDetail component', () => { const findWorkItemState = () => wrapper.findComponent(WorkItemState); const findWorkItemDescription = () => wrapper.findComponent(WorkItemDescription); const findWorkItemAssignees = () => wrapper.findComponent(WorkItemAssignees); + const findWorkItemLabels = () => wrapper.findComponent(WorkItemLabels); const findWorkItemWeight = () => wrapper.findComponent(WorkItemWeight); + const findParent = () => wrapper.find('[data-testid="work-item-parent"]'); + const findParentButton = () => findParent().findComponent(GlButton); + const findCloseButton = () => wrapper.find('[data-testid="work-item-close"]'); + const findWorkItemType = () => wrapper.find('[data-testid="work-item-type"]'); + const findWorkItemInformationAlert = () => wrapper.findComponent(WorkItemInformation); + const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync); const createComponent = ({ + isModal = false, workItemId = workItemQueryResponse.data.workItem.id, handler = successHandler, subscriptionHandler = initialSubscriptionHandler, @@ -50,7 +68,7 @@ describe('WorkItemDetail component', () => { typePolicies: includeWidgets ? temporaryConfig.cacheConfig.typePolicies : {}, }, ), - propsData: { workItemId }, + propsData: { isModal, workItemId }, provide: { glFeatures: { workItemsMvc2: workItemsMvc2Enabled, @@ -98,6 +116,36 @@ describe('WorkItemDetail component', () => { }); }); + describe('close button', () => { + describe('when isModal prop is false', () => { + it('does not render', async () => { + createComponent({ isModal: false }); + await waitForPromises(); + + expect(findCloseButton().exists()).toBe(false); + }); + }); + + describe('when isModal prop is true', () => { + it('renders', async () => { + createComponent({ isModal: true }); + await waitForPromises(); + + expect(findCloseButton().props('icon')).toBe('close'); + expect(findCloseButton().attributes('aria-label')).toBe('Close'); + }); + + it('emits `close` event when clicked', async () => { + createComponent({ isModal: true }); + await waitForPromises(); + + findCloseButton().vm.$emit('click'); + + expect(wrapper.emitted('close')).toEqual([[]]); + }); + }); + }); + describe('description', () => { it('does not show description widget if loading description fails', () => { createComponent(); @@ -107,13 +155,56 @@ describe('WorkItemDetail component', () => { it('shows description widget if description loads', async () => { createComponent(); - await waitForPromises(); expect(findWorkItemDescription().exists()).toBe(true); }); }); + describe('secondary breadcrumbs', () => { + it('does not show secondary breadcrumbs by default', () => { + createComponent(); + + expect(findParent().exists()).toBe(false); + }); + + it('does not show secondary breadcrumbs if there is not a parent', async () => { + createComponent(); + + await waitForPromises(); + + expect(findParent().exists()).toBe(false); + }); + + it('shows work item type if there is not a parent', async () => { + createComponent(); + + await waitForPromises(); + expect(findWorkItemType().exists()).toBe(true); + }); + + describe('with parent', () => { + beforeEach(() => { + const parentResponse = workItemResponseFactory(mockParent); + createComponent({ handler: jest.fn().mockResolvedValue(parentResponse) }); + + return waitForPromises(); + }); + + it('shows secondary breadcrumbs if there is a parent', () => { + expect(findParent().exists()).toBe(true); + }); + + it('does not show work item type', async () => { + expect(findWorkItemType().exists()).toBe(false); + }); + + it('sets the parent breadcrumb URL', () => { + expect(findParentButton().attributes().href).toBe('../../issues/5'); + }); + }); + }); + it('shows an error message when the work item query was unsuccessful', async () => { const errorHandler = jest.fn().mockRejectedValue('Oops'); createComponent({ handler: errorHandler }); @@ -145,7 +236,6 @@ describe('WorkItemDetail component', () => { it('renders assignees component when assignees widget is returned from the API', async () => { createComponent({ workItemsMvc2Enabled: true, - includeWidgets: true, }); await waitForPromises(); @@ -155,7 +245,9 @@ describe('WorkItemDetail component', () => { it('does not render assignees component when assignees widget is not returned from the API', async () => { createComponent({ workItemsMvc2Enabled: true, - includeWidgets: false, + handler: jest + .fn() + .mockResolvedValue(workItemResponseFactory({ assigneesWidgetPresent: false })), }); await waitForPromises(); @@ -170,6 +262,19 @@ describe('WorkItemDetail component', () => { expect(findWorkItemAssignees().exists()).toBe(false); }); + describe('labels widget', () => { + it.each` + description | includeWidgets | exists + ${'renders when widget is returned from API'} | ${true} | ${true} + ${'does not render when widget is not returned from API'} | ${false} | ${false} + `('$description', async ({ includeWidgets, exists }) => { + createComponent({ includeWidgets, workItemsMvc2Enabled: true }); + await waitForPromises(); + + expect(findWorkItemLabels().exists()).toBe(exists); + }); + }); + describe('weight widget', () => { describe('when work_items_mvc_2 feature flag is enabled', () => { describe.each` @@ -201,4 +306,22 @@ describe('WorkItemDetail component', () => { }); }); }); + + describe('work item information', () => { + beforeEach(() => { + createComponent(); + return waitForPromises(); + }); + + it('is visible when viewed for the first time and sets localStorage value', async () => { + localStorage.clear(); + expect(findWorkItemInformationAlert().exists()).toBe(true); + expect(findLocalStorageSync().props('value')).toBe(true); + }); + + it('is not visible after reading local storage input', async () => { + await findLocalStorageSync().vm.$emit('input', false); + expect(findWorkItemInformationAlert().exists()).toBe(false); + }); + }); }); |