Skip to content

Commit

Permalink
Redux 5.0.0 (#24482)
Browse files Browse the repository at this point in the history
 Migrate to Redux 5.0.0
  • Loading branch information
qmonmert authored Dec 16, 2023
1 parent 7a632b8 commit 2c8c914
Show file tree
Hide file tree
Showing 16 changed files with 396 additions and 643 deletions.
9 changes: 4 additions & 5 deletions generators/react/resources/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"@fortawesome/fontawesome-svg-core": "6.5.1",
"@fortawesome/free-solid-svg-icons": "6.5.1",
"@fortawesome/react-fontawesome": "0.2.0",
"@reduxjs/toolkit": "1.9.7",
"@reduxjs/toolkit": "2.0.1",
"axios": "1.6.2",
"bootstrap": "5.3.2",
"bootswatch": "5.3.2",
Expand All @@ -14,14 +14,13 @@
"react-hook-form": "7.49.2",
"react-jhipster": "0.25.3",
"react-loadable": "5.5.0",
"react-redux": "8.1.3",
"react-redux": "9.0.4",
"react-redux-loading-bar": "5.0.5",
"react-router-dom": "6.21.0",
"react-toastify": "9.1.3",
"react-transition-group": "4.4.5",
"reactstrap": "9.2.1",
"redux": "4.2.1",
"redux-thunk": "2.4.2",
"redux": "5.0.0",
"sonar-scanner": "3.1.0",
"tslib": "2.6.2",
"uuid": "9.0.1"
Expand All @@ -34,7 +33,7 @@
"@types/node": "18.19.3",
"@types/react": "18.2.45",
"@types/react-dom": "18.2.17",
"@types/react-redux": "7.1.31",
"@types/react-redux": "7.1.33",
"@types/redux": "3.6.31",
"@types/webpack-env": "1.18.4",
"@typescript-eslint/eslint-plugin": "6.14.0",
Expand Down
1 change: 0 additions & 1 deletion generators/react/templates/package.json.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
"react-transition-group": "<%= nodeDependencies['react-transition-group'] %>",
"reactstrap": "<%= nodeDependencies['reactstrap'] %>",
"redux": "<%= nodeDependencies['redux'] %>",
"redux-thunk": "<%= nodeDependencies['redux-thunk'] %>",
<%_ if (communicationSpringWebsocket) { _%>
"rxjs": "6.6.3",
"sockjs-client": "1.5.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
limitations under the License.
-%>
import {
AnyAction,
UnknownAction,
configureStore,
ThunkAction,
<%_ if (microfrontend || applicationTypeGateway) { _%>
Expand Down Expand Up @@ -60,7 +60,7 @@ const store = configureStore({
<%_ if (microfrontend || applicationTypeGateway) { _%>

// Allow lazy loading of reducers https://github.com/reduxjs/redux/blob/master/docs/usage/CodeSplitting.md
interface InjectableStore<S = any, A extends Action = AnyAction> extends Store<S, A> {
interface InjectableStore<S = any, A extends Action = UnknownAction> extends Store<S, A> {
asyncReducers: ReducersMapObject;
injectReducer(key: string, reducer: Reducer): void;
}
Expand Down Expand Up @@ -95,6 +95,6 @@ export type AppDispatch = typeof store.dispatch;

export const useAppSelector: TypedUseSelectorHook<IRootState> = useSelector;
export const useAppDispatch = () => useDispatch<AppDispatch>();
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, IRootState, unknown, AnyAction>;
export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, IRootState, unknown, UnknownAction>;

export default getStore;
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ let entityActionNamePlural = entityInstancePlural.toUpperCase();
_%>
import axios from 'axios';

import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { configureStore } from '@reduxjs/toolkit';
import sinon from 'sinon';
<%_ if (paginationInfiniteScroll) { _%>
import { parseHeaderForLinks } from 'react-jhipster';
Expand Down Expand Up @@ -167,7 +166,7 @@ describe('Entities reducer tests', () => {
'some message',
state => {
expect(state).toMatchObject({
errorMessage: 'error message',
errorMessage: null,
updateSuccess: false,
updating: false
});
Expand Down Expand Up @@ -270,9 +269,13 @@ describe('Entities reducer tests', () => {
let store;

const resolvedObject = { value: 'whatever' };
const getState = jest.fn();
const dispatch = jest.fn();
const extra = {};
beforeEach(() => {
const mockStore = configureStore([thunk]);
store = mockStore({});
store = configureStore({
reducer: (state = [], action) => [...state, action],
});
axios.get = sinon.stub().returns(Promise.resolve(resolvedObject));
axios.post = sinon.stub().returns(Promise.resolve(resolvedObject));
axios.put = sinon.stub().returns(Promise.resolve(resolvedObject));
Expand All @@ -281,150 +284,81 @@ describe('Entities reducer tests', () => {
});

it('dispatches FETCH_<%= entityActionName %>_LIST actions', async () => {
const expectedActions = [
{
type: getEntities.pending.type
},
{
type: getEntities.fulfilled.type,
payload: resolvedObject
}
];
await store.dispatch(getEntities({}));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
const arg = {};

const result = await getEntities(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(getEntities.fulfilled.match(result)).toBe(true);
});
<%_ if (searchEngineAny) { _%>
it('dispatches SEARCH_<%= entityActionNamePlural %> actions', async () => {
const expectedActions = [
{
type: searchEntities.pending.type
},
{
type: searchEntities.fulfilled.type,
payload: resolvedObject
}
];
await store.dispatch(searchEntities({}));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
const arg = {};

const result = await searchEntities(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(searchEntities.fulfilled.match(result)).toBe(true);
});
<%_ } _%>

it('dispatches FETCH_<%= entityActionName %> actions', async () => {
const expectedActions = [
{
type: getEntity.pending.type
},
{
type: getEntity.fulfilled.type,
payload: resolvedObject
}
];
await store.dispatch(getEntity(42666));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
const arg = 42666;

const result = await getEntity(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(getEntity.fulfilled.match(result)).toBe(true);
});

<%_ if (!readOnly) { _%>
it('dispatches CREATE_<%= entityActionName %> actions', async () => {
const expectedActions = [
{
type: createEntity.pending.type
},
<%_ if (!paginationInfiniteScroll) { _%>
{
type: getEntities.pending.type
},
<%_ } _%>
{
type: createEntity.fulfilled.type,
payload: resolvedObject
}
];
await store.dispatch(createEntity(<%- this.generateTestEntityPrimaryKey(primaryKey, 1) %>));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
<%_ if (!paginationInfiniteScroll) { _%>
expect(store.getActions()[2]).toMatchObject(expectedActions[2]);
<%_ } _%>
const arg = <%- this.generateTestEntityPrimaryKey(primaryKey, 1) %>;

const result = await createEntity(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(createEntity.fulfilled.match(result)).toBe(true);
});

it('dispatches UPDATE_<%= entityActionName %> actions', async () => {
const expectedActions = [
{
type: updateEntity.pending.type
},
<%_ if (!paginationInfiniteScroll) { _%>
{
type: getEntities.pending.type
},
<%_ } _%>
{
type: updateEntity.fulfilled.type,
payload: resolvedObject
}
];
await store.dispatch(updateEntity(<%- this.generateTestEntityPrimaryKey(primaryKey, 1) %>));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
<%_ if (!paginationInfiniteScroll) { _%>
expect(store.getActions()[2]).toMatchObject(expectedActions[2]);
<%_ } _%>
const arg = <%- this.generateTestEntityPrimaryKey(primaryKey, 1) %>;

const result = await updateEntity(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(updateEntity.fulfilled.match(result)).toBe(true);
});

it('dispatches PARTIAL_UPDATE_<%= entityActionName %> actions', async () => {
const expectedActions = [
{
type: partialUpdateEntity.pending.type
},
<%_ if (!paginationInfiniteScroll) { _%>
{
type: getEntities.pending.type
},
<%_ } _%>
{
type: partialUpdateEntity.fulfilled.type,
payload: resolvedObject
const arg = { <%- primaryKey.name %>: <%- this.generateTestEntityId(primaryKey.type) %> };

}
];
await store.dispatch(partialUpdateEntity({ <%- primaryKey.name %>: <%- this.generateTestEntityId(primaryKey.type) %> }));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
<%_ if (!paginationInfiniteScroll) { _%>
expect(store.getActions()[2]).toMatchObject(expectedActions[2]);
<%_ } _%>
const result = await partialUpdateEntity(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(partialUpdateEntity.fulfilled.match(result)).toBe(true);
});

it('dispatches DELETE_<%= entityActionName %> actions', async () => {
const expectedActions = [
{
type: deleteEntity.pending.type
},
<%_ if (!paginationInfiniteScroll) { _%>
{
type: getEntities.pending.type
},
<%_ } _%>
{
type: deleteEntity.fulfilled.type,
payload: resolvedObject
}
];
await store.dispatch(deleteEntity(42666));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
<%_ if (!paginationInfiniteScroll) { _%>
expect(store.getActions()[2]).toMatchObject(expectedActions[2]);
<%_ } _%>
const arg = 42666;

const result = await deleteEntity(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(deleteEntity.fulfilled.match(result)).toBe(true);
});
<%_ } _%>

it('dispatches RESET actions', async () => {
const expectedActions = [reset()];
await store.dispatch(reset());
expect(store.getActions()).toEqual(expectedActions);
expect(store.getState()).toEqual([expect.any(Object), expect.objectContaining(reset())]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
limitations under the License.
-%>

import thunk from 'redux-thunk';
import axios from 'axios';
import sinon from 'sinon';
import configureStore from 'redux-mock-store';
import { configureStore } from '@reduxjs/toolkit';

import activate, { activateAction, reset } from './activate.reducer';

Expand Down Expand Up @@ -74,29 +73,32 @@ describe('Activate reducer tests', () => {
let store;

const resolvedObject = { value: 'whatever' };
const getState = jest.fn();
const dispatch = jest.fn();
const extra = {};
beforeEach(() => {
const mockStore = configureStore([thunk]);
store = mockStore({});
store = configureStore({
reducer: (state = [], action) => [...state, action],
});
axios.get = sinon.stub().returns(Promise.resolve(resolvedObject));
});

it('dispatches ACTIVATE_ACCOUNT_PENDING and ACTIVATE_ACCOUNT_FULFILLED actions', async () => {
const expectedActions = [
{
type: activateAction.pending.type,
},
{
type: activateAction.fulfilled.type,
payload: resolvedObject,
},
];
await store.dispatch(activateAction(''));
expect(store.getActions()[0]).toMatchObject(expectedActions[0]);
expect(store.getActions()[1]).toMatchObject(expectedActions[1]);
const arg = '';

const result = await activateAction(arg)(dispatch, getState, extra);

const pendingAction = dispatch.mock.calls[0][0];
expect(pendingAction.meta.requestStatus).toBe('pending');
expect(activateAction.fulfilled.match(result)).toBe(true);
expect(result.payload).toBe(resolvedObject);
});
it('dispatches RESET actions', async () => {
await store.dispatch(reset());
expect(store.getActions()[0]).toMatchObject(reset());
expect(store.getState()).toEqual([
expect.any(Object),
expect.objectContaining(reset()),
]);
});
});
});
Loading

0 comments on commit 2c8c914

Please sign in to comment.