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:
Diffstat (limited to 'spec/frontend/issues/show/components/incidents')
-rw-r--r--spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js8
-rw-r--r--spec/frontend/issues/show/components/incidents/incident_tabs_spec.js83
-rw-r--r--spec/frontend/issues/show/components/incidents/mock_data.js21
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js41
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js27
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js17
6 files changed, 161 insertions, 36 deletions
diff --git a/spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js b/spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js
index 4c1638a9147..81c3c30bf8a 100644
--- a/spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js
+++ b/spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js
@@ -40,5 +40,13 @@ describe('Edit Timeline events', () => {
expect(wrapper.emitted()).toEqual(cancelEvent);
});
+
+ it('should emit the delete event', async () => {
+ const deleteEvent = { delete: [[]] };
+
+ await findTimelineEventsForm().vm.$emit('delete');
+
+ expect(wrapper.emitted()).toEqual(deleteEvent);
+ });
});
});
diff --git a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
index 458c1c3f858..33a3a6eddfc 100644
--- a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
+++ b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
@@ -1,10 +1,11 @@
-import { GlTab } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import merge from 'lodash/merge';
+import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import DescriptionComponent from '~/issues/show/components/description.vue';
import HighlightBar from '~/issues/show/components/incidents/highlight_bar.vue';
-import IncidentTabs from '~/issues/show/components/incidents/incident_tabs.vue';
+import IncidentTabs, {
+ incidentTabsI18n,
+} from '~/issues/show/components/incidents/incident_tabs.vue';
import INVALID_URL from '~/lib/utils/invalid_url';
import Tracking from '~/tracking';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
@@ -16,11 +17,24 @@ const mockAlert = {
iid: '1',
};
+const defaultMocks = {
+ $apollo: {
+ queries: {
+ alert: {
+ loading: true,
+ },
+ timelineEvents: {
+ loading: false,
+ },
+ },
+ },
+};
+
describe('Incident Tabs component', () => {
let wrapper;
- const mountComponent = (data = {}, options = {}) => {
- wrapper = shallowMount(
+ const mountComponent = ({ data = {}, options = {}, mount = shallowMountExtended } = {}) => {
+ wrapper = mount(
IncidentTabs,
merge(
{
@@ -29,7 +43,7 @@ describe('Incident Tabs component', () => {
},
stubs: {
DescriptionComponent: true,
- MetricsTab: true,
+ IncidentMetricTab: true,
},
provide: {
fullPath: '',
@@ -37,41 +51,37 @@ describe('Incident Tabs component', () => {
projectId: '',
issuableId: '',
uploadMetricsFeatureAvailable: true,
+ slaFeatureAvailable: true,
+ canUpdate: true,
+ canUpdateTimelineEvent: true,
},
data() {
return { alert: mockAlert, ...data };
},
- mocks: {
- $apollo: {
- queries: {
- alert: {
- loading: true,
- },
- timelineEvents: {
- loading: false,
- },
- },
- },
- },
+ mocks: defaultMocks,
},
options,
),
);
};
- const findTabs = () => wrapper.findAllComponents(GlTab);
- const findSummaryTab = () => findTabs().at(0);
- const findAlertDetailsTab = () => wrapper.find('[data-testid="alert-details-tab"]');
+ const findSummaryTab = () => wrapper.findByTestId('summary-tab');
+ const findTimelineTab = () => wrapper.findByTestId('timeline-tab');
+ const findAlertDetailsTab = () => wrapper.findByTestId('alert-details-tab');
const findAlertDetailsComponent = () => wrapper.findComponent(AlertDetailsTable);
const findDescriptionComponent = () => wrapper.findComponent(DescriptionComponent);
const findHighlightBarComponent = () => wrapper.findComponent(HighlightBar);
+ const findTabButtonByFilter = (filter) => wrapper.findAllByRole('tab').filter(filter);
+ const findTimelineTabButton = () =>
+ findTabButtonByFilter((inner) => inner.text() === incidentTabsI18n.timelineTitle).at(0);
+ const findActiveTabs = () => findTabButtonByFilter((inner) => inner.classes('active'));
- describe('empty state', () => {
+ describe('with no alerts', () => {
beforeEach(() => {
- mountComponent({ alert: null });
+ mountComponent({ data: { alert: null } });
});
- it('does not show the alert details tab', () => {
+ it('does not show the alert details tab option', () => {
expect(findAlertDetailsComponent().exists()).toBe(false);
});
});
@@ -83,7 +93,12 @@ describe('Incident Tabs component', () => {
it('renders the summary tab', () => {
expect(findSummaryTab().exists()).toBe(true);
- expect(findSummaryTab().attributes('title')).toBe('Summary');
+ expect(findSummaryTab().attributes('title')).toBe(incidentTabsI18n.summaryTitle);
+ });
+
+ it('renders the timeline tab', () => {
+ expect(findTimelineTab().exists()).toBe(true);
+ expect(findTimelineTab().attributes('title')).toBe(incidentTabsI18n.timelineTitle);
});
it('renders the alert details tab', () => {
@@ -125,4 +140,22 @@ describe('Incident Tabs component', () => {
expect(Tracking.event).toHaveBeenCalledWith(category, action);
});
});
+
+ describe('tab changing', () => {
+ beforeEach(() => {
+ mountComponent({ mount: mountExtended });
+ });
+
+ it('shows only the summary tab by default', async () => {
+ expect(findActiveTabs()).toHaveLength(1);
+ expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.summaryTitle);
+ });
+
+ it("shows the timeline tab after it's clicked", async () => {
+ await findTimelineTabButton().trigger('click');
+
+ expect(findActiveTabs()).toHaveLength(1);
+ expect(findActiveTabs().at(0).text()).toBe(incidentTabsI18n.timelineTitle);
+ });
+ });
});
diff --git a/spec/frontend/issues/show/components/incidents/mock_data.js b/spec/frontend/issues/show/components/incidents/mock_data.js
index adea2b6df59..9accfcea791 100644
--- a/spec/frontend/issues/show/components/incidents/mock_data.js
+++ b/spec/frontend/issues/show/components/incidents/mock_data.js
@@ -13,6 +13,9 @@ export const mockEvents = [
noteHtml: '<p>Dummy event 1</p>',
occurredAt: '2022-03-22T15:59:00Z',
updatedAt: '2022-03-22T15:59:08Z',
+ timelineEventTags: {
+ nodes: [],
+ },
__typename: 'TimelineEventType',
},
{
@@ -29,6 +32,18 @@ export const mockEvents = [
noteHtml: '<p>Dummy event 2</p>',
occurredAt: '2022-03-23T14:57:00Z',
updatedAt: '2022-03-23T14:57:08Z',
+ timelineEventTags: {
+ nodes: [
+ {
+ id: 'gid://gitlab/IncidentManagement::TimelineEvent/132',
+ name: 'Start time',
+ },
+ {
+ id: 'gid://gitlab/IncidentManagement::TimelineEvent/132',
+ name: 'End time',
+ },
+ ],
+ },
__typename: 'TimelineEventType',
},
{
@@ -45,6 +60,9 @@ export const mockEvents = [
noteHtml: '<p>Dummy event 3</p>',
occurredAt: '2022-03-23T15:59:00Z',
updatedAt: '2022-03-23T15:59:08Z',
+ timelineEventTags: {
+ nodes: [],
+ },
__typename: 'TimelineEventType',
},
];
@@ -152,6 +170,9 @@ export const mockGetTimelineData = {
action: 'comment',
occurredAt: '2022-07-01T12:47:00Z',
createdAt: '2022-07-20T12:47:40Z',
+ timelineEventTags: {
+ nodes: [],
+ },
},
],
},
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
index 0ce3f75f576..d5b199cc790 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js
@@ -22,11 +22,12 @@ describe('Timeline events form', () => {
useFakeDate(fakeDate);
let wrapper;
- const mountComponent = ({ mountMethod = shallowMountExtended } = {}) => {
+ const mountComponent = ({ mountMethod = shallowMountExtended } = {}, props = {}) => {
wrapper = mountMethod(TimelineEventsForm, {
propsData: {
showSaveAndAdd: true,
isEventProcessed: false,
+ ...props,
},
stubs: {
GlButton: true,
@@ -43,6 +44,7 @@ describe('Timeline events form', () => {
const findSubmitButton = () => wrapper.findByText(timelineFormI18n.save);
const findSubmitAndAddButton = () => wrapper.findByText(timelineFormI18n.saveAndAdd);
const findCancelButton = () => wrapper.findByText(timelineFormI18n.cancel);
+ const findDeleteButton = () => wrapper.findByText(timelineFormI18n.delete);
const findDatePicker = () => wrapper.findComponent(GlDatepicker);
const findHourInput = () => wrapper.findByTestId('input-hours');
const findMinuteInput = () => wrapper.findByTestId('input-minutes');
@@ -68,6 +70,9 @@ describe('Timeline events form', () => {
findCancelButton().vm.$emit('click');
await waitForPromises();
};
+ const deleteForm = () => {
+ findDeleteButton().vm.$emit('click');
+ };
it('renders markdown-field component with correct list of toolbar items', () => {
mountComponent({ mountMethod: mountExtended });
@@ -165,4 +170,38 @@ describe('Timeline events form', () => {
expect(findSubmitAndAddButton().props('disabled')).toBe(true);
});
});
+
+ describe('Delete button', () => {
+ it('does not show the delete button if showDelete prop is false', () => {
+ mountComponent({ mountMethod: mountExtended }, { showDelete: false });
+
+ expect(findDeleteButton().exists()).toBe(false);
+ });
+
+ it('shows the delete button if showDelete prop is true', () => {
+ mountComponent({ mountMethod: mountExtended }, { showDelete: true });
+
+ expect(findDeleteButton().exists()).toBe(true);
+ });
+
+ it('disables the delete button if isEventProcessed prop is true', () => {
+ mountComponent({ mountMethod: mountExtended }, { showDelete: true, isEventProcessed: true });
+
+ expect(findDeleteButton().props('disabled')).toBe(true);
+ });
+
+ it('does not disable the delete button if isEventProcessed prop is false', () => {
+ mountComponent({ mountMethod: mountExtended }, { showDelete: true, isEventProcessed: false });
+
+ expect(findDeleteButton().props('disabled')).toBe(false);
+ });
+
+ it('emits delete event on click', () => {
+ mountComponent({ mountMethod: mountExtended }, { showDelete: true, isEventProcessed: true });
+
+ deleteForm();
+
+ expect(wrapper.emitted('delete')).toEqual([[]]);
+ });
+ });
});
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js
index 1bf8d68efd4..ba0527e5395 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js
@@ -1,5 +1,5 @@
import timezoneMock from 'timezone-mock';
-import { GlIcon, GlDropdown } from '@gitlab/ui';
+import { GlIcon, GlDropdown, GlBadge } from '@gitlab/ui';
import { nextTick } from 'vue';
import { timelineItemI18n } from '~/issues/show/components/incidents/constants';
import { mountExtended } from 'helpers/vue_test_utils_helper';
@@ -27,25 +27,24 @@ describe('IncidentTimelineEventList', () => {
const findCommentIcon = () => wrapper.findComponent(GlIcon);
const findEventTime = () => wrapper.findByTestId('event-time');
+ const findEventTag = () => wrapper.findComponent(GlBadge);
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDeleteButton = () => wrapper.findByText(timelineItemI18n.delete);
describe('template', () => {
- it('shows comment icon', () => {
+ beforeEach(() => {
mountComponent();
+ });
+ it('shows comment icon', () => {
expect(findCommentIcon().exists()).toBe(true);
});
it('sets correct props for icon', () => {
- mountComponent();
-
expect(findCommentIcon().props('name')).toBe(mockEvents[0].action);
});
it('displays the correct time', () => {
- mountComponent();
-
expect(findEventTime().text()).toBe('15:59 UTC');
});
@@ -58,8 +57,6 @@ describe('IncidentTimelineEventList', () => {
describe(timezone, () => {
beforeEach(() => {
timezoneMock.register(timezone);
-
- mountComponent();
});
afterEach(() => {
@@ -72,10 +69,20 @@ describe('IncidentTimelineEventList', () => {
});
});
+ describe('timeline event tag', () => {
+ it('does not show when tag is not provided', () => {
+ expect(findEventTag().exists()).toBe(false);
+ });
+
+ it('shows when tag is provided', () => {
+ mountComponent({ propsData: { eventTag: 'Start time' } });
+
+ expect(findEventTag().exists()).toBe(true);
+ });
+ });
+
describe('action dropdown', () => {
it('does not show the action dropdown by default', () => {
- mountComponent();
-
expect(findDropdown().exists()).toBe(false);
expect(findDeleteButton().exists()).toBe(false);
});
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js
index dff1c429d07..a7250e8ad0d 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js
@@ -92,6 +92,9 @@ describe('IncidentTimelineEventList', () => {
expect(findItems().at(1).props('occurredAt')).toBe(mockEvents[1].occurredAt);
expect(findItems().at(1).props('action')).toBe(mockEvents[1].action);
expect(findItems().at(1).props('noteHtml')).toBe(mockEvents[1].noteHtml);
+ expect(findItems().at(1).props('eventTag')).toBe(
+ mockEvents[1].timelineEventTags.nodes[0].name,
+ );
});
it('formats dates correctly', () => {
@@ -120,6 +123,20 @@ describe('IncidentTimelineEventList', () => {
});
});
+ describe('getFirstTag', () => {
+ it('returns undefined, when timelineEventTags contains an empty array', () => {
+ const returnedTag = wrapper.vm.getFirstTag(mockEvents[0].timelineEventTags);
+
+ expect(returnedTag).toEqual(undefined);
+ });
+
+ it('returns the first string, when timelineEventTags contains array with at least one tag', () => {
+ const returnedTag = wrapper.vm.getFirstTag(mockEvents[1].timelineEventTags);
+
+ expect(returnedTag).toBe(mockEvents[1].timelineEventTags.nodes[0].name);
+ });
+ });
+
describe('delete functionality', () => {
beforeEach(() => {
mockConfirmAction({ confirmed: true });