import { Repository, File } from '@scm-manager/ui-types'; import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import fetchMock from 'fetch-mock'; import { FETCH_SOURCES, FETCH_SOURCES_FAILURE, FETCH_SOURCES_PENDING, FETCH_SOURCES_SUCCESS, fetchSources, getFetchSourcesFailure, isFetchSourcesPending, default as reducer, getSources, fetchSourcesSuccess, isDirectory, } from './sources'; const sourcesUrl = 'http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/'; const repository: Repository = { name: 'core', namespace: 'scm', type: 'git', _links: { sources: { href: sourcesUrl, }, }, }; const collection = { name: 'src', path: 'src', directory: true, description: 'foo', length: 176, revision: '76aae4bb4ceacf0e88938eb5b6832738b7d537b4', subRepository: undefined, _links: { self: { href: 'http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/', }, }, _embedded: { children: [ { name: 'src', path: 'src', directory: true, description: '', length: 176, revision: '76aae4bb4ceacf0e88938eb5b6832738b7d537b4', lastModified: '', subRepository: undefined, _links: { self: { href: 'http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/src', }, }, _embedded: { children: [], }, }, { name: 'package.json', path: 'package.json', directory: false, description: 'bump version', length: 780, revision: '76aae4bb4ceacf0e88938eb5b6832738b7d537b4', lastModified: '2017-07-31T11:17:19Z', subRepository: undefined, _links: { self: { href: 'http://localhost:8081/scm/rest/api/v2/repositories/scm/core/content/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/package.json', }, history: { href: 'http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/history/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/package.json', }, }, _embedded: { children: [], }, }, ], }, }; const noDirectory: File = { name: 'src', path: 'src', directory: true, length: 176, revision: 'abc', _links: { self: { href: 'http://localhost:8081/scm/rest/api/v2/repositories/scm/core/sources/76aae4bb4ceacf0e88938eb5b6832738b7d537b4/src', }, }, _embedded: { children: [], }, }; describe('sources fetch', () => { const mockStore = configureMockStore([thunk]); afterEach(() => { fetchMock.reset(); fetchMock.restore(); }); it('should fetch the sources of the repository', () => { fetchMock.getOnce(sourcesUrl, collection); const expectedActions = [ { type: FETCH_SOURCES_PENDING, itemId: 'scm/core/_/', }, { type: FETCH_SOURCES_SUCCESS, itemId: 'scm/core/_/', payload: collection, }, ]; const store = mockStore({}); return store.dispatch(fetchSources(repository, '', '')).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); it('should fetch the sources of the repository with the given revision and path', () => { fetchMock.getOnce(sourcesUrl + 'abc/src', collection); const expectedActions = [ { type: FETCH_SOURCES_PENDING, itemId: 'scm/core/abc/src', }, { type: FETCH_SOURCES_SUCCESS, itemId: 'scm/core/abc/src', payload: collection, }, ]; const store = mockStore({}); return store.dispatch(fetchSources(repository, 'abc', 'src')).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); it('should dispatch FETCH_SOURCES_FAILURE on server error', () => { fetchMock.getOnce(sourcesUrl, { status: 500, }); const store = mockStore({}); return store.dispatch(fetchSources(repository, '', '')).then(() => { const actions = store.getActions(); expect(actions[0].type).toBe(FETCH_SOURCES_PENDING); expect(actions[1].type).toBe(FETCH_SOURCES_FAILURE); expect(actions[1].itemId).toBe('scm/core/_/'); expect(actions[1].payload).toBeDefined(); }); }); }); describe('reducer tests', () => { it('should return unmodified state on unknown action', () => { const state = {}; expect(reducer(state)).toBe(state); }); it('should store the collection, without revision and path', () => { const expectedState = { 'scm/core/_/': collection, }; expect( reducer({}, fetchSourcesSuccess(repository, '', '', collection)), ).toEqual(expectedState); }); it('should store the collection, with revision and path', () => { const expectedState = { 'scm/core/abc/src/main': collection, }; expect( reducer( {}, fetchSourcesSuccess(repository, 'abc', 'src/main', collection), ), ).toEqual(expectedState); }); }); describe('selector tests', () => { it('should return false if it is no directory', () => { const state = { sources: { 'scm/core/abc/src/main/package.json': { noDirectory, }, }, }; expect( isDirectory(state, repository, 'abc', 'src/main/package.json'), ).toBeFalsy(); }); it('should return true if it is directory', () => { const state = { sources: { 'scm/core/abc/src': noDirectory, }, }; expect(isDirectory(state, repository, 'abc', 'src')).toBe(true); }); it('should return null', () => { expect(getSources({}, repository, '', '')).toBeFalsy(); }); it('should return the source collection without revision and path', () => { const state = { sources: { 'scm/core/_/': collection, }, }; expect(getSources(state, repository, '', '')).toBe(collection); }); it('should return the source collection with revision and path', () => { const state = { sources: { 'scm/core/abc/src/main': collection, }, }; expect(getSources(state, repository, 'abc', 'src/main')).toBe(collection); }); it('should return true, when fetch sources is pending', () => { const state = { pending: { [FETCH_SOURCES + '/scm/core/_/']: true, }, }; expect(isFetchSourcesPending(state, repository, '', '')).toEqual(true); }); it('should return false, when fetch sources is not pending', () => { expect(isFetchSourcesPending({}, repository, '', '')).toEqual(false); }); const error = new Error('incredible error from hell'); it('should return error when fetch sources did fail', () => { const state = { failure: { [FETCH_SOURCES + '/scm/core/_/']: error, }, }; expect(getFetchSourcesFailure(state, repository, '', '')).toEqual(error); }); it('should return undefined when fetch sources did not fail', () => { expect(getFetchSourcesFailure({}, repository, '', '')).toBe(undefined); }); });