2021-04-17 20:07:23 +05:30
|
|
|
import axios from 'axios';
|
|
|
|
import MockAdapter from 'axios-mock-adapter';
|
2022-07-16 23:28:13 +05:30
|
|
|
import Cookies from '~/lib/utils/cookies';
|
2023-04-23 21:23:45 +05:30
|
|
|
import { HTTP_STATUS_BAD_REQUEST, HTTP_STATUS_OK } from '~/lib/utils/http_status';
|
2021-04-17 20:07:23 +05:30
|
|
|
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
|
|
|
|
import testAction from 'helpers/vuex_action_helper';
|
2022-11-25 23:54:43 +05:30
|
|
|
import { createAlert } from '~/flash';
|
2021-04-17 20:07:23 +05:30
|
|
|
import { INTERACTIVE_RESOLVE_MODE, EDIT_RESOLVE_MODE } from '~/merge_conflicts/constants';
|
|
|
|
import * as actions from '~/merge_conflicts/store/actions';
|
|
|
|
import * as types from '~/merge_conflicts/store/mutation_types';
|
|
|
|
import { restoreFileLinesState, markLine, decorateFiles } from '~/merge_conflicts/utils';
|
|
|
|
|
|
|
|
jest.mock('~/flash.js');
|
|
|
|
jest.mock('~/merge_conflicts/utils');
|
2022-07-16 23:28:13 +05:30
|
|
|
jest.mock('~/lib/utils/cookies');
|
2021-04-17 20:07:23 +05:30
|
|
|
|
|
|
|
describe('merge conflicts actions', () => {
|
|
|
|
let mock;
|
|
|
|
|
|
|
|
const files = [
|
|
|
|
{
|
|
|
|
blobPath: 'a',
|
|
|
|
},
|
|
|
|
{ blobPath: 'b' },
|
|
|
|
];
|
|
|
|
|
|
|
|
beforeEach(() => {
|
|
|
|
mock = new MockAdapter(axios);
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
mock.restore();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('fetchConflictsData', () => {
|
|
|
|
const conflictsPath = 'conflicts/path/mock';
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
it('on success dispatches setConflictsData', () => {
|
2023-04-23 21:23:45 +05:30
|
|
|
mock.onGet(conflictsPath).reply(HTTP_STATUS_OK, {});
|
2022-06-21 17:19:12 +05:30
|
|
|
return testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.fetchConflictsData,
|
|
|
|
conflictsPath,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{ type: types.SET_LOADING_STATE, payload: true },
|
|
|
|
{ type: types.SET_LOADING_STATE, payload: false },
|
|
|
|
],
|
|
|
|
[{ type: 'setConflictsData', payload: {} }],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2022-10-11 01:57:18 +05:30
|
|
|
it('when data has type equal to error', () => {
|
2023-04-23 21:23:45 +05:30
|
|
|
mock.onGet(conflictsPath).reply(HTTP_STATUS_OK, { type: 'error', message: 'error message' });
|
2022-06-21 17:19:12 +05:30
|
|
|
return testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.fetchConflictsData,
|
|
|
|
conflictsPath,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{ type: types.SET_LOADING_STATE, payload: true },
|
|
|
|
{ type: types.SET_FAILED_REQUEST, payload: 'error message' },
|
|
|
|
{ type: types.SET_LOADING_STATE, payload: false },
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2022-10-11 01:57:18 +05:30
|
|
|
it('when request fails', () => {
|
2023-04-23 21:23:45 +05:30
|
|
|
mock.onGet(conflictsPath).reply(HTTP_STATUS_BAD_REQUEST);
|
2022-06-21 17:19:12 +05:30
|
|
|
return testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.fetchConflictsData,
|
|
|
|
conflictsPath,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{ type: types.SET_LOADING_STATE, payload: true },
|
|
|
|
{ type: types.SET_FAILED_REQUEST },
|
|
|
|
{ type: types.SET_LOADING_STATE, payload: false },
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
describe('setConflictsData', () => {
|
2022-10-11 01:57:18 +05:30
|
|
|
it('INTERACTIVE_RESOLVE_MODE updates the correct file', () => {
|
2021-04-29 21:17:54 +05:30
|
|
|
decorateFiles.mockReturnValue([{ bar: 'baz' }]);
|
2022-06-21 17:19:12 +05:30
|
|
|
return testAction(
|
2021-04-29 21:17:54 +05:30
|
|
|
actions.setConflictsData,
|
|
|
|
{ files, foo: 'bar' },
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.SET_CONFLICTS_DATA,
|
|
|
|
payload: { foo: 'bar', files: [{ bar: 'baz' }] },
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-04-17 20:07:23 +05:30
|
|
|
describe('submitResolvedConflicts', () => {
|
|
|
|
useMockLocationHelper();
|
|
|
|
const resolveConflictsPath = 'resolve/conflicts/path/mock';
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
it('on success reloads the page', async () => {
|
2023-04-23 21:23:45 +05:30
|
|
|
mock.onPost(resolveConflictsPath).reply(HTTP_STATUS_OK, { redirect_to: 'hrefPath' });
|
2022-06-21 17:19:12 +05:30
|
|
|
await testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.submitResolvedConflicts,
|
|
|
|
resolveConflictsPath,
|
|
|
|
{},
|
|
|
|
[{ type: types.SET_SUBMIT_STATE, payload: true }],
|
|
|
|
[],
|
|
|
|
);
|
2022-06-21 17:19:12 +05:30
|
|
|
expect(window.location.assign).toHaveBeenCalledWith('hrefPath');
|
2021-04-17 20:07:23 +05:30
|
|
|
});
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
it('on errors shows flash', async () => {
|
2023-04-23 21:23:45 +05:30
|
|
|
mock.onPost(resolveConflictsPath).reply(HTTP_STATUS_BAD_REQUEST);
|
2022-06-21 17:19:12 +05:30
|
|
|
await testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.submitResolvedConflicts,
|
|
|
|
resolveConflictsPath,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{ type: types.SET_SUBMIT_STATE, payload: true },
|
|
|
|
{ type: types.SET_SUBMIT_STATE, payload: false },
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(createAlert).toHaveBeenCalledWith({
|
2022-06-21 17:19:12 +05:30
|
|
|
message: 'Failed to save merge conflicts resolutions. Please try again!',
|
|
|
|
});
|
2021-04-17 20:07:23 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-04-29 21:17:54 +05:30
|
|
|
describe('setLoadingState', () => {
|
|
|
|
it('commits the right mutation', () => {
|
2021-04-17 20:07:23 +05:30
|
|
|
testAction(
|
2021-04-29 21:17:54 +05:30
|
|
|
actions.setLoadingState,
|
|
|
|
true,
|
2021-04-17 20:07:23 +05:30
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
2021-04-29 21:17:54 +05:30
|
|
|
type: types.SET_LOADING_STATE,
|
|
|
|
payload: true,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setErrorState', () => {
|
|
|
|
it('commits the right mutation', () => {
|
|
|
|
testAction(
|
|
|
|
actions.setErrorState,
|
|
|
|
true,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.SET_ERROR_STATE,
|
|
|
|
payload: true,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setFailedRequest', () => {
|
|
|
|
it('commits the right mutation', () => {
|
|
|
|
testAction(
|
|
|
|
actions.setFailedRequest,
|
|
|
|
'errors in the request',
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.SET_FAILED_REQUEST,
|
|
|
|
payload: 'errors in the request',
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setViewType', () => {
|
2022-06-21 17:19:12 +05:30
|
|
|
it('commits the right mutation', async () => {
|
2021-04-29 21:17:54 +05:30
|
|
|
const payload = 'viewType';
|
2022-06-21 17:19:12 +05:30
|
|
|
await testAction(
|
2021-04-29 21:17:54 +05:30
|
|
|
actions.setViewType,
|
|
|
|
payload,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.SET_VIEW_TYPE,
|
|
|
|
payload,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
2022-06-21 17:19:12 +05:30
|
|
|
expect(Cookies.set).toHaveBeenCalledWith('diff_view', payload, {
|
|
|
|
expires: 365,
|
|
|
|
secure: false,
|
|
|
|
});
|
2021-04-29 21:17:54 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setSubmitState', () => {
|
|
|
|
it('commits the right mutation', () => {
|
|
|
|
testAction(
|
|
|
|
actions.setSubmitState,
|
|
|
|
true,
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.SET_SUBMIT_STATE,
|
|
|
|
payload: true,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('updateCommitMessage', () => {
|
|
|
|
it('commits the right mutation', () => {
|
|
|
|
testAction(
|
|
|
|
actions.updateCommitMessage,
|
|
|
|
'some message',
|
|
|
|
{},
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.UPDATE_CONFLICTS_DATA,
|
|
|
|
payload: { commitMessage: 'some message' },
|
2021-04-17 20:07:23 +05:30
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setFileResolveMode', () => {
|
2022-10-11 01:57:18 +05:30
|
|
|
it('INTERACTIVE_RESOLVE_MODE updates the correct file', () => {
|
2022-06-21 17:19:12 +05:30
|
|
|
return testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.setFileResolveMode,
|
|
|
|
{ file: files[0], mode: INTERACTIVE_RESOLVE_MODE },
|
|
|
|
{ conflictsData: { files }, getFileIndex: () => 0 },
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.UPDATE_FILE,
|
|
|
|
payload: {
|
|
|
|
file: { ...files[0], showEditor: false, resolveMode: INTERACTIVE_RESOLVE_MODE },
|
|
|
|
index: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2022-10-11 01:57:18 +05:30
|
|
|
it('EDIT_RESOLVE_MODE updates the correct file', async () => {
|
2021-04-17 20:07:23 +05:30
|
|
|
restoreFileLinesState.mockReturnValue([]);
|
|
|
|
const file = {
|
|
|
|
...files[0],
|
|
|
|
showEditor: true,
|
|
|
|
loadEditor: true,
|
|
|
|
resolutionData: {},
|
|
|
|
resolveMode: EDIT_RESOLVE_MODE,
|
|
|
|
};
|
2022-06-21 17:19:12 +05:30
|
|
|
await testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.setFileResolveMode,
|
|
|
|
{ file: files[0], mode: EDIT_RESOLVE_MODE },
|
|
|
|
{ conflictsData: { files }, getFileIndex: () => 0 },
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.UPDATE_FILE,
|
|
|
|
payload: {
|
|
|
|
file,
|
|
|
|
index: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
2022-06-21 17:19:12 +05:30
|
|
|
expect(restoreFileLinesState).toHaveBeenCalledWith(file);
|
2021-04-17 20:07:23 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('setPromptConfirmationState', () => {
|
2022-10-11 01:57:18 +05:30
|
|
|
it('updates the correct file', () => {
|
2022-06-21 17:19:12 +05:30
|
|
|
return testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.setPromptConfirmationState,
|
|
|
|
{ file: files[0], promptDiscardConfirmation: true },
|
|
|
|
{ conflictsData: { files }, getFileIndex: () => 0 },
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.UPDATE_FILE,
|
|
|
|
payload: {
|
|
|
|
file: { ...files[0], promptDiscardConfirmation: true },
|
|
|
|
index: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('handleSelected', () => {
|
|
|
|
const file = {
|
|
|
|
...files[0],
|
|
|
|
inlineLines: [{ id: 1, hasConflict: true }, { id: 2 }],
|
|
|
|
parallelLines: [
|
|
|
|
[{ id: 1, hasConflict: true }, { id: 1 }],
|
|
|
|
[{ id: 2 }, { id: 3 }],
|
|
|
|
],
|
|
|
|
};
|
|
|
|
|
2022-10-11 01:57:18 +05:30
|
|
|
it('updates the correct file', async () => {
|
2021-04-17 20:07:23 +05:30
|
|
|
const marLikeMockReturn = { foo: 'bar' };
|
|
|
|
markLine.mockReturnValue(marLikeMockReturn);
|
|
|
|
|
2022-06-21 17:19:12 +05:30
|
|
|
await testAction(
|
2021-04-17 20:07:23 +05:30
|
|
|
actions.handleSelected,
|
|
|
|
{ file, line: { id: 1, section: 'baz' } },
|
|
|
|
{ conflictsData: { files }, getFileIndex: () => 0 },
|
|
|
|
[
|
|
|
|
{
|
|
|
|
type: types.UPDATE_FILE,
|
|
|
|
payload: {
|
|
|
|
file: {
|
|
|
|
...file,
|
|
|
|
resolutionData: { 1: 'baz' },
|
|
|
|
inlineLines: [marLikeMockReturn, { id: 2 }],
|
|
|
|
parallelLines: [
|
|
|
|
[marLikeMockReturn, marLikeMockReturn],
|
|
|
|
[{ id: 2 }, { id: 3 }],
|
|
|
|
],
|
|
|
|
},
|
|
|
|
index: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
[],
|
|
|
|
);
|
2022-06-21 17:19:12 +05:30
|
|
|
expect(markLine).toHaveBeenCalledTimes(3);
|
2021-04-17 20:07:23 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|