mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-10 18:27:25 +03:00
Created mercure info reducer and loaded info when server is reachable
This commit is contained in:
parent
d231ed3ede
commit
37e6c27461
9 changed files with 85 additions and 7 deletions
|
@ -9,6 +9,7 @@ import provideServersServices from '../servers/services/provideServices';
|
|||
import provideVisitsServices from '../visits/services/provideServices';
|
||||
import provideTagsServices from '../tags/services/provideServices';
|
||||
import provideUtilsServices from '../utils/services/provideServices';
|
||||
import provideMercureServices from '../mercure/services/provideServices';
|
||||
|
||||
const bottle = new Bottle();
|
||||
const { container } = bottle;
|
||||
|
@ -34,5 +35,6 @@ provideServersServices(bottle, connect, withRouter);
|
|||
provideTagsServices(bottle, connect);
|
||||
provideVisitsServices(bottle, connect);
|
||||
provideUtilsServices(bottle);
|
||||
provideMercureServices(bottle);
|
||||
|
||||
export default container;
|
||||
|
|
41
src/mercure/reducers/mercureInfo.js
Normal file
41
src/mercure/reducers/mercureInfo.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { handleActions } from 'redux-actions';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
/* eslint-disable padding-line-between-statements */
|
||||
export const GET_MERCURE_INFO_START = 'shlink/mercure/GET_MERCURE_INFO_START';
|
||||
export const GET_MERCURE_INFO_ERROR = 'shlink/mercure/GET_MERCURE_INFO_ERROR';
|
||||
export const GET_MERCURE_INFO = 'shlink/mercure/GET_MERCURE_INFO';
|
||||
/* eslint-enable padding-line-between-statements */
|
||||
|
||||
export const MercureInfoType = PropTypes.shape({
|
||||
token: PropTypes.string,
|
||||
mercureHubUrl: PropTypes.string,
|
||||
loading: PropTypes.bool,
|
||||
error: PropTypes.bool,
|
||||
});
|
||||
|
||||
const initialState = {
|
||||
token: undefined,
|
||||
mercureHubUrl: undefined,
|
||||
loading: false,
|
||||
error: false,
|
||||
};
|
||||
|
||||
export default handleActions({
|
||||
[GET_MERCURE_INFO_START]: (state) => ({ ...state, loading: true, error: false }),
|
||||
[GET_MERCURE_INFO_ERROR]: (state) => ({ ...state, loading: false, error: true }),
|
||||
[GET_MERCURE_INFO]: (state, { token, mercureHubUrl }) => ({ token, mercureHubUrl, loading: false, error: false }),
|
||||
}, initialState);
|
||||
|
||||
export const loadMercureInfo = (buildShlinkApiClient) => () => async (dispatch, getState) => {
|
||||
dispatch({ type: GET_MERCURE_INFO_START });
|
||||
const { mercureInfo } = buildShlinkApiClient(getState);
|
||||
|
||||
try {
|
||||
const result = await mercureInfo();
|
||||
|
||||
dispatch({ type: GET_MERCURE_INFO, ...result });
|
||||
} catch (e) {
|
||||
dispatch({ type: GET_MERCURE_INFO_ERROR });
|
||||
}
|
||||
};
|
8
src/mercure/services/provideServices.js
Normal file
8
src/mercure/services/provideServices.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { loadMercureInfo } from '../reducers/mercureInfo';
|
||||
|
||||
const provideServices = (bottle) => {
|
||||
// Actions
|
||||
bottle.serviceFactory('loadMercureInfo', loadMercureInfo, 'buildShlinkApiClient');
|
||||
};
|
||||
|
||||
export default provideServices;
|
|
@ -13,6 +13,7 @@ import shortUrlDetailReducer from '../visits/reducers/shortUrlDetail';
|
|||
import tagsListReducer from '../tags/reducers/tagsList';
|
||||
import tagDeleteReducer from '../tags/reducers/tagDelete';
|
||||
import tagEditReducer from '../tags/reducers/tagEdit';
|
||||
import mercureInfoReducer from '../mercure/reducers/mercureInfo';
|
||||
|
||||
export default combineReducers({
|
||||
servers: serversReducer,
|
||||
|
@ -29,4 +30,5 @@ export default combineReducers({
|
|||
tagsList: tagsListReducer,
|
||||
tagDelete: tagDeleteReducer,
|
||||
tagEdit: tagEditReducer,
|
||||
mercureInfo: mercureInfoReducer,
|
||||
});
|
||||
|
|
|
@ -25,7 +25,9 @@ const getServerVersion = memoizeWith(identity, (serverId, health) => health().th
|
|||
|
||||
export const resetSelectedServer = createAction(RESET_SELECTED_SERVER);
|
||||
|
||||
export const selectServer = ({ findServerById }, buildShlinkApiClient) => (serverId) => async (dispatch) => {
|
||||
export const selectServer = ({ findServerById }, buildShlinkApiClient, loadMercureInfo) => (serverId) => async (
|
||||
dispatch
|
||||
) => {
|
||||
dispatch(resetSelectedServer());
|
||||
dispatch(resetShortUrlParams());
|
||||
const selectedServer = findServerById(serverId);
|
||||
|
@ -51,6 +53,7 @@ export const selectServer = ({ findServerById }, buildShlinkApiClient) => (serve
|
|||
printableVersion,
|
||||
},
|
||||
});
|
||||
dispatch(loadMercureInfo());
|
||||
} catch (e) {
|
||||
dispatch({
|
||||
type: SELECT_SERVER,
|
||||
|
|
|
@ -47,7 +47,7 @@ const provideServices = (bottle, connect, withRouter) => {
|
|||
bottle.service('ServersExporter', ServersExporter, 'ServersService', 'window', 'csvjson');
|
||||
|
||||
// Actions
|
||||
bottle.serviceFactory('selectServer', selectServer, 'ServersService', 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('selectServer', selectServer, 'ServersService', 'buildShlinkApiClient', 'loadMercureInfo');
|
||||
bottle.serviceFactory('createServer', createServer, 'ServersService', 'listServers');
|
||||
bottle.serviceFactory('createServers', createServers, 'ServersService', 'listServers');
|
||||
bottle.serviceFactory('deleteServer', deleteServer, 'ServersService', 'listServers');
|
||||
|
|
|
@ -66,6 +66,8 @@ export default class ShlinkApiClient {
|
|||
|
||||
health = () => this._performRequest('/health', 'GET').then((resp) => resp.data);
|
||||
|
||||
mercureInfo = () => this._performRequest('/mercure-info', 'GET').then((resp) => resp.data);
|
||||
|
||||
_performRequest = async (url, method = 'GET', query = {}, body = {}) => {
|
||||
try {
|
||||
return await this.axios({
|
||||
|
|
|
@ -40,6 +40,7 @@ describe('selectedServerReducer', () => {
|
|||
};
|
||||
const buildApiClient = jest.fn().mockReturnValue(apiClientMock);
|
||||
const dispatch = jest.fn();
|
||||
const loadMercureInfo = jest.fn();
|
||||
|
||||
afterEach(jest.clearAllMocks);
|
||||
|
||||
|
@ -56,16 +57,17 @@ describe('selectedServerReducer', () => {
|
|||
|
||||
apiClientMock.health.mockResolvedValue({ version: serverVersion });
|
||||
|
||||
await selectServer(ServersServiceMock, buildApiClient)(uuid())(dispatch);
|
||||
await selectServer(ServersServiceMock, buildApiClient, loadMercureInfo)(uuid())(dispatch);
|
||||
|
||||
expect(dispatch).toHaveBeenCalledTimes(3);
|
||||
expect(dispatch).toHaveBeenCalledTimes(4);
|
||||
expect(dispatch).toHaveBeenNthCalledWith(1, { type: RESET_SELECTED_SERVER });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(2, { type: RESET_SHORT_URL_PARAMS });
|
||||
expect(dispatch).toHaveBeenNthCalledWith(3, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
|
||||
expect(loadMercureInfo).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('invokes dependencies', async () => {
|
||||
await selectServer(ServersServiceMock, buildApiClient)(uuid())(() => {});
|
||||
await selectServer(ServersServiceMock, buildApiClient, loadMercureInfo)(uuid())(() => {});
|
||||
|
||||
expect(ServersServiceMock.findServerById).toHaveBeenCalledTimes(1);
|
||||
expect(buildApiClient).toHaveBeenCalledTimes(1);
|
||||
|
@ -76,10 +78,11 @@ describe('selectedServerReducer', () => {
|
|||
|
||||
apiClientMock.health.mockRejectedValue({});
|
||||
|
||||
await selectServer(ServersServiceMock, buildApiClient)(uuid())(dispatch);
|
||||
await selectServer(ServersServiceMock, buildApiClient, loadMercureInfo)(uuid())(dispatch);
|
||||
|
||||
expect(apiClientMock.health).toHaveBeenCalled();
|
||||
expect(dispatch).toHaveBeenNthCalledWith(3, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
|
||||
expect(loadMercureInfo).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('dispatches error when server is not found', async () => {
|
||||
|
@ -87,11 +90,12 @@ describe('selectedServerReducer', () => {
|
|||
|
||||
ServersServiceMock.findServerById.mockReturnValue(undefined);
|
||||
|
||||
await selectServer(ServersServiceMock, buildApiClient)(uuid())(dispatch);
|
||||
await selectServer(ServersServiceMock, buildApiClient, loadMercureInfo)(uuid())(dispatch);
|
||||
|
||||
expect(ServersServiceMock.findServerById).toHaveBeenCalled();
|
||||
expect(apiClientMock.health).not.toHaveBeenCalled();
|
||||
expect(dispatch).toHaveBeenNthCalledWith(3, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
|
||||
expect(loadMercureInfo).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -209,4 +209,20 @@ describe('ShlinkApiClient', () => {
|
|||
expect(result).toEqual(expectedData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('mercureInfo', () => {
|
||||
it('returns mercure info', async () => {
|
||||
const expectedData = {
|
||||
token: 'abc.123.def',
|
||||
mercureHubUrl: 'http://example.com/.well-known/mercure',
|
||||
};
|
||||
const axiosSpy = jest.fn(createAxiosMock({ data: expectedData }));
|
||||
const { mercureInfo } = new ShlinkApiClient(axiosSpy);
|
||||
|
||||
const result = await mercureInfo();
|
||||
|
||||
expect(axiosSpy).toHaveBeenCalled();
|
||||
expect(result).toEqual(expectedData);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue