implemented create repository

This commit is contained in:
Sebastian Sdorra
2018-08-03 08:52:02 +02:00
parent a70420bb06
commit 211551a5be
4 changed files with 277 additions and 25 deletions

View File

@@ -2,9 +2,9 @@
import { apiClient } from "../../apiclient";
import * as types from "../../modules/types";
import type { Action } from "../../types/Action";
import type {Repository, RepositoryCollection} from "../types/Repositories";
import {isPending} from "../../modules/pending";
import {getFailure} from "../../modules/failure";
import type { Repository, RepositoryCollection } from "../types/Repositories";
import { isPending } from "../../modules/pending";
import { getFailure } from "../../modules/failure";
export const FETCH_REPOS = "scm/repos/FETCH_REPOS";
export const FETCH_REPOS_PENDING = `${FETCH_REPOS}_${types.PENDING_SUFFIX}`;
@@ -16,8 +16,16 @@ 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_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}`;
const REPOS_URL = "repositories";
const CONTENT_TYPE = "application/vnd.scmm-repository+json;v=2";
// fetch repos
const SORT_BY = "sortBy=namespaceAndName";
@@ -84,15 +92,16 @@ export function fetchReposFailure(err: Error): Action {
export function fetchRepo(namespace: string, name: string) {
return function(dispatch: any) {
dispatch(fetchRepoPending(namespace, name));
return apiClient.get(`${REPOS_URL}/${namespace}/${name}`)
return apiClient
.get(`${REPOS_URL}/${namespace}/${name}`)
.then(response => response.json())
.then( repository => {
dispatch(fetchRepoSuccess(repository))
} )
.then(repository => {
dispatch(fetchRepoSuccess(repository));
})
.catch(err => {
dispatch(fetchRepoFailure(namespace, name, err))
dispatch(fetchRepoFailure(namespace, name, err));
});
}
};
}
export function fetchRepoPending(namespace: string, name: string): Action {
@@ -114,7 +123,11 @@ export function fetchRepoSuccess(repository: Repository): Action {
};
}
export function fetchRepoFailure(namespace: string, name: string, error: Error): Action {
export function fetchRepoFailure(
namespace: string,
name: string,
error: Error
): Action {
return {
type: FETCH_REPO_FAILURE,
payload: {
@@ -126,6 +139,50 @@ export function fetchRepoFailure(namespace: string, name: string, error: Error):
};
}
// create repo
export function createRepo(repository: Repository, callback?: () => void) {
return function(dispatch: any) {
dispatch(createRepoPending());
return apiClient
.post(REPOS_URL, repository, CONTENT_TYPE)
.then(() => {
dispatch(createRepoSuccess());
if (callback) {
callback();
}
})
.catch(err => {
dispatch(createRepoFailure(err));
});
};
}
export function createRepoPending(): Action {
return {
type: CREATE_REPO_PENDING
};
}
export function createRepoSuccess(): Action {
return {
type: CREATE_REPO_SUCCESS
};
}
export function createRepoFailure(err: Error): Action {
return {
type: CREATE_REPO_FAILURE,
payload: err
};
}
export function createRepoReset(): Action {
return {
type: CREATE_REPO_RESET
};
}
// reducer
function createIdentifier(repository: Repository) {
@@ -180,7 +237,7 @@ export default function reducer(
case FETCH_REPO_SUCCESS:
return reducerByNames(state, action.payload);
default:
return state;
return state;
}
}
@@ -211,14 +268,42 @@ export function getFetchReposFailure(state: Object) {
export function getRepository(state: Object, namespace: string, name: string) {
if (state.repos && state.repos.byNames) {
return state.repos.byNames[ namespace + "/" + name];
return state.repos.byNames[namespace + "/" + name];
}
}
export function isFetchRepoPending(state: Object, namespace: string, name: string) {
export function isFetchRepoPending(
state: Object,
namespace: string,
name: string
) {
return isPending(state, FETCH_REPO, namespace + "/" + name);
}
export function getFetchRepoFailure(state: Object, namespace: string, name: string) {
export function getFetchRepoFailure(
state: Object,
namespace: string,
name: string
) {
return getFailure(state, FETCH_REPO, namespace + "/" + name);
}
export function isAbleToCreateRepos(state: Object) {
if (
state.repos &&
state.repos.list &&
state.repos.list._links &&
state.repos.list._links.create
) {
return true;
}
return false;
}
export function isCreateRepoPending(state: Object) {
return isPending(state, CREATE_REPO);
}
export function getCreateRepoFailure(state: Object) {
return getFailure(state, CREATE_REPO);
}

View File

@@ -22,7 +22,15 @@ import reducer, {
fetchRepoSuccess,
getRepository,
isFetchRepoPending,
getFetchRepoFailure
getFetchRepoFailure,
CREATE_REPO_PENDING,
CREATE_REPO_SUCCESS,
createRepo,
CREATE_REPO_FAILURE,
isCreateRepoPending,
CREATE_REPO,
getCreateRepoFailure,
isAbleToCreateRepos
} from "./repos";
import type { Repository, RepositoryCollection } from "../types/Repositories";
@@ -354,6 +362,56 @@ describe("repos fetch", () => {
expect(actions[1].itemId).toBe("slarti/fjords");
});
});
it("should successfully create repo slarti/fjords", () => {
fetchMock.postOnce(REPOS_URL, slartiFjords);
const expectedActions = [
{
type: CREATE_REPO_PENDING
},
{
type: CREATE_REPO_SUCCESS
}
];
const store = mockStore({});
return store.dispatch(createRepo(slartiFjords)).then(() => {
expect(store.getActions()).toEqual(expectedActions);
});
});
it("should successfully create repo slarti/fjords and call the callback", () => {
// unmatched
fetchMock.postOnce(REPOS_URL, {
status: 201
});
let callMe = "not yet";
const callback = () => {
callMe = "yeah";
};
const store = mockStore({});
return store.dispatch(createRepo(slartiFjords, callback)).then(() => {
expect(callMe).toBe("yeah");
});
});
it("should disapatch failure if server returns status code 500", () => {
fetchMock.postOnce(REPOS_URL, {
status: 500
});
const store = mockStore({});
return store.dispatch(createRepo(slartiFjords)).then(() => {
const actions = store.getActions();
expect(actions[0].type).toEqual(CREATE_REPO_PENDING);
expect(actions[1].type).toEqual(CREATE_REPO_FAILURE);
expect(actions[1].payload).toBeDefined();
});
});
});
describe("repos reducer", () => {
@@ -471,4 +529,58 @@ describe("repos selectors", () => {
};
expect(getFetchRepoFailure(state, "slarti", "fjords")).toEqual(error);
});
it("should return undefined when fetch repo did not fail", () => {
expect(getFetchRepoFailure({}, "slarti", "fjords")).toBe(undefined);
});
// create
it("should return true, when create repo is pending", () => {
const state = {
pending: {
[CREATE_REPO]: true
}
};
expect(isCreateRepoPending(state)).toEqual(true);
});
it("should return false, when create repo is not pending", () => {
expect(isCreateRepoPending({})).toEqual(false);
});
it("should return error when create repo did fail", () => {
const state = {
failure: {
[CREATE_REPO]: error
}
};
expect(getCreateRepoFailure(state)).toEqual(error);
});
it("should return undefined when create repo did not fail", () => {
expect(getCreateRepoFailure({})).toBe(undefined);
});
it("should return true if the list contains the create link", () => {
const state = {
repos: {
list: repositoryCollection
}
};
expect(isAbleToCreateRepos(state)).toBe(true);
});
it("should return false, if create link is unavailable", () => {
const state = {
repos: {
list: {
_links: {}
}
}
};
expect(isAbleToCreateRepos(state)).toBe(false);
});
});