summaryrefslogtreecommitdiff
path: root/spec/frontend/releases/stores/modules/detail/actions_spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/releases/stores/modules/detail/actions_spec.js')
-rw-r--r--spec/frontend/releases/stores/modules/detail/actions_spec.js615
1 files changed, 384 insertions, 231 deletions
diff --git a/spec/frontend/releases/stores/modules/detail/actions_spec.js b/spec/frontend/releases/stores/modules/detail/actions_spec.js
index 345be2acc71..1b2a705e8f4 100644
--- a/spec/frontend/releases/stores/modules/detail/actions_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/actions_spec.js
@@ -1,18 +1,20 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
-import { cloneDeep, merge } from 'lodash';
+import { cloneDeep } from 'lodash';
import * as actions from '~/releases/stores/modules/detail/actions';
import * as types from '~/releases/stores/modules/detail/mutation_types';
import { release as originalRelease } from '../../../mock_data';
import createState from '~/releases/stores/modules/detail/state';
-import createFlash from '~/flash';
+import { deprecatedCreateFlash as createFlash } from '~/flash';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { redirectTo } from '~/lib/utils/url_utility';
import api from '~/api';
+import httpStatus from '~/lib/utils/http_status';
import { ASSET_LINK_TYPE } from '~/releases/constants';
+import { releaseToApiJson, apiJsonToRelease } from '~/releases/util';
-jest.mock('~/flash', () => jest.fn());
+jest.mock('~/flash');
jest.mock('~/lib/utils/url_utility', () => ({
redirectTo: jest.fn(),
@@ -25,15 +27,26 @@ describe('Release detail actions', () => {
let mock;
let error;
+ const setupState = (updates = {}) => {
+ const getters = {
+ isExistingRelease: true,
+ };
+
+ state = {
+ ...createState({
+ projectId: '18',
+ tagName: release.tag_name,
+ releasesPagePath: 'path/to/releases/page',
+ markdownDocsPath: 'path/to/markdown/docs',
+ markdownPreviewPath: 'path/to/markdown/preview',
+ updateReleaseApiDocsPath: 'path/to/api/docs',
+ }),
+ ...getters,
+ ...updates,
+ };
+ };
+
beforeEach(() => {
- state = createState({
- projectId: '18',
- tagName: 'v1.3',
- releasesPagePath: 'path/to/releases/page',
- markdownDocsPath: 'path/to/markdown/docs',
- markdownPreviewPath: 'path/to/markdown/preview',
- updateReleaseApiDocsPath: 'path/to/api/docs',
- });
release = cloneDeep(originalRelease);
mock = new MockAdapter(axios);
gon.api_version = 'v4';
@@ -45,284 +58,424 @@ describe('Release detail actions', () => {
mock.restore();
});
- describe('requestRelease', () => {
- it(`commits ${types.REQUEST_RELEASE}`, () =>
- testAction(actions.requestRelease, undefined, state, [{ type: types.REQUEST_RELEASE }]));
- });
+ describe('when creating a new release', () => {
+ beforeEach(() => {
+ setupState({ isExistingRelease: false });
+ });
- describe('receiveReleaseSuccess', () => {
- it(`commits ${types.RECEIVE_RELEASE_SUCCESS}`, () =>
- testAction(actions.receiveReleaseSuccess, release, state, [
- { type: types.RECEIVE_RELEASE_SUCCESS, payload: release },
- ]));
+ describe('initializeRelease', () => {
+ it(`commits ${types.INITIALIZE_EMPTY_RELEASE}`, () => {
+ testAction(actions.initializeRelease, undefined, state, [
+ { type: types.INITIALIZE_EMPTY_RELEASE },
+ ]);
+ });
+ });
+
+ describe('saveRelease', () => {
+ it(`commits ${types.REQUEST_SAVE_RELEASE} and then dispatched "createRelease"`, () => {
+ testAction(
+ actions.saveRelease,
+ undefined,
+ state,
+ [{ type: types.REQUEST_SAVE_RELEASE }],
+ [{ type: 'createRelease' }],
+ );
+ });
+ });
});
- describe('receiveReleaseError', () => {
- it(`commits ${types.RECEIVE_RELEASE_ERROR}`, () =>
- testAction(actions.receiveReleaseError, error, state, [
- { type: types.RECEIVE_RELEASE_ERROR, payload: error },
- ]));
+ describe('when editing an existing release', () => {
+ beforeEach(setupState);
- it('shows a flash with an error message', () => {
- actions.receiveReleaseError({ commit: jest.fn() }, error);
+ describe('initializeRelease', () => {
+ it('dispatches "fetchRelease"', () => {
+ testAction(actions.initializeRelease, undefined, state, [], [{ type: 'fetchRelease' }]);
+ });
+ });
- expect(createFlash).toHaveBeenCalledTimes(1);
- expect(createFlash).toHaveBeenCalledWith(
- 'Something went wrong while getting the release details',
- );
+ describe('saveRelease', () => {
+ it(`commits ${types.REQUEST_SAVE_RELEASE} and then dispatched "updateRelease"`, () => {
+ testAction(
+ actions.saveRelease,
+ undefined,
+ state,
+ [{ type: types.REQUEST_SAVE_RELEASE }],
+ [{ type: 'updateRelease' }],
+ );
+ });
});
});
- describe('fetchRelease', () => {
- let getReleaseUrl;
+ describe('actions that behave the same whether creating a new release or editing an existing release', () => {
+ beforeEach(setupState);
- beforeEach(() => {
- state.projectId = '18';
- state.tagName = 'v1.3';
- getReleaseUrl = `/api/v4/projects/${state.projectId}/releases/${state.tagName}`;
- });
+ describe('fetchRelease', () => {
+ let getReleaseUrl;
+
+ beforeEach(() => {
+ getReleaseUrl = `/api/v4/projects/${state.projectId}/releases/${state.tagName}`;
+ });
+
+ describe('when the network request to the Release API is successful', () => {
+ beforeEach(() => {
+ mock.onGet(getReleaseUrl).replyOnce(httpStatus.OK, release);
+ });
+
+ it(`commits ${types.REQUEST_RELEASE} and then commits ${types.RECEIVE_RELEASE_SUCCESS} with the converted release object`, () => {
+ return testAction(actions.fetchRelease, undefined, state, [
+ {
+ type: types.REQUEST_RELEASE,
+ },
+ {
+ type: types.RECEIVE_RELEASE_SUCCESS,
+ payload: apiJsonToRelease(release, { deep: true }),
+ },
+ ]);
+ });
+ });
- it(`dispatches requestRelease and receiveReleaseSuccess with the camel-case'd release object`, () => {
- mock.onGet(getReleaseUrl).replyOnce(200, release);
-
- return testAction(
- actions.fetchRelease,
- undefined,
- state,
- [],
- [
- { type: 'requestRelease' },
- {
- type: 'receiveReleaseSuccess',
- payload: convertObjectPropsToCamelCase(release, { deep: true }),
- },
- ],
- );
+ describe('when the network request to the Release API fails', () => {
+ beforeEach(() => {
+ mock.onGet(getReleaseUrl).replyOnce(httpStatus.INTERNAL_SERVER_ERROR);
+ });
+
+ it(`commits ${types.REQUEST_RELEASE} and then commits ${types.RECEIVE_RELEASE_ERROR} with an error object`, () => {
+ return testAction(actions.fetchRelease, undefined, state, [
+ {
+ type: types.REQUEST_RELEASE,
+ },
+ {
+ type: types.RECEIVE_RELEASE_ERROR,
+ payload: expect.any(Error),
+ },
+ ]);
+ });
+
+ it(`shows a flash message`, () => {
+ return actions.fetchRelease({ commit: jest.fn(), state }).then(() => {
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createFlash).toHaveBeenCalledWith(
+ 'Something went wrong while getting the release details',
+ );
+ });
+ });
+ });
});
- it(`dispatches requestRelease and receiveReleaseError with an error object`, () => {
- mock.onGet(getReleaseUrl).replyOnce(500);
+ describe('updateReleaseTagName', () => {
+ it(`commits ${types.UPDATE_RELEASE_TAG_NAME} with the updated tag name`, () => {
+ const newTag = 'updated-tag-name';
+ return testAction(actions.updateReleaseTagName, newTag, state, [
+ { type: types.UPDATE_RELEASE_TAG_NAME, payload: newTag },
+ ]);
+ });
+ });
- return testAction(
- actions.fetchRelease,
- undefined,
- state,
- [],
- [{ type: 'requestRelease' }, { type: 'receiveReleaseError', payload: expect.anything() }],
- );
+ describe('updateCreateFrom', () => {
+ it(`commits ${types.UPDATE_CREATE_FROM} with the updated ref`, () => {
+ const newRef = 'my-feature-branch';
+ return testAction(actions.updateCreateFrom, newRef, state, [
+ { type: types.UPDATE_CREATE_FROM, payload: newRef },
+ ]);
+ });
});
- });
- describe('updateReleaseTitle', () => {
- it(`commits ${types.UPDATE_RELEASE_TITLE} with the updated release title`, () => {
- const newTitle = 'The new release title';
- return testAction(actions.updateReleaseTitle, newTitle, state, [
- { type: types.UPDATE_RELEASE_TITLE, payload: newTitle },
- ]);
+ describe('updateReleaseTitle', () => {
+ it(`commits ${types.UPDATE_RELEASE_TITLE} with the updated release title`, () => {
+ const newTitle = 'The new release title';
+ return testAction(actions.updateReleaseTitle, newTitle, state, [
+ { type: types.UPDATE_RELEASE_TITLE, payload: newTitle },
+ ]);
+ });
});
- });
- describe('updateReleaseNotes', () => {
- it(`commits ${types.UPDATE_RELEASE_NOTES} with the updated release notes`, () => {
- const newReleaseNotes = 'The new release notes';
- return testAction(actions.updateReleaseNotes, newReleaseNotes, state, [
- { type: types.UPDATE_RELEASE_NOTES, payload: newReleaseNotes },
- ]);
+ describe('updateReleaseNotes', () => {
+ it(`commits ${types.UPDATE_RELEASE_NOTES} with the updated release notes`, () => {
+ const newReleaseNotes = 'The new release notes';
+ return testAction(actions.updateReleaseNotes, newReleaseNotes, state, [
+ { type: types.UPDATE_RELEASE_NOTES, payload: newReleaseNotes },
+ ]);
+ });
});
- });
- describe('updateAssetLinkUrl', () => {
- it(`commits ${types.UPDATE_ASSET_LINK_URL} with the updated link URL`, () => {
- const params = {
- linkIdToUpdate: 2,
- newUrl: 'https://example.com/updated',
- };
+ describe('updateReleaseMilestones', () => {
+ it(`commits ${types.UPDATE_RELEASE_MILESTONES} with the updated release milestones`, () => {
+ const newReleaseMilestones = ['v0.0', 'v0.1'];
+ return testAction(actions.updateReleaseMilestones, newReleaseMilestones, state, [
+ { type: types.UPDATE_RELEASE_MILESTONES, payload: newReleaseMilestones },
+ ]);
+ });
+ });
- return testAction(actions.updateAssetLinkUrl, params, state, [
- { type: types.UPDATE_ASSET_LINK_URL, payload: params },
- ]);
+ describe('addEmptyAssetLink', () => {
+ it(`commits ${types.ADD_EMPTY_ASSET_LINK}`, () => {
+ return testAction(actions.addEmptyAssetLink, undefined, state, [
+ { type: types.ADD_EMPTY_ASSET_LINK },
+ ]);
+ });
});
- });
- describe('updateAssetLinkName', () => {
- it(`commits ${types.UPDATE_ASSET_LINK_NAME} with the updated link name`, () => {
- const params = {
- linkIdToUpdate: 2,
- newName: 'Updated link name',
- };
+ describe('updateAssetLinkUrl', () => {
+ it(`commits ${types.UPDATE_ASSET_LINK_URL} with the updated link URL`, () => {
+ const params = {
+ linkIdToUpdate: 2,
+ newUrl: 'https://example.com/updated',
+ };
- return testAction(actions.updateAssetLinkName, params, state, [
- { type: types.UPDATE_ASSET_LINK_NAME, payload: params },
- ]);
+ return testAction(actions.updateAssetLinkUrl, params, state, [
+ { type: types.UPDATE_ASSET_LINK_URL, payload: params },
+ ]);
+ });
});
- });
- describe('updateAssetLinkType', () => {
- it(`commits ${types.UPDATE_ASSET_LINK_TYPE} with the updated link type`, () => {
- const params = {
- linkIdToUpdate: 2,
- newType: ASSET_LINK_TYPE.RUNBOOK,
- };
+ describe('updateAssetLinkName', () => {
+ it(`commits ${types.UPDATE_ASSET_LINK_NAME} with the updated link name`, () => {
+ const params = {
+ linkIdToUpdate: 2,
+ newName: 'Updated link name',
+ };
- return testAction(actions.updateAssetLinkType, params, state, [
- { type: types.UPDATE_ASSET_LINK_TYPE, payload: params },
- ]);
+ return testAction(actions.updateAssetLinkName, params, state, [
+ { type: types.UPDATE_ASSET_LINK_NAME, payload: params },
+ ]);
+ });
});
- });
- describe('removeAssetLink', () => {
- it(`commits ${types.REMOVE_ASSET_LINK} with the ID of the asset link to remove`, () => {
- const idToRemove = 2;
- return testAction(actions.removeAssetLink, idToRemove, state, [
- { type: types.REMOVE_ASSET_LINK, payload: idToRemove },
- ]);
+ describe('updateAssetLinkType', () => {
+ it(`commits ${types.UPDATE_ASSET_LINK_TYPE} with the updated link type`, () => {
+ const params = {
+ linkIdToUpdate: 2,
+ newType: ASSET_LINK_TYPE.RUNBOOK,
+ };
+
+ return testAction(actions.updateAssetLinkType, params, state, [
+ { type: types.UPDATE_ASSET_LINK_TYPE, payload: params },
+ ]);
+ });
});
- });
- describe('updateReleaseMilestones', () => {
- it(`commits ${types.UPDATE_RELEASE_MILESTONES} with the updated release milestones`, () => {
- const newReleaseMilestones = ['v0.0', 'v0.1'];
- return testAction(actions.updateReleaseMilestones, newReleaseMilestones, state, [
- { type: types.UPDATE_RELEASE_MILESTONES, payload: newReleaseMilestones },
- ]);
+ describe('removeAssetLink', () => {
+ it(`commits ${types.REMOVE_ASSET_LINK} with the ID of the asset link to remove`, () => {
+ const idToRemove = 2;
+ return testAction(actions.removeAssetLink, idToRemove, state, [
+ { type: types.REMOVE_ASSET_LINK, payload: idToRemove },
+ ]);
+ });
});
- });
- describe('requestUpdateRelease', () => {
- it(`commits ${types.REQUEST_UPDATE_RELEASE}`, () =>
- testAction(actions.requestUpdateRelease, undefined, state, [
- { type: types.REQUEST_UPDATE_RELEASE },
- ]));
- });
+ describe('receiveSaveReleaseSuccess', () => {
+ it(`commits ${types.RECEIVE_SAVE_RELEASE_SUCCESS}`, () =>
+ testAction(actions.receiveSaveReleaseSuccess, undefined, { ...state, featureFlags: {} }, [
+ { type: types.RECEIVE_SAVE_RELEASE_SUCCESS },
+ ]));
- describe('receiveUpdateReleaseSuccess', () => {
- it(`commits ${types.RECEIVE_UPDATE_RELEASE_SUCCESS}`, () =>
- testAction(actions.receiveUpdateReleaseSuccess, undefined, { ...state, featureFlags: {} }, [
- { type: types.RECEIVE_UPDATE_RELEASE_SUCCESS },
- ]));
+ describe('when the releaseShowPage feature flag is enabled', () => {
+ beforeEach(() => {
+ const rootState = { featureFlags: { releaseShowPage: true } };
+ actions.receiveSaveReleaseSuccess({ commit: jest.fn(), state, rootState }, release);
+ });
- it('redirects to the releases page if releaseShowPage feature flag is enabled', () => {
- const rootState = { featureFlags: { releaseShowPage: true } };
- const updatedState = merge({}, state, {
- releasesPagePath: 'path/to/releases/page',
- release: {
- _links: {
- self: 'path/to/self',
- },
- },
+ it("redirects to the release's dedicated page", () => {
+ expect(redirectTo).toHaveBeenCalledTimes(1);
+ expect(redirectTo).toHaveBeenCalledWith(release._links.self);
+ });
});
- actions.receiveUpdateReleaseSuccess({ commit: jest.fn(), state: updatedState, rootState });
+ describe('when the releaseShowPage feature flag is disabled', () => {
+ beforeEach(() => {
+ const rootState = { featureFlags: { releaseShowPage: false } };
+ actions.receiveSaveReleaseSuccess({ commit: jest.fn(), state, rootState }, release);
+ });
- expect(redirectTo).toHaveBeenCalledTimes(1);
- expect(redirectTo).toHaveBeenCalledWith(updatedState.release._links.self);
+ it("redirects to the project's main Releases page", () => {
+ expect(redirectTo).toHaveBeenCalledTimes(1);
+ expect(redirectTo).toHaveBeenCalledWith(state.releasesPagePath);
+ });
+ });
});
- describe('when the releaseShowPage feature flag is disabled', () => {});
- });
-
- describe('receiveUpdateReleaseError', () => {
- it(`commits ${types.RECEIVE_UPDATE_RELEASE_ERROR}`, () =>
- testAction(actions.receiveUpdateReleaseError, error, state, [
- { type: types.RECEIVE_UPDATE_RELEASE_ERROR, payload: error },
- ]));
+ describe('createRelease', () => {
+ let createReleaseUrl;
+ let releaseLinksToCreate;
- it('shows a flash with an error message', () => {
- actions.receiveUpdateReleaseError({ commit: jest.fn() }, error);
+ beforeEach(() => {
+ const camelCasedRelease = convertObjectPropsToCamelCase(release);
- expect(createFlash).toHaveBeenCalledTimes(1);
- expect(createFlash).toHaveBeenCalledWith(
- 'Something went wrong while saving the release details',
- );
- });
- });
+ releaseLinksToCreate = camelCasedRelease.assets.links.slice(0, 1);
- describe('updateRelease', () => {
- let getters;
- let dispatch;
- let callOrder;
+ setupState({
+ release: camelCasedRelease,
+ releaseLinksToCreate,
+ });
- beforeEach(() => {
- state.release = convertObjectPropsToCamelCase(release);
- state.projectId = '18';
- state.tagName = state.release.tagName;
+ createReleaseUrl = `/api/v4/projects/${state.projectId}/releases`;
+ });
- getters = {
- releaseLinksToDelete: [{ id: '1' }, { id: '2' }],
- releaseLinksToCreate: [{ id: 'new-link-1' }, { id: 'new-link-2' }],
- };
+ describe('when the network request to the Release API is successful', () => {
+ beforeEach(() => {
+ const expectedRelease = releaseToApiJson({
+ ...state.release,
+ assets: {
+ links: releaseLinksToCreate,
+ },
+ });
- dispatch = jest.fn();
+ mock.onPost(createReleaseUrl, expectedRelease).replyOnce(httpStatus.CREATED, release);
+ });
- callOrder = [];
- jest.spyOn(api, 'updateRelease').mockImplementation(() => {
- callOrder.push('updateRelease');
- return Promise.resolve();
- });
- jest.spyOn(api, 'deleteReleaseLink').mockImplementation(() => {
- callOrder.push('deleteReleaseLink');
- return Promise.resolve();
- });
- jest.spyOn(api, 'createReleaseLink').mockImplementation(() => {
- callOrder.push('createReleaseLink');
- return Promise.resolve();
+ it(`dispatches "receiveSaveReleaseSuccess" with the converted release object`, () => {
+ return testAction(
+ actions.createRelease,
+ undefined,
+ state,
+ [],
+ [
+ {
+ type: 'receiveSaveReleaseSuccess',
+ payload: apiJsonToRelease(release, { deep: true }),
+ },
+ ],
+ );
+ });
});
- });
- it('dispatches requestUpdateRelease and receiveUpdateReleaseSuccess', () => {
- return actions.updateRelease({ dispatch, state, getters }).then(() => {
- expect(dispatch.mock.calls).toEqual([
- ['requestUpdateRelease'],
- ['receiveUpdateReleaseSuccess'],
- ]);
+ describe('when the network request to the Release API fails', () => {
+ beforeEach(() => {
+ mock.onPost(createReleaseUrl).replyOnce(httpStatus.INTERNAL_SERVER_ERROR);
+ });
+
+ it(`commits ${types.RECEIVE_SAVE_RELEASE_ERROR} with an error object`, () => {
+ return testAction(actions.createRelease, undefined, state, [
+ {
+ type: types.RECEIVE_SAVE_RELEASE_ERROR,
+ payload: expect.any(Error),
+ },
+ ]);
+ });
+
+ it(`shows a flash message`, () => {
+ return actions
+ .createRelease({ commit: jest.fn(), dispatch: jest.fn(), state, getters: {} })
+ .then(() => {
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createFlash).toHaveBeenCalledWith(
+ 'Something went wrong while creating a new release',
+ );
+ });
+ });
});
});
- it('dispatches requestUpdateRelease and receiveUpdateReleaseError with an error object', () => {
- jest.spyOn(api, 'updateRelease').mockRejectedValue(error);
+ describe('updateRelease', () => {
+ let getters;
+ let dispatch;
+ let commit;
+ let callOrder;
+
+ beforeEach(() => {
+ getters = {
+ releaseLinksToDelete: [{ id: '1' }, { id: '2' }],
+ releaseLinksToCreate: [{ id: 'new-link-1' }, { id: 'new-link-2' }],
+ };
+
+ setupState({
+ release: convertObjectPropsToCamelCase(release),
+ ...getters,
+ });
- return actions.updateRelease({ dispatch, state, getters }).then(() => {
- expect(dispatch.mock.calls).toEqual([
- ['requestUpdateRelease'],
- ['receiveUpdateReleaseError', error],
- ]);
+ dispatch = jest.fn();
+ commit = jest.fn();
+
+ callOrder = [];
+ jest.spyOn(api, 'updateRelease').mockImplementation(() => {
+ callOrder.push('updateRelease');
+ return Promise.resolve({ data: release });
+ });
+ jest.spyOn(api, 'deleteReleaseLink').mockImplementation(() => {
+ callOrder.push('deleteReleaseLink');
+ return Promise.resolve();
+ });
+ jest.spyOn(api, 'createReleaseLink').mockImplementation(() => {
+ callOrder.push('createReleaseLink');
+ return Promise.resolve();
+ });
});
- });
- it('updates the Release, then deletes all existing links, and then recreates new links', () => {
- return actions.updateRelease({ dispatch, state, getters }).then(() => {
- expect(callOrder).toEqual([
- 'updateRelease',
- 'deleteReleaseLink',
- 'deleteReleaseLink',
- 'createReleaseLink',
- 'createReleaseLink',
- ]);
+ describe('when the network request to the Release API is successful', () => {
+ it('dispatches receiveSaveReleaseSuccess', () => {
+ return actions.updateRelease({ commit, dispatch, state, getters }).then(() => {
+ expect(dispatch.mock.calls).toEqual([
+ ['receiveSaveReleaseSuccess', apiJsonToRelease(release)],
+ ]);
+ });
+ });
- expect(api.updateRelease.mock.calls).toEqual([
- [
- state.projectId,
- state.tagName,
- {
- name: state.release.name,
- description: state.release.description,
- milestones: state.release.milestones.map(milestone => milestone.title),
- },
- ],
- ]);
+ it('updates the Release, then deletes all existing links, and then recreates new links', () => {
+ return actions.updateRelease({ dispatch, state, getters }).then(() => {
+ expect(callOrder).toEqual([
+ 'updateRelease',
+ 'deleteReleaseLink',
+ 'deleteReleaseLink',
+ 'createReleaseLink',
+ 'createReleaseLink',
+ ]);
+
+ expect(api.updateRelease.mock.calls).toEqual([
+ [
+ state.projectId,
+ state.tagName,
+ releaseToApiJson({
+ ...state.release,
+ assets: {
+ links: getters.releaseLinksToCreate,
+ },
+ }),
+ ],
+ ]);
+
+ expect(api.deleteReleaseLink).toHaveBeenCalledTimes(
+ getters.releaseLinksToDelete.length,
+ );
+ getters.releaseLinksToDelete.forEach(link => {
+ expect(api.deleteReleaseLink).toHaveBeenCalledWith(
+ state.projectId,
+ state.tagName,
+ link.id,
+ );
+ });
+
+ expect(api.createReleaseLink).toHaveBeenCalledTimes(
+ getters.releaseLinksToCreate.length,
+ );
+ getters.releaseLinksToCreate.forEach(link => {
+ expect(api.createReleaseLink).toHaveBeenCalledWith(
+ state.projectId,
+ state.tagName,
+ link,
+ );
+ });
+ });
+ });
+ });
- expect(api.deleteReleaseLink).toHaveBeenCalledTimes(getters.releaseLinksToDelete.length);
- getters.releaseLinksToDelete.forEach(link => {
- expect(api.deleteReleaseLink).toHaveBeenCalledWith(
- state.projectId,
- state.tagName,
- link.id,
- );
+ describe('when the network request to the Release API fails', () => {
+ beforeEach(() => {
+ jest.spyOn(api, 'updateRelease').mockRejectedValue(error);
+ });
+
+ it('dispatches requestUpdateRelease and receiveUpdateReleaseError with an error object', () => {
+ return actions.updateRelease({ commit, dispatch, state, getters }).then(() => {
+ expect(commit.mock.calls).toEqual([[types.RECEIVE_SAVE_RELEASE_ERROR, error]]);
+ });
});
- expect(api.createReleaseLink).toHaveBeenCalledTimes(getters.releaseLinksToCreate.length);
- getters.releaseLinksToCreate.forEach(link => {
- expect(api.createReleaseLink).toHaveBeenCalledWith(state.projectId, state.tagName, link);
+ it('shows a flash message', () => {
+ return actions.updateRelease({ commit, dispatch, state, getters }).then(() => {
+ expect(createFlash).toHaveBeenCalledTimes(1);
+ expect(createFlash).toHaveBeenCalledWith(
+ 'Something went wrong while saving the release details',
+ );
+ });
});
});
});