From f0794c9d151afe1843e3e7d5f4250ae37d619cbb Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 3 Aug 2018 09:54:04 +0200 Subject: [PATCH] implemented action and selectors for delete repository --- scm-ui/src/repos/modules/repos.js | 79 ++++++++++++++++-- scm-ui/src/repos/modules/repos.test.js | 107 ++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 9 deletions(-) diff --git a/scm-ui/src/repos/modules/repos.js b/scm-ui/src/repos/modules/repos.js index c96719efcb..8f401e00ce 100644 --- a/scm-ui/src/repos/modules/repos.js +++ b/scm-ui/src/repos/modules/repos.js @@ -16,12 +16,17 @@ export const FETCH_REPO_PENDING = `${FETCH_REPO}_${types.PENDING_SUFFIX}`; export const FETCH_REPO_SUCCESS = `${FETCH_REPO}_${types.SUCCESS_SUFFIX}`; export const FETCH_REPO_FAILURE = `${FETCH_REPO}_${types.FAILURE_SUFFIX}`; -export const CREATE_REPO = "scm/repos/FETCH_REPO"; +export const CREATE_REPO = "scm/repos/CREATE_REPO"; export const CREATE_REPO_PENDING = `${CREATE_REPO}_${types.PENDING_SUFFIX}`; export const CREATE_REPO_SUCCESS = `${CREATE_REPO}_${types.SUCCESS_SUFFIX}`; export const CREATE_REPO_FAILURE = `${CREATE_REPO}_${types.FAILURE_SUFFIX}`; export const CREATE_REPO_RESET = `${CREATE_REPO}_${types.RESET_SUFFIX}`; +export const DELETE_REPO = "scm/repos/DELETE_REPO"; +export const DELETE_REPO_PENDING = `${DELETE_REPO}_${types.PENDING_SUFFIX}`; +export const DELETE_REPO_SUCCESS = `${DELETE_REPO}_${types.SUCCESS_SUFFIX}`; +export const DELETE_REPO_FAILURE = `${DELETE_REPO}_${types.FAILURE_SUFFIX}`; + const REPOS_URL = "repositories"; const CONTENT_TYPE = "application/vnd.scmm-repository+json;v=2"; @@ -183,6 +188,55 @@ export function createRepoReset(): Action { }; } +// delete + +export function deleteRepo(repository: Repository, callback?: () => void) { + return function(dispatch: any) { + dispatch(deleteRepoPending(repository)); + return apiClient + .delete(repository._links.delete.href) + .then(() => { + dispatch(deleteRepoSuccess(repository)); + if (callback) { + callback(); + } + }) + .catch(err => { + dispatch(deleteRepoFailure(repository, err)); + }); + }; +} + +export function deleteRepoPending(repository: Repository): Action { + return { + type: DELETE_REPO_PENDING, + payload: repository, + itemId: createIdentifier(repository) + }; +} + +export function deleteRepoSuccess(repository: Repository): Action { + return { + type: DELETE_REPO_SUCCESS, + payload: repository, + itemId: createIdentifier(repository) + }; +} + +export function deleteRepoFailure( + repository: Repository, + error: Error +): Action { + return { + type: DELETE_REPO_FAILURE, + payload: { + error, + repository + }, + itemId: createIdentifier(repository) + }; +} + // reducer function createIdentifier(repository: Repository) { @@ -289,15 +343,12 @@ export function getFetchRepoFailure( } export function isAbleToCreateRepos(state: Object) { - if ( + return !!( state.repos && state.repos.list && state.repos.list._links && state.repos.list._links.create - ) { - return true; - } - return false; + ); } export function isCreateRepoPending(state: Object) { @@ -307,3 +358,19 @@ export function isCreateRepoPending(state: Object) { export function getCreateRepoFailure(state: Object) { return getFailure(state, CREATE_REPO); } + +export function isDeleteRepoPending( + state: Object, + namespace: string, + name: string +) { + return isPending(state, DELETE_REPO, namespace + "/" + name); +} + +export function getDeleteRepoFailure( + state: Object, + namespace: string, + name: string +) { + return getFailure(state, DELETE_REPO, namespace + "/" + name); +} diff --git a/scm-ui/src/repos/modules/repos.test.js b/scm-ui/src/repos/modules/repos.test.js index c35d95c9a4..0544f56d16 100644 --- a/scm-ui/src/repos/modules/repos.test.js +++ b/scm-ui/src/repos/modules/repos.test.js @@ -30,7 +30,14 @@ import reducer, { isCreateRepoPending, CREATE_REPO, getCreateRepoFailure, - isAbleToCreateRepos + isAbleToCreateRepos, + DELETE_REPO, + DELETE_REPO_SUCCESS, + deleteRepo, + DELETE_REPO_PENDING, + DELETE_REPO_FAILURE, + isDeleteRepoPending, + getDeleteRepoFailure } from "./repos"; import type { Repository, RepositoryCollection } from "../types/Repositories"; @@ -364,7 +371,9 @@ describe("repos fetch", () => { }); it("should successfully create repo slarti/fjords", () => { - fetchMock.postOnce(REPOS_URL, slartiFjords); + fetchMock.postOnce(REPOS_URL, { + status: 201 + }); const expectedActions = [ { @@ -382,7 +391,6 @@ describe("repos fetch", () => { }); it("should successfully create repo slarti/fjords and call the callback", () => { - // unmatched fetchMock.postOnce(REPOS_URL, { status: 201 }); @@ -412,6 +420,71 @@ describe("repos fetch", () => { expect(actions[1].payload).toBeDefined(); }); }); + + it("should successfully delete repo slarti/fjords", () => { + fetchMock.delete( + "http://localhost:8081/scm/api/rest/v2/repositories/slarti/fjords", + { + status: 204 + } + ); + + const expectedActions = [ + { + type: DELETE_REPO_PENDING, + payload: slartiFjords, + itemId: "slarti/fjords" + }, + { + type: DELETE_REPO_SUCCESS, + payload: slartiFjords, + itemId: "slarti/fjords" + } + ]; + + const store = mockStore({}); + return store.dispatch(deleteRepo(slartiFjords)).then(() => { + expect(store.getActions()).toEqual(expectedActions); + }); + }); + + it("should successfully delete repo slarti/fjords and call the callback", () => { + fetchMock.delete( + "http://localhost:8081/scm/api/rest/v2/repositories/slarti/fjords", + { + status: 204 + } + ); + + let callMe = "not yet"; + + const callback = () => { + callMe = "yeah"; + }; + + const store = mockStore({}); + return store.dispatch(deleteRepo(slartiFjords, callback)).then(() => { + expect(callMe).toBe("yeah"); + }); + }); + + it("should disapatch failure on delete, if server returns status code 500", () => { + fetchMock.delete( + "http://localhost:8081/scm/api/rest/v2/repositories/slarti/fjords", + { + status: 500 + } + ); + + const store = mockStore({}); + return store.dispatch(deleteRepo(slartiFjords)).then(() => { + const actions = store.getActions(); + expect(actions[0].type).toEqual(DELETE_REPO_PENDING); + expect(actions[1].type).toEqual(DELETE_REPO_FAILURE); + expect(actions[1].payload.repository).toBe(slartiFjords); + expect(actions[1].payload.error).toBeDefined(); + }); + }); }); describe("repos reducer", () => { @@ -562,6 +635,34 @@ describe("repos selectors", () => { expect(getCreateRepoFailure({})).toBe(undefined); }); + // delete + + it("should return true, when delete repo is pending", () => { + const state = { + pending: { + [DELETE_REPO + "/slarti/fjords"]: true + } + }; + expect(isDeleteRepoPending(state, "slarti", "fjords")).toEqual(true); + }); + + it("should return false, when delete repo is not pending", () => { + expect(isDeleteRepoPending({}, "slarti", "fjords")).toEqual(false); + }); + + it("should return error when delete repo did fail", () => { + const state = { + failure: { + [DELETE_REPO + "/slarti/fjords"]: error + } + }; + expect(getDeleteRepoFailure(state, "slarti", "fjords")).toEqual(error); + }); + + it("should return undefined when delete repo did not fail", () => { + expect(getDeleteRepoFailure({}, "slarti", "fjords")).toBe(undefined); + }); + it("should return true if the list contains the create link", () => { const state = { repos: {