diff --git a/scm-ui/src/repos/branches/components/BranchForm.js b/scm-ui/src/repos/branches/components/BranchForm.js index 1c7409e8a7..67440620cb 100644 --- a/scm-ui/src/repos/branches/components/BranchForm.js +++ b/scm-ui/src/repos/branches/components/BranchForm.js @@ -15,6 +15,7 @@ type Props = { repository: Repository, branches: Branch[], loading?: boolean, + transmittedName?: string, t: string => string }; diff --git a/scm-ui/src/repos/branches/containers/CreateBranch.js b/scm-ui/src/repos/branches/containers/CreateBranch.js index 24b7697f73..b477d13a51 100644 --- a/scm-ui/src/repos/branches/containers/CreateBranch.js +++ b/scm-ui/src/repos/branches/containers/CreateBranch.js @@ -14,6 +14,7 @@ import { } from "../modules/branches"; import type { History } from "history"; import { connect } from "react-redux"; +import {withRouter} from "react-router-dom"; type Props = { loading?: boolean, @@ -28,7 +29,8 @@ type Props = { // context objects t: string => string, - history: History + history: History, + location: any }; class CreateBranch extends React.Component { @@ -47,8 +49,14 @@ class CreateBranch extends React.Component { this.props.createBranch(branch, () => this.branchCreated(branch)); }; + matchesTransmittedName = (search: string) => { + const regex = new RegExp("\\?name=.+"); + const match = search.match(regex); + return match ? match[0].substring(6, 0): null; + }; + render() { - const { t, loading, error, repository, branches } = this.props; + const { t, loading, error, repository, branches, location } = this.props; if (error) { return ; @@ -66,6 +74,7 @@ class CreateBranch extends React.Component { loading={loading} repository={repository} branches={branches} + transmittedName={this.matchesTransmittedName(location.search)} /> ); @@ -103,7 +112,7 @@ const mapStateToProps = (state, ownProps) => { }; }; -export default connect( +export default withRouter(connect( mapStateToProps, mapDispatchToProps -)(translate("repos")(CreateBranch)); +)(translate("repos")(CreateBranch))); diff --git a/scm-ui/src/repos/branches/modules/branches.js b/scm-ui/src/repos/branches/modules/branches.js index b226ba7c0c..ffe257a94c 100644 --- a/scm-ui/src/repos/branches/modules/branches.js +++ b/scm-ui/src/repos/branches/modules/branches.js @@ -81,16 +81,19 @@ export function createBranch( link: string, repository: Repository, branch: Branch, - callback?: () => void + callback?: (branch: Branch) => void ) { return function(dispatch: any) { dispatch(createBranchPending(repository, branch.name)); return apiClient .post(link, branch, CONTENT_TYPE_BRANCH) - .then(() => { + .then(response => response.headers.get("Location")) + .then(location => apiClient.get(location)) + .then(response => response.json()) + .then(branch => { dispatch(createBranchSuccess()); if (callback) { - callback(); + callback(branch); } }) .catch(error => dispatch(createBranchFailure(error))); @@ -107,7 +110,7 @@ export function getBranches(state: Object, repository: Repository) { return null; } -export const isPermittedToCreateBranch = (state: Object): boolean => { +export const isPermittedToCreateBranches = (state: Object): boolean => { return false; // TODO }; diff --git a/scm-ui/src/repos/branches/modules/branches.test.js b/scm-ui/src/repos/branches/modules/branches.test.js index 99c9bba60a..4e5c1d96a9 100644 --- a/scm-ui/src/repos/branches/modules/branches.test.js +++ b/scm-ui/src/repos/branches/modules/branches.test.js @@ -9,13 +9,20 @@ import reducer, { FETCH_BRANCH_PENDING, FETCH_BRANCH_SUCCESS, FETCH_BRANCH_FAILURE, + CREATE_BRANCH, + CREATE_BRANCH_FAILURE, + CREATE_BRANCH_PENDING, + CREATE_BRANCH_SUCCESS, fetchBranches, fetchBranch, fetchBranchSuccess, getBranch, getBranches, getFetchBranchesFailure, - isFetchBranchesPending + isFetchBranchesPending, + createBranch, + isCreateBranchPending, + getCreateBranchFailure } from "./branches"; const namespace = "foo"; @@ -34,6 +41,8 @@ const repository = { const branch1 = { name: "branch1", revision: "revision1" }; const branch2 = { name: "branch2", revision: "revision2" }; const branch3 = { name: "branch3", revision: "revision3" }; +const branchRequest = { name: "newBranch", source: "master" }; +const newBranch = { name: "newBranch", revision: "rev3" }; describe("branches", () => { describe("fetch branches", () => { @@ -119,6 +128,64 @@ describe("branches", () => { expect(actions[1].payload).toBeDefined(); }); }); + + it("should create a branch successfully", () => { + //branchrequest answer + fetchMock.postOnce(URL, { + status: 201, + headers: { + location: URL + "/newBranch" + } + }); + + //branch answer + fetchMock.getOnce(URL + "/newBranch", newBranch); + + const store = mockStore({}); + return store.dispatch(createBranch(URL, repository, branchRequest)).then(() => { + const actions = store.getActions(); + expect(actions[0].type).toEqual(CREATE_BRANCH_PENDING); + expect(actions[1].type).toEqual(CREATE_BRANCH_SUCCESS); + }); + }); + + it("should call the callback with the branch from the location header", () => { + //branchrequest answer + fetchMock.postOnce(URL, { + status: 201, + headers: { + location: URL + "/newBranch" + } + }); + + //branch answer + fetchMock.getOnce(URL + "/newBranch", newBranch); + + const store = mockStore({}); + + let receivedBranch = null; + + const callback = (branch) => { + receivedBranch = branch; + }; + + return store.dispatch(createBranch(URL, repository, branchRequest, callback)).then(() => { + expect(receivedBranch).toEqual(newBranch); + }); + }); + + it("should fail creating a branch on HTTP 500", () => { + fetchMock.postOnce(URL, { + status: 500 + }); + + const store = mockStore({}); + return store.dispatch(createBranch(URL, repository, branchRequest)).then(() => { + const actions = store.getActions(); + expect(actions[0].type).toEqual(CREATE_BRANCH_PENDING); + expect(actions[1].type).toEqual(CREATE_BRANCH_FAILURE); + }); + }); }); describe("branches reducer", () => { @@ -279,5 +346,36 @@ describe("branches", () => { it("should return false if fetching branches did not fail", () => { expect(getFetchBranchesFailure({}, repository)).toBeUndefined(); }); + + it("should return true if create branch is pending", () => { + const state = { + pending: { + [CREATE_BRANCH]: true + } + }; + expect(isCreateBranchPending(state)).toBe(true); + }); + + it("should return false if create branch is not pending", () => { + const state = { + pending: { + [CREATE_BRANCH]: false + } + }; + expect(isCreateBranchPending(state)).toBe(false); + }); + + it("should return error when create branch did fail", () => { + const state = { + failure: { + [CREATE_BRANCH]: error + } + }; + expect(getCreateBranchFailure(state)).toEqual(error); + }); + + it("shouls return undefined when create branch did not fail", () => { + expect(getCreateBranchFailure({})).toBe(undefined); + }); }); }); diff --git a/scm-ui/src/repos/containers/RepositoryRoot.js b/scm-ui/src/repos/containers/RepositoryRoot.js index 418b43d144..6630086964 100644 --- a/scm-ui/src/repos/containers/RepositoryRoot.js +++ b/scm-ui/src/repos/containers/RepositoryRoot.js @@ -174,15 +174,6 @@ class RepositoryRoot extends React.Component { /> )} /> - ( - - )} - /> ( @@ -193,6 +184,15 @@ class RepositoryRoot extends React.Component { /> )} /> + ( + + )} + />