From 666d2d306564796caa49453c2c7886a2de5e942a Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Feb 2020 10:46:11 +0100 Subject: [PATCH 1/2] Ensured domain is dispatched when modifying a short URL somehow --- src/short-urls/reducers/shortUrlDeletion.js | 2 +- src/short-urls/reducers/shortUrlMeta.js | 2 +- src/short-urls/reducers/shortUrlTags.js | 2 +- src/short-urls/reducers/shortUrlsList.js | 18 +++++++++++++----- .../reducers/shortUrlDeletion.test.js | 2 +- test/short-urls/reducers/shortUrlMeta.test.js | 2 +- test/short-urls/reducers/shortUrlTags.test.js | 5 ++++- test/short-urls/reducers/shortUrlsList.test.js | 16 +++++++++++----- 8 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/short-urls/reducers/shortUrlDeletion.js b/src/short-urls/reducers/shortUrlDeletion.js index 6754527a..62c78569 100644 --- a/src/short-urls/reducers/shortUrlDeletion.js +++ b/src/short-urls/reducers/shortUrlDeletion.js @@ -37,7 +37,7 @@ export const deleteShortUrl = (buildShlinkApiClient) => (shortCode, domain) => a try { await deleteShortUrl(shortCode, domain); - dispatch({ type: SHORT_URL_DELETED, shortCode }); + dispatch({ type: SHORT_URL_DELETED, shortCode, domain }); } catch (e) { dispatch({ type: DELETE_SHORT_URL_ERROR, errorData: e.response.data }); diff --git a/src/short-urls/reducers/shortUrlMeta.js b/src/short-urls/reducers/shortUrlMeta.js index c7891cb8..c05bf4ba 100644 --- a/src/short-urls/reducers/shortUrlMeta.js +++ b/src/short-urls/reducers/shortUrlMeta.js @@ -41,7 +41,7 @@ export const editShortUrlMeta = (buildShlinkApiClient) => (shortCode, domain, me try { await updateShortUrlMeta(shortCode, domain, meta); - dispatch({ shortCode, meta, type: SHORT_URL_META_EDITED }); + dispatch({ shortCode, meta, domain, type: SHORT_URL_META_EDITED }); } catch (e) { dispatch({ type: EDIT_SHORT_URL_META_ERROR }); diff --git a/src/short-urls/reducers/shortUrlTags.js b/src/short-urls/reducers/shortUrlTags.js index 77302d76..c48e2e03 100644 --- a/src/short-urls/reducers/shortUrlTags.js +++ b/src/short-urls/reducers/shortUrlTags.js @@ -36,7 +36,7 @@ export const editShortUrlTags = (buildShlinkApiClient) => (shortCode, domain, ta try { const normalizedTags = await updateShortUrlTags(shortCode, domain, tags); - dispatch({ tags: normalizedTags, shortCode, type: SHORT_URL_TAGS_EDITED }); + dispatch({ tags: normalizedTags, shortCode, domain, type: SHORT_URL_TAGS_EDITED }); } catch (e) { dispatch({ type: EDIT_SHORT_URL_TAGS_ERROR }); diff --git a/src/short-urls/reducers/shortUrlsList.js b/src/short-urls/reducers/shortUrlsList.js index f43c264b..02efcfd7 100644 --- a/src/short-urls/reducers/shortUrlsList.js +++ b/src/short-urls/reducers/shortUrlsList.js @@ -1,5 +1,5 @@ import { handleActions } from 'redux-actions'; -import { assoc, assocPath, propEq, reject } from 'ramda'; +import { assoc, assocPath, isNil, reject } from 'ramda'; import PropTypes from 'prop-types'; import { SHORT_URL_TAGS_EDITED } from './shortUrlTags'; import { SHORT_URL_DELETED } from './shortUrlDeletion'; @@ -27,10 +27,18 @@ const initialState = { error: false, }; -const setPropFromActionOnMatchingShortUrl = (prop) => (state, { shortCode, [prop]: propValue }) => assocPath( +const shortUrlMatches = (shortUrl, shortCode, domain) => { + if (isNil(domain)) { + return shortUrl.shortCode === shortCode && !shortUrl.domain; + } + + return shortUrl.shortCode === shortCode && shortUrl.domain === domain; +}; + +const setPropFromActionOnMatchingShortUrl = (prop) => (state, { shortCode, domain, [prop]: propValue }) => assocPath( [ 'shortUrls', 'data' ], state.shortUrls.data.map( - (shortUrl) => shortUrl.shortCode === shortCode ? assoc(prop, propValue, shortUrl) : shortUrl + (shortUrl) => shortUrlMatches(shortUrl, shortCode, domain) ? assoc(prop, propValue, shortUrl) : shortUrl ), state ); @@ -39,9 +47,9 @@ export default handleActions({ [LIST_SHORT_URLS_START]: (state) => ({ ...state, loading: true, error: false }), [LIST_SHORT_URLS]: (state, { shortUrls }) => ({ loading: false, error: false, shortUrls }), [LIST_SHORT_URLS_ERROR]: () => ({ loading: false, error: true, shortUrls: {} }), - [SHORT_URL_DELETED]: (state, { shortCode }) => assocPath( + [SHORT_URL_DELETED]: (state, { shortCode, domain }) => assocPath( [ 'shortUrls', 'data' ], - reject(propEq('shortCode', shortCode), state.shortUrls.data), + reject((shortUrl) => shortUrlMatches(shortUrl, shortCode, domain), state.shortUrls.data), state, ), [SHORT_URL_TAGS_EDITED]: setPropFromActionOnMatchingShortUrl('tags'), diff --git a/test/short-urls/reducers/shortUrlDeletion.test.js b/test/short-urls/reducers/shortUrlDeletion.test.js index be7f3adf..d1b142ce 100644 --- a/test/short-urls/reducers/shortUrlDeletion.test.js +++ b/test/short-urls/reducers/shortUrlDeletion.test.js @@ -72,7 +72,7 @@ describe('shortUrlDeletionReducer', () => { expect(dispatch).toHaveBeenCalledTimes(2); expect(dispatch).toHaveBeenNthCalledWith(1, { type: DELETE_SHORT_URL_START }); - expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_DELETED, shortCode }); + expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_DELETED, shortCode, domain }); expect(apiClientMock.deleteShortUrl).toHaveBeenCalledTimes(1); expect(apiClientMock.deleteShortUrl).toHaveBeenCalledWith(shortCode, domain); diff --git a/test/short-urls/reducers/shortUrlMeta.test.js b/test/short-urls/reducers/shortUrlMeta.test.js index d3019395..92d82066 100644 --- a/test/short-urls/reducers/shortUrlMeta.test.js +++ b/test/short-urls/reducers/shortUrlMeta.test.js @@ -65,7 +65,7 @@ describe('shortUrlMetaReducer', () => { expect(updateShortUrlMeta).toHaveBeenCalledWith(shortCode, domain, meta); expect(dispatch).toHaveBeenCalledTimes(2); expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_META_START }); - expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_META_EDITED, meta, shortCode }); + expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_META_EDITED, meta, shortCode, domain }); }); it('dispatches error on failure', async () => { diff --git a/test/short-urls/reducers/shortUrlTags.test.js b/test/short-urls/reducers/shortUrlTags.test.js index bd43199a..169c5607 100644 --- a/test/short-urls/reducers/shortUrlTags.test.js +++ b/test/short-urls/reducers/shortUrlTags.test.js @@ -73,7 +73,10 @@ describe('shortUrlTagsReducer', () => { expect(updateShortUrlTags).toHaveBeenCalledWith(shortCode, domain, tags); expect(dispatch).toHaveBeenCalledTimes(2); expect(dispatch).toHaveBeenNthCalledWith(1, { type: EDIT_SHORT_URL_TAGS_START }); - expect(dispatch).toHaveBeenNthCalledWith(2, { type: SHORT_URL_TAGS_EDITED, tags: normalizedTags, shortCode }); + expect(dispatch).toHaveBeenNthCalledWith( + 2, + { type: SHORT_URL_TAGS_EDITED, tags: normalizedTags, shortCode, domain } + ); }); it('dispatches error on failure', async () => { diff --git a/test/short-urls/reducers/shortUrlsList.test.js b/test/short-urls/reducers/shortUrlsList.test.js index a34786f3..00a4e6d8 100644 --- a/test/short-urls/reducers/shortUrlsList.test.js +++ b/test/short-urls/reducers/shortUrlsList.test.js @@ -38,15 +38,17 @@ describe('shortUrlsListReducer', () => { shortUrls: { data: [ { shortCode, tags: [] }, + { shortCode, tags: [], domain: 'example.com' }, { shortCode: 'foo', tags: [] }, ], }, }; - expect(reducer(state, { type: SHORT_URL_TAGS_EDITED, shortCode, tags })).toEqual({ + expect(reducer(state, { type: SHORT_URL_TAGS_EDITED, shortCode, tags, domain: null })).toEqual({ shortUrls: { data: [ { shortCode, tags }, + { shortCode, tags: [], domain: 'example.com' }, { shortCode: 'foo', tags: [] }, ], }, @@ -55,6 +57,7 @@ describe('shortUrlsListReducer', () => { it('Updates meta on matching URL on SHORT_URL_META_EDITED', () => { const shortCode = 'abc123'; + const domain = 'example.com'; const meta = { maxVisits: 5, validSince: '2020-05-05', @@ -62,16 +65,18 @@ describe('shortUrlsListReducer', () => { const state = { shortUrls: { data: [ - { shortCode, meta: { maxVisits: 10 } }, + { shortCode, meta: { maxVisits: 10 }, domain }, + { shortCode, meta: { maxVisits: 50 } }, { shortCode: 'foo', meta: null }, ], }, }; - expect(reducer(state, { type: SHORT_URL_META_EDITED, shortCode, meta })).toEqual({ + expect(reducer(state, { type: SHORT_URL_META_EDITED, shortCode, meta, domain })).toEqual({ shortUrls: { data: [ - { shortCode, meta }, + { shortCode, meta, domain: 'example.com' }, + { shortCode, meta: { maxVisits: 50 } }, { shortCode: 'foo', meta: null }, ], }, @@ -84,6 +89,7 @@ describe('shortUrlsListReducer', () => { shortUrls: { data: [ { shortCode }, + { shortCode, domain: 'example.com' }, { shortCode: 'foo' }, ], }, @@ -91,7 +97,7 @@ describe('shortUrlsListReducer', () => { expect(reducer(state, { type: SHORT_URL_DELETED, shortCode })).toEqual({ shortUrls: { - data: [{ shortCode: 'foo' }], + data: [{ shortCode, domain: 'example.com' }, { shortCode: 'foo' }], }, }); }); From 86c155d8d1ab68480a2839f9c5522cfc8bc51ff6 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 8 Feb 2020 10:47:44 +0100 Subject: [PATCH 2/2] Updated changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21bbbc76..733c2632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 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). -## [Unreleased] +## 2.3.1 - 2020-02-08 #### Added @@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * [#193](https://github.com/shlinkio/shlink-web-client/issues/193) Fixed `maxVisits` being set to 0 when trying to reset it from having a value to `null`. * [#196](https://github.com/shlinkio/shlink-web-client/issues/196) Included apache `.htaccess` file which takes care of falling back to index.html when reloading the page on a client-side handled route. * [#179](https://github.com/shlinkio/shlink-web-client/issues/179) Ensured domain is provided to Shlink server when editing, deleting or fetching short URLs which do not belong to default domain. +* [#202](https://github.com/shlinkio/shlink-web-client/issues/202) Fixed domain not passed when dispatching actions that affect a single short URL (edit tags, edit meta and delete), which cased the list not to be properly updated. ## 2.3.0 - 2020-01-19