added create branch tests and started transmitting name for creating form

This commit is contained in:
Florian Scholdei
2019-04-04 11:04:39 +02:00
parent d113fa98a5
commit dfa0ceda55
5 changed files with 129 additions and 18 deletions

View File

@@ -15,6 +15,7 @@ type Props = {
repository: Repository, repository: Repository,
branches: Branch[], branches: Branch[],
loading?: boolean, loading?: boolean,
transmittedName?: string,
t: string => string t: string => string
}; };

View File

@@ -14,6 +14,7 @@ import {
} from "../modules/branches"; } from "../modules/branches";
import type { History } from "history"; import type { History } from "history";
import { connect } from "react-redux"; import { connect } from "react-redux";
import {withRouter} from "react-router-dom";
type Props = { type Props = {
loading?: boolean, loading?: boolean,
@@ -28,7 +29,8 @@ type Props = {
// context objects // context objects
t: string => string, t: string => string,
history: History history: History,
location: any
}; };
class CreateBranch extends React.Component<Props> { class CreateBranch extends React.Component<Props> {
@@ -47,8 +49,14 @@ class CreateBranch extends React.Component<Props> {
this.props.createBranch(branch, () => this.branchCreated(branch)); 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() { render() {
const { t, loading, error, repository, branches } = this.props; const { t, loading, error, repository, branches, location } = this.props;
if (error) { if (error) {
return <ErrorNotification error={error} />; return <ErrorNotification error={error} />;
@@ -66,6 +74,7 @@ class CreateBranch extends React.Component<Props> {
loading={loading} loading={loading}
repository={repository} repository={repository}
branches={branches} branches={branches}
transmittedName={this.matchesTransmittedName(location.search)}
/> />
</> </>
); );
@@ -103,7 +112,7 @@ const mapStateToProps = (state, ownProps) => {
}; };
}; };
export default connect( export default withRouter(connect(
mapStateToProps, mapStateToProps,
mapDispatchToProps mapDispatchToProps
)(translate("repos")(CreateBranch)); )(translate("repos")(CreateBranch)));

View File

@@ -81,16 +81,19 @@ export function createBranch(
link: string, link: string,
repository: Repository, repository: Repository,
branch: Branch, branch: Branch,
callback?: () => void callback?: (branch: Branch) => void
) { ) {
return function(dispatch: any) { return function(dispatch: any) {
dispatch(createBranchPending(repository, branch.name)); dispatch(createBranchPending(repository, branch.name));
return apiClient return apiClient
.post(link, branch, CONTENT_TYPE_BRANCH) .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()); dispatch(createBranchSuccess());
if (callback) { if (callback) {
callback(); callback(branch);
} }
}) })
.catch(error => dispatch(createBranchFailure(error))); .catch(error => dispatch(createBranchFailure(error)));
@@ -107,7 +110,7 @@ export function getBranches(state: Object, repository: Repository) {
return null; return null;
} }
export const isPermittedToCreateBranch = (state: Object): boolean => { export const isPermittedToCreateBranches = (state: Object): boolean => {
return false; // TODO return false; // TODO
}; };

View File

@@ -9,13 +9,20 @@ import reducer, {
FETCH_BRANCH_PENDING, FETCH_BRANCH_PENDING,
FETCH_BRANCH_SUCCESS, FETCH_BRANCH_SUCCESS,
FETCH_BRANCH_FAILURE, FETCH_BRANCH_FAILURE,
CREATE_BRANCH,
CREATE_BRANCH_FAILURE,
CREATE_BRANCH_PENDING,
CREATE_BRANCH_SUCCESS,
fetchBranches, fetchBranches,
fetchBranch, fetchBranch,
fetchBranchSuccess, fetchBranchSuccess,
getBranch, getBranch,
getBranches, getBranches,
getFetchBranchesFailure, getFetchBranchesFailure,
isFetchBranchesPending isFetchBranchesPending,
createBranch,
isCreateBranchPending,
getCreateBranchFailure
} from "./branches"; } from "./branches";
const namespace = "foo"; const namespace = "foo";
@@ -34,6 +41,8 @@ const repository = {
const branch1 = { name: "branch1", revision: "revision1" }; const branch1 = { name: "branch1", revision: "revision1" };
const branch2 = { name: "branch2", revision: "revision2" }; const branch2 = { name: "branch2", revision: "revision2" };
const branch3 = { name: "branch3", revision: "revision3" }; const branch3 = { name: "branch3", revision: "revision3" };
const branchRequest = { name: "newBranch", source: "master" };
const newBranch = { name: "newBranch", revision: "rev3" };
describe("branches", () => { describe("branches", () => {
describe("fetch branches", () => { describe("fetch branches", () => {
@@ -119,6 +128,64 @@ describe("branches", () => {
expect(actions[1].payload).toBeDefined(); 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", () => { describe("branches reducer", () => {
@@ -279,5 +346,36 @@ describe("branches", () => {
it("should return false if fetching branches did not fail", () => { it("should return false if fetching branches did not fail", () => {
expect(getFetchBranchesFailure({}, repository)).toBeUndefined(); 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);
});
}); });
}); });

View File

@@ -174,15 +174,6 @@ class RepositoryRoot extends React.Component<Props> {
/> />
)} )}
/> />
<Route
path={`${url}/branch/:branch`}
render={() => (
<BranchRoot
repository={repository}
baseUrl={`${url}/branch`}
/>
)}
/>
<Route <Route
path={`${url}/branch/:branch/changesets`} path={`${url}/branch/:branch/changesets`}
render={() => ( render={() => (
@@ -193,6 +184,15 @@ class RepositoryRoot extends React.Component<Props> {
/> />
)} )}
/> />
<Route
path={`${url}/branch/:branch`}
render={() => (
<BranchRoot
repository={repository}
baseUrl={`${url}/branch`}
/>
)}
/>
<Route <Route
path={`${url}/branches`} path={`${url}/branches`}
exact={true} exact={true}