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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-30 21:09:50 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-30 21:09:50 +0300
commit6619ed911ffab93b90756bf392d2925fdc0c1ee2 (patch)
tree79d122438dd8e1cb672f8bb52b9d573bd49bdd77 /spec/frontend
parent4b1fc3dc32e768499d81ed64ea7ed497c1785c48 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/ide/components/preview/clientside_spec.js36
-rw-r--r--spec/frontend/ide/components/preview/navigator_spec.js20
-rw-r--r--spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js8
-rw-r--r--spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js44
-rw-r--r--spec/frontend/issues/show/components/incidents/mock_data.js37
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_form_spec.js6
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_item_spec.js16
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_list_spec.js112
-rw-r--r--spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js15
-rw-r--r--spec/frontend/issues/show/components/incidents/utils_spec.js6
-rw-r--r--spec/frontend/notebook/cells/output/html_sanitize_fixtures.js4
-rw-r--r--spec/frontend/notebook/cells/output/index_spec.js14
12 files changed, 223 insertions, 95 deletions
diff --git a/spec/frontend/ide/components/preview/clientside_spec.js b/spec/frontend/ide/components/preview/clientside_spec.js
index cf768114e70..51e6a9d9034 100644
--- a/spec/frontend/ide/components/preview/clientside_spec.js
+++ b/spec/frontend/ide/components/preview/clientside_spec.js
@@ -2,15 +2,15 @@ import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import { dispatch } from 'codesandbox-api';
-import smooshpack from 'smooshpack';
+import { SandpackClient } from '@codesandbox/sandpack-client';
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import Clientside from '~/ide/components/preview/clientside.vue';
import { PING_USAGE_PREVIEW_KEY, PING_USAGE_PREVIEW_SUCCESS_KEY } from '~/ide/constants';
import eventHub from '~/ide/eventhub';
-jest.mock('smooshpack', () => ({
- Manager: jest.fn(),
+jest.mock('@codesandbox/sandpack-client', () => ({
+ SandpackClient: jest.fn(),
}));
Vue.use(Vuex);
@@ -78,8 +78,8 @@ describe('IDE clientside preview', () => {
// eslint-disable-next-line no-restricted-syntax
wrapper.setData({
sandpackReady: true,
- manager: {
- listener: jest.fn(),
+ client: {
+ cleanup: jest.fn(),
updatePreview: jest.fn(),
},
});
@@ -90,9 +90,9 @@ describe('IDE clientside preview', () => {
});
describe('without main entry', () => {
- it('creates sandpack manager', () => {
+ it('creates sandpack client', () => {
createComponent();
- expect(smooshpack.Manager).not.toHaveBeenCalled();
+ expect(SandpackClient).not.toHaveBeenCalled();
});
});
describe('with main entry', () => {
@@ -102,8 +102,8 @@ describe('IDE clientside preview', () => {
return waitForPromises();
});
- it('creates sandpack manager', () => {
- expect(smooshpack.Manager).toHaveBeenCalledWith(
+ it('creates sandpack client', () => {
+ expect(SandpackClient).toHaveBeenCalledWith(
'#ide-preview',
expectedSandpackOptions(),
expectedSandpackSettings(),
@@ -141,8 +141,8 @@ describe('IDE clientside preview', () => {
return waitForPromises();
});
- it('creates sandpack manager with bundlerURL', () => {
- expect(smooshpack.Manager).toHaveBeenCalledWith('#ide-preview', expectedSandpackOptions(), {
+ it('creates sandpack client with bundlerURL', () => {
+ expect(SandpackClient).toHaveBeenCalledWith('#ide-preview', expectedSandpackOptions(), {
...expectedSandpackSettings(),
bundlerURL: TEST_BUNDLER_URL,
});
@@ -156,8 +156,8 @@ describe('IDE clientside preview', () => {
return waitForPromises();
});
- it('creates sandpack manager', () => {
- expect(smooshpack.Manager).toHaveBeenCalledWith(
+ it('creates sandpack client', () => {
+ expect(SandpackClient).toHaveBeenCalledWith(
'#ide-preview',
{
files: {},
@@ -332,7 +332,7 @@ describe('IDE clientside preview', () => {
});
describe('update', () => {
- it('initializes manager if manager is empty', () => {
+ it('initializes client if client is empty', () => {
createComponent({ getters: { packageJson: dummyPackageJson } });
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
@@ -340,7 +340,7 @@ describe('IDE clientside preview', () => {
wrapper.vm.update();
return waitForPromises().then(() => {
- expect(smooshpack.Manager).toHaveBeenCalled();
+ expect(SandpackClient).toHaveBeenCalled();
});
});
@@ -349,7 +349,7 @@ describe('IDE clientside preview', () => {
wrapper.vm.update();
- expect(wrapper.vm.manager.updatePreview).toHaveBeenCalledWith(wrapper.vm.sandboxOpts);
+ expect(wrapper.vm.client.updatePreview).toHaveBeenCalledWith(wrapper.vm.sandboxOpts);
});
});
@@ -361,7 +361,7 @@ describe('IDE clientside preview', () => {
});
it('calls updatePreview', () => {
- expect(wrapper.vm.manager.updatePreview).toHaveBeenCalledWith(wrapper.vm.sandboxOpts);
+ expect(wrapper.vm.client.updatePreview).toHaveBeenCalledWith(wrapper.vm.sandboxOpts);
});
});
});
@@ -405,7 +405,7 @@ describe('IDE clientside preview', () => {
beforeEach(() => {
createInitializedComponent();
- spy = wrapper.vm.manager.updatePreview;
+ spy = wrapper.vm.client.updatePreview;
wrapper.destroy();
});
diff --git a/spec/frontend/ide/components/preview/navigator_spec.js b/spec/frontend/ide/components/preview/navigator_spec.js
index 9c4f825ccf5..532cb6e795c 100644
--- a/spec/frontend/ide/components/preview/navigator_spec.js
+++ b/spec/frontend/ide/components/preview/navigator_spec.js
@@ -11,7 +11,7 @@ jest.mock('codesandbox-api', () => ({
describe('IDE clientside preview navigator', () => {
let wrapper;
- let manager;
+ let client;
let listenHandler;
const findBackButton = () => wrapper.findAll('button').at(0);
@@ -20,9 +20,9 @@ describe('IDE clientside preview navigator', () => {
beforeEach(() => {
listen.mockClear();
- manager = { bundlerURL: TEST_HOST, iframe: { src: '' } };
+ client = { bundlerURL: TEST_HOST, iframe: { src: '' } };
- wrapper = shallowMount(ClientsideNavigator, { propsData: { manager } });
+ wrapper = shallowMount(ClientsideNavigator, { propsData: { client } });
[[listenHandler]] = listen.mock.calls;
});
@@ -31,7 +31,7 @@ describe('IDE clientside preview navigator', () => {
});
it('renders readonly URL bar', async () => {
- listenHandler({ type: 'urlchange', url: manager.bundlerURL });
+ listenHandler({ type: 'urlchange', url: client.bundlerURL });
await nextTick();
expect(wrapper.find('input[readonly]').element.value).toBe('/');
});
@@ -89,13 +89,13 @@ describe('IDE clientside preview navigator', () => {
expect(findBackButton().attributes('disabled')).toBe('disabled');
});
- it('updates manager iframe src', async () => {
+ it('updates client iframe src', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
await nextTick();
findBackButton().trigger('click');
- expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
+ expect(client.iframe.src).toBe(`${TEST_HOST}/url1`);
});
});
@@ -133,13 +133,13 @@ describe('IDE clientside preview navigator', () => {
expect(findForwardButton().attributes('disabled')).toBe('disabled');
});
- it('updates manager iframe src', async () => {
+ it('updates client iframe src', async () => {
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url1` });
listenHandler({ type: 'urlchange', url: `${TEST_HOST}/url2` });
await nextTick();
findBackButton().trigger('click');
- expect(manager.iframe.src).toBe(`${TEST_HOST}/url1`);
+ expect(client.iframe.src).toBe(`${TEST_HOST}/url1`);
});
});
@@ -152,10 +152,10 @@ describe('IDE clientside preview navigator', () => {
});
it('calls refresh with current path', () => {
- manager.iframe.src = 'something-other';
+ client.iframe.src = 'something-other';
findRefreshButton().trigger('click');
- expect(manager.iframe.src).toBe(url);
+ expect(client.iframe.src).toBe(url);
});
});
});
diff --git a/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js b/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js
index 3ab2bb3460b..a277dd70764 100644
--- a/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js
+++ b/spec/frontend/issues/show/components/incidents/create_timeline_events_form_spec.js
@@ -42,17 +42,15 @@ describe('Create Timeline events', () => {
const findDatePicker = () => wrapper.findComponent(GlDatepicker);
const findNoteInput = () => wrapper.findByTestId('input-note');
const setNoteInput = () => {
- const textarea = findNoteInput().element;
- textarea.value = mockInputData.note;
- textarea.dispatchEvent(new Event('input'));
+ findNoteInput().setValue(mockInputData.note);
};
const findHourInput = () => wrapper.findByTestId('input-hours');
const findMinuteInput = () => wrapper.findByTestId('input-minutes');
const setDatetime = () => {
const inputDate = new Date(mockInputData.occurredAt);
findDatePicker().vm.$emit('input', inputDate);
- findHourInput().vm.$emit('input', inputDate.getHours());
- findMinuteInput().vm.$emit('input', inputDate.getMinutes());
+ findHourInput().setValue(inputDate.getHours());
+ findMinuteInput().setValue(inputDate.getMinutes());
};
const fillForm = () => {
setDatetime();
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
new file mode 100644
index 00000000000..4c1638a9147
--- /dev/null
+++ b/spec/frontend/issues/show/components/incidents/edit_timeline_event_spec.js
@@ -0,0 +1,44 @@
+import EditTimelineEvent from '~/issues/show/components/incidents/edit_timeline_event.vue';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import TimelineEventsForm from '~/issues/show/components/incidents/timeline_events_form.vue';
+
+import { mockEvents, fakeEventData, mockInputData } from './mock_data';
+
+describe('Edit Timeline events', () => {
+ let wrapper;
+
+ const mountComponent = () => {
+ wrapper = mountExtended(EditTimelineEvent, {
+ propsData: {
+ event: mockEvents[0],
+ editTimelineEventActive: false,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ const findTimelineEventsForm = () => wrapper.findComponent(TimelineEventsForm);
+
+ const mockSaveData = { ...fakeEventData, ...mockInputData };
+
+ describe('editTimelineEvent', () => {
+ const saveEventEvent = { 'handle-save-edit': [[mockSaveData, false]] };
+
+ it('should call the mutation with the right variables', async () => {
+ await findTimelineEventsForm().vm.$emit('save-event', mockSaveData, false);
+
+ expect(wrapper.emitted()).toEqual(saveEventEvent);
+ });
+
+ it('should close the form on cancel', async () => {
+ const cancelEvent = { 'hide-edit': [[]] };
+
+ await findTimelineEventsForm().vm.$emit('cancel');
+
+ expect(wrapper.emitted()).toEqual(cancelEvent);
+ });
+ });
+});
diff --git a/spec/frontend/issues/show/components/incidents/mock_data.js b/spec/frontend/issues/show/components/incidents/mock_data.js
index fd26fd86ced..adea2b6df59 100644
--- a/spec/frontend/issues/show/components/incidents/mock_data.js
+++ b/spec/frontend/issues/show/components/incidents/mock_data.js
@@ -49,6 +49,15 @@ export const mockEvents = [
},
];
+const mockUpdatedEvent = {
+ id: 'gid://gitlab/IncidentManagement::TimelineEvent/8',
+ note: 'another one23',
+ noteHtml: '<p>another one23</p>',
+ action: 'comment',
+ occurredAt: '2022-07-01T12:47:00Z',
+ createdAt: '2022-07-20T12:47:40Z',
+};
+
export const timelineEventsQueryListResponse = {
data: {
project: {
@@ -93,6 +102,29 @@ export const timelineEventsCreateEventError = {
},
};
+export const timelineEventsEditEventResponse = {
+ data: {
+ timelineEventUpdate: {
+ timelineEvent: {
+ ...mockUpdatedEvent,
+ },
+ errors: [],
+ __typename: 'TimelineEventUpdatePayload',
+ },
+ },
+};
+
+export const timelineEventsEditEventError = {
+ data: {
+ timelineEventUpdate: {
+ timelineEvent: {
+ ...mockUpdatedEvent,
+ },
+ errors: ['Create error'],
+ },
+ },
+};
+
const timelineEventDeleteData = (errors = []) => {
return {
data: {
@@ -128,5 +160,10 @@ export const mockGetTimelineData = {
export const fakeDate = '2020-07-08T00:00:00.000Z';
+export const mockInputData = {
+ note: 'test',
+ occurredAt: '2020-08-10T02:30:00.000Z',
+};
+
const { id, note, occurredAt } = mockEvents[0];
export const fakeEventData = { id, note, occurredAt };
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 abe42dc3f28..d04d2965401 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
@@ -23,7 +23,7 @@ describe('Timeline events form', () => {
const mountComponent = ({ mountMethod = shallowMountExtended }) => {
wrapper = mountMethod(TimelineEventsForm, {
propsData: {
- hasTimelineEvents: true,
+ showSaveAndAdd: true,
isEventProcessed: false,
},
});
@@ -42,8 +42,8 @@ describe('Timeline events form', () => {
const findMinuteInput = () => wrapper.findByTestId('input-minutes');
const setDatetime = () => {
findDatePicker().vm.$emit('input', mockInputDate);
- findHourInput().vm.$emit('input', 5);
- findMinuteInput().vm.$emit('input', 45);
+ findHourInput().setValue(5);
+ findMinuteInput().setValue(45);
};
const submitForm = async () => {
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 90e55003ab3..9f1f6aff57e 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
@@ -15,7 +15,6 @@ describe('IncidentTimelineEventList', () => {
action,
noteHtml,
occurredAt,
- isLastItem: false,
...propsData,
},
provide: {
@@ -26,7 +25,6 @@ describe('IncidentTimelineEventList', () => {
};
const findCommentIcon = () => wrapper.findComponent(GlIcon);
- const findTextContainer = () => wrapper.findByTestId('event-text-container');
const findEventTime = () => wrapper.findByTestId('event-time');
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDeleteButton = () => wrapper.findByText('Delete');
@@ -50,20 +48,6 @@ describe('IncidentTimelineEventList', () => {
expect(findEventTime().text()).toBe('15:59 UTC');
});
- describe('last item in list', () => {
- it('shows a bottom border when not the last item', () => {
- mountComponent();
-
- expect(findTextContainer().classes()).toContain('gl-border-1');
- });
-
- it('does not show a bottom border when the last item', () => {
- mountComponent({ propsData: { isLastItem: true } });
-
- expect(wrapper.classes()).not.toContain('gl-border-1');
- });
- });
-
describe.each`
timezone
${'Europe/London'}
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 fe182016924..18bd91f0465 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
@@ -4,10 +4,11 @@ import Vue from 'vue';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import IncidentTimelineEventList from '~/issues/show/components/incidents/timeline_events_list.vue';
import IncidentTimelineEventItem from '~/issues/show/components/incidents/timeline_events_item.vue';
+import EditTimelineEvent from '~/issues/show/components/incidents/edit_timeline_event.vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import deleteTimelineEventMutation from '~/issues/show/components/incidents/graphql/queries/delete_timeline_event.mutation.graphql';
-import getTimelineEvents from '~/issues/show/components/incidents/graphql/queries/get_timeline_events.query.graphql';
+import editTimelineEventMutation from '~/issues/show/components/incidents/graphql/queries/edit_timeline_event.mutation.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import { useFakeDate } from 'helpers/fake_date';
import { createAlert } from '~/flash';
@@ -15,9 +16,11 @@ import {
mockEvents,
timelineEventsDeleteEventResponse,
timelineEventsDeleteEventError,
+ timelineEventsEditEventResponse,
+ timelineEventsEditEventError,
fakeDate,
fakeEventData,
- timelineEventsQueryListResponse,
+ mockInputData,
} from './mock_data';
Vue.use(VueApollo);
@@ -32,20 +35,15 @@ const mockConfirmAction = ({ confirmed }) => {
describe('IncidentTimelineEventList', () => {
useFakeDate(fakeDate);
let wrapper;
- const responseSpy = jest.fn().mockResolvedValue(timelineEventsDeleteEventResponse);
+ const deleteResponseSpy = jest.fn().mockResolvedValue(timelineEventsDeleteEventResponse);
+ const editResponseSpy = jest.fn().mockResolvedValue(timelineEventsEditEventResponse);
- const requestHandlers = [[deleteTimelineEventMutation, responseSpy]];
+ const requestHandlers = [
+ [deleteTimelineEventMutation, deleteResponseSpy],
+ [editTimelineEventMutation, editResponseSpy],
+ ];
const apolloProvider = createMockApollo(requestHandlers);
- apolloProvider.clients.defaultClient.cache.writeQuery({
- query: getTimelineEvents,
- data: timelineEventsQueryListResponse.data,
- variables: {
- fullPath: 'group/project',
- incidentId: 'gid://gitlab/Issue/1',
- },
- });
-
const mountComponent = () => {
wrapper = mountExtended(IncidentTimelineEventList, {
propsData: {
@@ -70,6 +68,10 @@ describe('IncidentTimelineEventList', () => {
await waitForPromises();
};
+ const clickFirstEditButton = async () => {
+ findItems().at(0).vm.$emit('edit');
+ await waitForPromises();
+ };
beforeEach(() => {
mountComponent();
});
@@ -86,12 +88,6 @@ describe('IncidentTimelineEventList', () => {
expect(findItems(findSecondTimelineEventGroup())).toHaveLength(2);
});
- it('sets the isLastItem prop correctly', () => {
- expect(findItems().at(0).props('isLastItem')).toBe(false);
- expect(findItems().at(1).props('isLastItem')).toBe(false);
- expect(findItems().at(2).props('isLastItem')).toBe(true);
- });
-
it('sets the event props correctly', () => {
expect(findItems().at(1).props('occurredAt')).toBe(mockEvents[1].occurredAt);
expect(findItems().at(1).props('action')).toBe(mockEvents[1].action);
@@ -133,7 +129,7 @@ describe('IncidentTimelineEventList', () => {
const expectedVars = { input: { id: mockEvents[0].id } };
await clickFirstDeleteButton();
- expect(responseSpy).toHaveBeenCalledWith(expectedVars);
+ expect(deleteResponseSpy).toHaveBeenCalledWith(expectedVars);
});
it('should show an error when delete returns an error', async () => {
@@ -141,7 +137,7 @@ describe('IncidentTimelineEventList', () => {
message: 'Error deleting incident timeline event: Item does not exist',
};
- responseSpy.mockResolvedValue(timelineEventsDeleteEventError);
+ deleteResponseSpy.mockResolvedValue(timelineEventsDeleteEventError);
await clickFirstDeleteButton();
@@ -154,7 +150,7 @@ describe('IncidentTimelineEventList', () => {
error: new Error(),
message: 'Something went wrong while deleting the incident timeline event.',
};
- responseSpy.mockRejectedValueOnce();
+ deleteResponseSpy.mockRejectedValueOnce();
await clickFirstDeleteButton();
@@ -162,4 +158,76 @@ describe('IncidentTimelineEventList', () => {
});
});
});
+
+ describe('Edit Functionality', () => {
+ beforeEach(() => {
+ mountComponent();
+ clickFirstEditButton();
+ });
+
+ const findEditEvent = () => wrapper.findComponent(EditTimelineEvent);
+ const mockSaveData = { ...fakeEventData, ...mockInputData };
+
+ describe('editTimelineEvent', () => {
+ it('should call the mutation with the right variables', async () => {
+ await findEditEvent().vm.$emit('handle-save-edit', mockSaveData);
+ await waitForPromises();
+
+ expect(editResponseSpy).toHaveBeenCalledWith({
+ input: mockSaveData,
+ });
+ });
+
+ it('should close the form on successful addition', async () => {
+ await findEditEvent().vm.$emit('handle-save-edit', mockSaveData);
+ await waitForPromises();
+
+ expect(findEditEvent().exists()).toBe(false);
+ });
+
+ it('should close the form on cancel', async () => {
+ await findEditEvent().vm.$emit('hide-edit');
+ await waitForPromises();
+
+ expect(findEditEvent().exists()).toBe(false);
+ });
+ });
+
+ describe('error handling', () => {
+ it('should show an error when submission returns an error', async () => {
+ const expectedAlertArgs = {
+ message: `Error updating incident timeline event: ${timelineEventsEditEventError.data.timelineEventUpdate.errors[0]}`,
+ };
+ editResponseSpy.mockResolvedValueOnce(timelineEventsEditEventError);
+
+ await findEditEvent().vm.$emit('handle-save-edit', mockSaveData);
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalledWith(expectedAlertArgs);
+ });
+
+ it('should show an error when submission fails', async () => {
+ const expectedAlertArgs = {
+ captureError: true,
+ error: new Error(),
+ message: 'Something went wrong while updating the incident timeline event.',
+ };
+ editResponseSpy.mockRejectedValueOnce();
+
+ await findEditEvent().vm.$emit('handle-save-edit', mockSaveData);
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalledWith(expectedAlertArgs);
+ });
+
+ it('should keep the form open on failed addition', async () => {
+ editResponseSpy.mockResolvedValueOnce(timelineEventsEditEventError);
+
+ await findEditEvent().vm.$emit('handle-save-edit', mockSaveData);
+ await waitForPromises();
+
+ expect(findEditEvent().exists()).toBe(true);
+ });
+ });
+ });
});
diff --git a/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js b/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js
index 2cdb971395d..f260b803b7a 100644
--- a/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js
+++ b/spec/frontend/issues/show/components/incidents/timeline_events_tab_spec.js
@@ -143,22 +143,13 @@ describe('TimelineEventsTab', () => {
});
it('should not show a form by default', () => {
- expect(findCreateTimelineEvent().isVisible()).toBe(false);
+ expect(findCreateTimelineEvent().exists()).toBe(false);
});
it('should show a form when button is clicked', async () => {
await findAddEventButton().trigger('click');
- expect(findCreateTimelineEvent().isVisible()).toBe(true);
- });
-
- it('should clear the form when button is clicked', async () => {
- const mockClear = jest.fn();
- wrapper.vm.$refs.createEventForm.clearForm = mockClear;
-
- await findAddEventButton().trigger('click');
-
- expect(mockClear).toHaveBeenCalled();
+ expect(findCreateTimelineEvent().exists()).toBe(true);
});
it('should hide the form when the hide event is emitted', async () => {
@@ -167,7 +158,7 @@ describe('TimelineEventsTab', () => {
await findCreateTimelineEvent().vm.$emit('hide-new-timeline-events-form');
- expect(findCreateTimelineEvent().isVisible()).toBe(false);
+ expect(findCreateTimelineEvent().exists()).toBe(false);
});
});
});
diff --git a/spec/frontend/issues/show/components/incidents/utils_spec.js b/spec/frontend/issues/show/components/incidents/utils_spec.js
index d3a86680f14..f0494591e95 100644
--- a/spec/frontend/issues/show/components/incidents/utils_spec.js
+++ b/spec/frontend/issues/show/components/incidents/utils_spec.js
@@ -2,7 +2,7 @@ import timezoneMock from 'timezone-mock';
import {
displayAndLogError,
getEventIcon,
- getUtcShiftedDateNow,
+ getUtcShiftedDate,
} from '~/issues/show/components/incidents/utils';
import { createAlert } from '~/flash';
@@ -34,7 +34,7 @@ describe('incident utils', () => {
});
});
- describe('getUtcShiftedDateNow', () => {
+ describe('getUtcShiftedDate', () => {
beforeEach(() => {
timezoneMock.register('US/Pacific');
});
@@ -46,7 +46,7 @@ describe('incident utils', () => {
it('should shift the date by the timezone offset', () => {
const date = new Date();
- const shiftedDate = getUtcShiftedDateNow();
+ const shiftedDate = getUtcShiftedDate();
expect(shiftedDate > date).toBe(true);
});
diff --git a/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js b/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
index 70c7f56b62f..296d01ddd99 100644
--- a/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
+++ b/spec/frontend/notebook/cells/output/html_sanitize_fixtures.js
@@ -38,7 +38,7 @@ export default [
'</tr>\n',
'</table>',
].join(''),
- output: '<table>',
+ output: '<table data-myattr=&quot;XSS&quot;>',
},
],
// Note: style is sanitized out
@@ -98,7 +98,7 @@ export default [
'</svg>',
].join(),
output:
- '<svg xmlns="http://www.w3.org/2000/svg" width="388.84pt" version="1.0" id="svg2" height="115.02pt">',
+ '<svg height=&quot;115.02pt&quot; id=&quot;svg2&quot; version=&quot;1.0&quot; width=&quot;388.84pt&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;>',
},
],
];
diff --git a/spec/frontend/notebook/cells/output/index_spec.js b/spec/frontend/notebook/cells/output/index_spec.js
index 4d1d03e5e34..97a7e22be60 100644
--- a/spec/frontend/notebook/cells/output/index_spec.js
+++ b/spec/frontend/notebook/cells/output/index_spec.js
@@ -49,15 +49,17 @@ describe('Output component', () => {
const htmlType = json.cells[4];
createComponent(htmlType.outputs[0]);
- expect(wrapper.findAll('p')).toHaveLength(1);
- expect(wrapper.text()).toContain('test');
+ const iframe = wrapper.find('iframe');
+ expect(iframe.exists()).toBe(true);
+ expect(iframe.element.getAttribute('sandbox')).toBe('');
+ expect(iframe.element.getAttribute('srcdoc')).toBe('<p>test</p>');
});
it('renders multiple raw HTML outputs', () => {
const htmlType = json.cells[4];
createComponent([htmlType.outputs[0], htmlType.outputs[0]]);
- expect(wrapper.findAll('p')).toHaveLength(2);
+ expect(wrapper.findAll('iframe')).toHaveLength(2);
});
});
@@ -84,7 +86,11 @@ describe('Output component', () => {
});
it('renders as an svg', () => {
- expect(wrapper.find('svg').exists()).toBe(true);
+ const iframe = wrapper.find('iframe');
+
+ expect(iframe.exists()).toBe(true);
+ expect(iframe.element.getAttribute('sandbox')).toBe('');
+ expect(iframe.element.getAttribute('srcdoc')).toBe('<svg></svg>');
});
});