Skip to content

Commit

Permalink
Merge pull request #166 from acelaya-forks/feature/fix-create-short-url
Browse files Browse the repository at this point in the history
Ensured server version is properly parsed to avoid errors due to inva…
  • Loading branch information
acelaya committed Oct 18, 2019
2 parents d9a8243 + 12f6b94 commit e9fc2bb
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 13 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).

## 2.2.1 - 2019-10-18

#### Added

* *Nothing*

#### Changed

* *Nothing*

#### Deprecated

* *Nothing*

#### Removed

* *Nothing*

#### Fixed

* [#165](https://github.com/shlinkio/shlink-web-client/issues/165) Fixed error thrown when opening "create" page while using a Shlink version which does not return a valid SemVer version (like `latest` docker image, or any development instance).


## 2.2.0 - 2019-10-05

#### Added
Expand Down
10 changes: 9 additions & 1 deletion src/servers/reducers/selectedServer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { createAction, handleActions } from 'redux-actions';
import { resetShortUrlParams } from '../../short-urls/reducers/shortUrlsListParams';
import { versionIsValidSemVer } from '../../utils/utils';

/* eslint-disable padding-line-between-statements */
export const SELECT_SERVER = 'shlink/selectedServer/SELECT_SERVER';
export const RESET_SELECTED_SERVER = 'shlink/selectedServer/RESET_SELECTED_SERVER';

export const MIN_FALLBACK_VERSION = '1.0.0';
export const MAX_FALLBACK_VERSION = '999.999.999';
export const LATEST_VERSION_CONSTRAINT = 'latest';
/* eslint-enable padding-line-between-statements */

const initialState = null;
Expand All @@ -15,7 +20,10 @@ export const selectServer = ({ findServerById }, buildShlinkApiClient) => (serve

const selectedServer = findServerById(serverId);
const { health } = await buildShlinkApiClient(selectedServer);
const { version } = await health().catch(() => ({ version: '1.0.0' }));
const version = await health()
.then(({ version }) => version === LATEST_VERSION_CONSTRAINT ? MAX_FALLBACK_VERSION : version)
.then((version) => !versionIsValidSemVer(version) ? MIN_FALLBACK_VERSION : version)
.catch(() => MIN_FALLBACK_VERSION);

dispatch({
type: SELECT_SERVER,
Expand Down
8 changes: 8 additions & 0 deletions src/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ export const compareVersions = (firstVersion, operator, secondVersion) => compar
secondVersion,
operator
);

export const versionIsValidSemVer = (version) => {
try {
return compareVersions(version, '=', version);
} catch (e) {
return false;
}
};
39 changes: 27 additions & 12 deletions test/servers/reducers/selectedServer.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import each from 'jest-each';
import reducer, {
selectServer,
resetSelectedServer,
RESET_SELECTED_SERVER,
SELECT_SERVER,
MAX_FALLBACK_VERSION,
MIN_FALLBACK_VERSION,
} from '../../../src/servers/reducers/selectedServer';
import { RESET_SHORT_URL_PARAMS } from '../../../src/short-urls/reducers/shortUrlsListParams';

Expand Down Expand Up @@ -34,26 +37,25 @@ describe('selectedServerReducer', () => {
findServerById: jest.fn(() => selectedServer),
};
const apiClientMock = {
health: jest.fn().mockResolvedValue({ version }),
health: jest.fn(),
};
const buildApiClient = jest.fn().mockResolvedValue(apiClientMock);
const dispatch = jest.fn();

beforeEach(() => {
apiClientMock.health.mockClear();
buildApiClient.mockClear();
});

afterEach(() => {
ServersServiceMock.findServerById.mockClear();
});
afterEach(jest.clearAllMocks);

it('dispatches proper actions', async () => {
const dispatch = jest.fn();
each([
[ version, version ],
[ 'latest', MAX_FALLBACK_VERSION ],
[ '%invalid_semver%', MIN_FALLBACK_VERSION ],
]).it('dispatches proper actions', async (serverVersion, expectedVersion) => {
const expectedSelectedServer = {
...selectedServer,
version,
version: expectedVersion,
};

apiClientMock.health.mockResolvedValue({ version: serverVersion });

await selectServer(ServersServiceMock, buildApiClient)(serverId)(dispatch);

expect(dispatch).toHaveBeenCalledTimes(2);
Expand All @@ -67,5 +69,18 @@ describe('selectedServerReducer', () => {
expect(ServersServiceMock.findServerById).toHaveBeenCalledTimes(1);
expect(buildApiClient).toHaveBeenCalledTimes(1);
});

it('falls back to min version when health endpoint fails', async () => {
const expectedSelectedServer = {
...selectedServer,
version: MIN_FALLBACK_VERSION,
};

apiClientMock.health.mockRejectedValue({});

await selectServer(ServersServiceMock, buildApiClient)(serverId)(dispatch);

expect(dispatch).toHaveBeenNthCalledWith(2, { type: SELECT_SERVER, selectedServer: expectedSelectedServer });
});
});
});

0 comments on commit e9fc2bb

Please sign in to comment.