mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 00:15:44 +01:00
implemented repository create form
This commit is contained in:
107
scm-ui/src/repos/modules/repository-types.js
Normal file
107
scm-ui/src/repos/modules/repository-types.js
Normal file
@@ -0,0 +1,107 @@
|
||||
// @flow
|
||||
|
||||
import * as types from "../../modules/types";
|
||||
import type { Action } from "../../types/Action";
|
||||
import type {
|
||||
RepositoryType,
|
||||
RepositoryTypeCollection
|
||||
} from "../types/RepositoryTypes";
|
||||
import { apiClient } from "../../apiclient";
|
||||
import { isPending } from "../../modules/pending";
|
||||
import { getFailure } from "../../modules/failure";
|
||||
|
||||
export const FETCH_REPOSITORY_TYPES = "scm/repos/FETCH_REPOSITORY_TYPES";
|
||||
export const FETCH_REPOSITORY_TYPES_PENDING = `${FETCH_REPOSITORY_TYPES}_${
|
||||
types.PENDING_SUFFIX
|
||||
}`;
|
||||
export const FETCH_REPOSITORY_TYPES_SUCCESS = `${FETCH_REPOSITORY_TYPES}_${
|
||||
types.SUCCESS_SUFFIX
|
||||
}`;
|
||||
export const FETCH_REPOSITORY_TYPES_FAILURE = `${FETCH_REPOSITORY_TYPES}_${
|
||||
types.FAILURE_SUFFIX
|
||||
}`;
|
||||
|
||||
export function fetchRepositoryTypesIfNeeded() {
|
||||
return function(dispatch: any, getState: () => Object) {
|
||||
if (shouldFetchRepositoryTypes(getState())) {
|
||||
return fetchRepositoryTypes(dispatch);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function fetchRepositoryTypes(dispatch: any) {
|
||||
dispatch(fetchRepositoryTypesPending());
|
||||
return apiClient
|
||||
.get("repository-types")
|
||||
.then(response => response.json())
|
||||
.then(repositoryTypes => {
|
||||
dispatch(fetchRepositoryTypesSuccess(repositoryTypes));
|
||||
})
|
||||
.catch(err => {
|
||||
dispatch(fetchRepositoryTypesFailure(err));
|
||||
});
|
||||
}
|
||||
|
||||
export function shouldFetchRepositoryTypes(state: Object) {
|
||||
if (
|
||||
isFetchRepositoryTypesPending(state) ||
|
||||
getFetchRepositoryTypesFailure(state)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (state.repositoryTypes && state.repositoryTypes.length > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export function fetchRepositoryTypesPending(): Action {
|
||||
return {
|
||||
type: FETCH_REPOSITORY_TYPES_PENDING
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchRepositoryTypesSuccess(
|
||||
repositoryTypes: RepositoryTypeCollection
|
||||
): Action {
|
||||
return {
|
||||
type: FETCH_REPOSITORY_TYPES_SUCCESS,
|
||||
payload: repositoryTypes
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchRepositoryTypesFailure(error: Error): Action {
|
||||
return {
|
||||
type: FETCH_REPOSITORY_TYPES_FAILURE,
|
||||
payload: error
|
||||
};
|
||||
}
|
||||
|
||||
// reducers
|
||||
|
||||
export default function reducer(
|
||||
state: RepositoryType[] = [],
|
||||
action: Action = { type: "UNKNOWN" }
|
||||
): RepositoryType[] {
|
||||
if (action.type === FETCH_REPOSITORY_TYPES_SUCCESS && action.payload) {
|
||||
return action.payload._embedded["repository-types"];
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
// selectors
|
||||
|
||||
export function getRepositoryTypes(state: Object) {
|
||||
if (state.repositoryTypes) {
|
||||
return state.repositoryTypes;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export function isFetchRepositoryTypesPending(state: Object) {
|
||||
return isPending(state, FETCH_REPOSITORY_TYPES);
|
||||
}
|
||||
|
||||
export function getFetchRepositoryTypesFailure(state: Object) {
|
||||
return getFailure(state, FETCH_REPOSITORY_TYPES);
|
||||
}
|
||||
198
scm-ui/src/repos/modules/repository-types.test.js
Normal file
198
scm-ui/src/repos/modules/repository-types.test.js
Normal file
@@ -0,0 +1,198 @@
|
||||
// @flow
|
||||
|
||||
import fetchMock from "fetch-mock";
|
||||
import configureMockStore from "redux-mock-store";
|
||||
import thunk from "redux-thunk";
|
||||
import {
|
||||
FETCH_REPOSITORY_TYPES,
|
||||
FETCH_REPOSITORY_TYPES_FAILURE,
|
||||
FETCH_REPOSITORY_TYPES_PENDING,
|
||||
FETCH_REPOSITORY_TYPES_SUCCESS,
|
||||
fetchRepositoryTypesIfNeeded,
|
||||
fetchRepositoryTypesSuccess,
|
||||
getFetchRepositoryTypesFailure,
|
||||
getRepositoryTypes,
|
||||
isFetchRepositoryTypesPending,
|
||||
shouldFetchRepositoryTypes
|
||||
} from "./repository-types";
|
||||
import reducer from "./repository-types";
|
||||
|
||||
const git = {
|
||||
name: "git",
|
||||
displayName: "Git",
|
||||
_links: {
|
||||
self: {
|
||||
href: "http://localhost:8081/scm/api/rest/v2/repository-types/git"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const hg = {
|
||||
name: "hg",
|
||||
displayName: "Mercurial",
|
||||
_links: {
|
||||
self: {
|
||||
href: "http://localhost:8081/scm/api/rest/v2/repository-types/hg"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const svn = {
|
||||
name: "svn",
|
||||
displayName: "Subversion",
|
||||
_links: {
|
||||
self: {
|
||||
href: "http://localhost:8081/scm/api/rest/v2/repository-types/svn"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const collection = {
|
||||
_embedded: {
|
||||
"repository-types": [git, hg, svn]
|
||||
},
|
||||
_links: {
|
||||
self: {
|
||||
href: "http://localhost:8081/scm/api/rest/v2/repository-types"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
describe("repository types caching", () => {
|
||||
it("should fetch repository types, on empty state", () => {
|
||||
expect(shouldFetchRepositoryTypes({})).toBe(true);
|
||||
});
|
||||
|
||||
it("should fetch repository types, if the state contains an empty array", () => {
|
||||
const state = {
|
||||
repositoryTypes: []
|
||||
};
|
||||
expect(shouldFetchRepositoryTypes(state)).toBe(true);
|
||||
});
|
||||
|
||||
it("should not fetch repository types, on pending state", () => {
|
||||
const state = {
|
||||
pending: {
|
||||
[FETCH_REPOSITORY_TYPES]: true
|
||||
}
|
||||
};
|
||||
expect(shouldFetchRepositoryTypes(state)).toBe(false);
|
||||
});
|
||||
|
||||
it("should not fetch repository types, on failure state", () => {
|
||||
const state = {
|
||||
failure: {
|
||||
[FETCH_REPOSITORY_TYPES]: new Error("no...")
|
||||
}
|
||||
};
|
||||
expect(shouldFetchRepositoryTypes(state)).toBe(false);
|
||||
});
|
||||
|
||||
it("should not fetch repository types, if they are already fetched", () => {
|
||||
const state = {
|
||||
repositoryTypes: [git, hg, svn]
|
||||
};
|
||||
expect(shouldFetchRepositoryTypes(state)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("repository types fetch", () => {
|
||||
const URL = "/scm/api/rest/v2/repository-types";
|
||||
const mockStore = configureMockStore([thunk]);
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.reset();
|
||||
fetchMock.restore();
|
||||
});
|
||||
|
||||
it("should successfully fetch repository types", () => {
|
||||
fetchMock.getOnce(URL, collection);
|
||||
|
||||
const expectedActions = [
|
||||
{ type: FETCH_REPOSITORY_TYPES_PENDING },
|
||||
{
|
||||
type: FETCH_REPOSITORY_TYPES_SUCCESS,
|
||||
payload: collection
|
||||
}
|
||||
];
|
||||
|
||||
const store = mockStore({});
|
||||
return store.dispatch(fetchRepositoryTypesIfNeeded()).then(() => {
|
||||
expect(store.getActions()).toEqual(expectedActions);
|
||||
});
|
||||
});
|
||||
|
||||
it("should dispatch FETCH_REPOSITORY_TYPES_FAILURE on server error", () => {
|
||||
fetchMock.getOnce(URL, {
|
||||
status: 500
|
||||
});
|
||||
|
||||
const store = mockStore({});
|
||||
return store.dispatch(fetchRepositoryTypesIfNeeded()).then(() => {
|
||||
const actions = store.getActions();
|
||||
expect(actions[0].type).toBe(FETCH_REPOSITORY_TYPES_PENDING);
|
||||
expect(actions[1].type).toBe(FETCH_REPOSITORY_TYPES_FAILURE);
|
||||
expect(actions[1].payload).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("should dispatch not dispatch any action, if the repository types are already fetched", () => {
|
||||
const store = mockStore({
|
||||
repositoryTypes: [git, hg, svn]
|
||||
});
|
||||
store.dispatch(fetchRepositoryTypesIfNeeded());
|
||||
expect(store.getActions().length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("repository types reducer", () => {
|
||||
it("should return unmodified state on unknown action", () => {
|
||||
const state = [];
|
||||
expect(reducer(state)).toBe(state);
|
||||
});
|
||||
it("should store the repository types on FETCH_REPOSITORY_TYPES_SUCCESS", () => {
|
||||
const newState = reducer([], fetchRepositoryTypesSuccess(collection));
|
||||
expect(newState).toEqual([git, hg, svn]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("repository types selectors", () => {
|
||||
const error = new Error("The end of the universe");
|
||||
|
||||
it("should return an emtpy array", () => {
|
||||
expect(getRepositoryTypes({})).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return the repository types", () => {
|
||||
const state = {
|
||||
repositoryTypes: [git, hg, svn]
|
||||
};
|
||||
expect(getRepositoryTypes(state)).toEqual([git, hg, svn]);
|
||||
});
|
||||
|
||||
it("should return true, when fetch repository types is pending", () => {
|
||||
const state = {
|
||||
pending: {
|
||||
[FETCH_REPOSITORY_TYPES]: true
|
||||
}
|
||||
};
|
||||
expect(isFetchRepositoryTypesPending(state)).toEqual(true);
|
||||
});
|
||||
|
||||
it("should return false, when fetch repos is not pending", () => {
|
||||
expect(isFetchRepositoryTypesPending({})).toEqual(false);
|
||||
});
|
||||
|
||||
it("should return error when fetch repository types did fail", () => {
|
||||
const state = {
|
||||
failure: {
|
||||
[FETCH_REPOSITORY_TYPES]: error
|
||||
}
|
||||
};
|
||||
expect(getFetchRepositoryTypesFailure(state)).toEqual(error);
|
||||
});
|
||||
|
||||
it("should return undefined when fetch repos did not fail", () => {
|
||||
expect(getFetchRepositoryTypesFailure({})).toBe(undefined);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user