Skip to content
This repository has been archived by the owner on Jun 19, 2023. It is now read-only.

Commit

Permalink
Merge 46703ee into cc3ae93
Browse files Browse the repository at this point in the history
  • Loading branch information
mmcgahan committed Aug 18, 2017
2 parents cc3ae93 + 46703ee commit d21dd86
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 63 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
- **Moved + renamed** `src/middleware/platform:getEpicMiddleware` has moved to
`require('src/api-state').getApiMiddleware`

- **Moved + renamed** `src/reducers/platform` has moved to `src/store/reducer`.
`makeRootReducer` is now the default export of the module.

## [5.1]

- **Change** (could be considered breaking, but it's specifically for a
Expand Down
2 changes: 1 addition & 1 deletion docs/Rendering.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ The browser entry script would typically have the following structure:

```jsx
import { resolveAppProps } from 'meetup-web-platform/lib/renderers/browser-render';
import makeRootReducer from 'meetup-web-platform/lib/reducers/platform';
import makeRootReducer from 'meetup-web-platform/lib/store/reducer';

const appReducers = require('./reducers'); // map of reducer keys to reducer functions
const reducer = makeRootReducer(appReducers); // create the root reducer function
Expand Down
39 changes: 0 additions & 39 deletions flow-typed/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,42 +108,3 @@ declare type CookieOpts = {
isSecure?: boolean,
encoding?: string,
};

declare type Match = {
params: Params,
isExact: boolean,
path: string,
url: string,
};

declare type MatchedRoute = { route: PlatformRoute, match: Match };
declare type MatchPathOptions = {
path: string,
exact?: boolean,
strict?: boolean,
};

declare module 'react-router-dom/matchPath' {
declare function matchPath(
pathname: string,
options: MatchPathOptions
): null | Match;
declare module.exports: typeof matchPath;
}

declare type LocationShape = {
pathname?: string,
search?: string,
hash?: string,
state?: any,
};

declare class RouterRedirect extends React$Component {
props: {
to: string | LocationShape,
push?: boolean,
},
}
declare module 'react-router-dom/Redirect' {
declare export default typeof RouterRedirect
}
42 changes: 42 additions & 0 deletions flow-typed/router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
declare type RouterTo = string | LocationShape | URL;

declare type Match = {
params: Params,
isExact: boolean,
path: string,
url: string,
};

declare type MatchedRoute = { route: PlatformRoute, match: Match };
declare type MatchPathOptions = {
path: string,
exact?: boolean,
strict?: boolean,
};

declare module 'react-router-dom/matchPath' {
declare function matchPath(
pathname: string,
options: MatchPathOptions
): null | Match;
declare module.exports: typeof matchPath;
}

declare type LocationShape = {
pathname?: string,
search?: string,
hash?: string,
state?: any,
};

declare class RouterRedirect extends React$Component {
props: {
to: string | LocationShape,
push?: boolean,
},
}
declare module 'react-router-dom/Redirect' {
declare export default typeof RouterRedirect
}

declare type LocationAction = { type: string, payload: LocationShape };
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
actions as clickActionCreators,
reducer as clickTracking,
DEFAULT_CLICK_TRACK,
} from '../plugins/tracking/util/clickState';
} from './clickState';

describe('clickTracking reducer', () => {
it('appends a click action to state.clicks', () => {
Expand Down
1 change: 0 additions & 1 deletion src/router/Redirect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import withSideEffect from 'react-side-effect';
import RouterRedirect from 'react-router-dom/Redirect';
import Route from 'react-router-dom/Route';
import { testForExternal } from './util';
import type { RouterTo } from './util/types';

type RedirectProps = {
to: RouterTo,
Expand Down
1 change: 1 addition & 0 deletions src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export {
SERVER_RENDER,
locationChange,
} from './routeActionCreators';
export { default as routing } from './reducer';
18 changes: 18 additions & 0 deletions src/router/reducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// @flow
import { LOCATION_CHANGE, SERVER_RENDER } from './routeActionCreators';
/*
* Store routing state to allow middleware to record more accurate
* tracking info
*/
export default function routing(
state: { location?: LocationShape, referrer?: LocationShape | {} } = {},
action: LocationAction
) {
if (action.type === LOCATION_CHANGE || action.type === SERVER_RENDER) {
return {
referrer: state.location || {},
location: action.payload,
};
}
return state;
}
3 changes: 2 additions & 1 deletion src/router/routeActionCreators.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// @flow
export const LOCATION_CHANGE = '@@router/LOCATION_CHANGE';
export const SERVER_RENDER = '@@router/INITIAL_RENDER';

export function locationChange(location) {
export function locationChange(location: LocationShape): LocationAction {
return {
type: LOCATION_CHANGE,
payload: location,
Expand Down
1 change: 0 additions & 1 deletion src/router/util/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// @flow
import type { RouterTo } from './types';
export * from './resolve';
export { decodeParams, getMatchedQueries } from './query';

Expand Down
2 changes: 0 additions & 2 deletions src/router/util/types.js

This file was deleted.

18 changes: 2 additions & 16 deletions src/reducers/platform.js → src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { combineReducers } from 'redux';
import { api, app, API_RESP_COMPLETE } from '../api-state'; // mwp-api-state
import { LOCATION_CHANGE, SERVER_RENDER } from '../router'; // mwp-router
import { routing } from '../router'; // mwp-router
import { reducer as clickTracking } from '../plugins/tracking/util/clickState'; // mwp-tracking/util/clickState

export function config(state = {}, action) {
Expand All @@ -28,21 +28,7 @@ export function preRenderChecklist([apiDataLoaded] = [false], action) {
return [apiDataLoaded || action.type === API_RESP_COMPLETE];
}

/*
* Store routing state to allow middleware to record more accurate
* tracking info
*/
export function routing(state = {}, action) {
if (action.type === LOCATION_CHANGE || action.type === SERVER_RENDER) {
return {
referrer: state.location || {},
location: action.payload,
};
}
return state;
}

const platformReducers = {
export const platformReducers = {
api,
app,
clickTracking,
Expand Down
40 changes: 40 additions & 0 deletions src/store/reducer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import * as redux from 'redux';
import makeRootReducer, { platformReducers } from './reducer';
/**
* A function that builds a reducer combining platform-standard reducers and
* app-specific reducers
export default function makeRootReducer(appReducers = {}) {
Object.keys(appReducers).forEach(reducer => {
if (reducer in platformReducers) {
throw new Error(`'${reducer}' is a reserved platform reducer name`);
}
});
return combineReducers({
...platformReducers,
...appReducers,
});
}
*/
redux.combineReducers = jest.fn();

describe('makeRootReducer', () => {
it('calls combineReducers with platform reducers + supplied reducers', () => {
redux.combineReducers.mockClear();
const foo = () => {};
const appReducers = { foo };
makeRootReducer(appReducers);
expect(redux.combineReducers).toHaveBeenCalled();
const calledWith = redux.combineReducers.mock.calls[0][0];
expect(calledWith).toMatchObject(platformReducers); // all platform reducers
expect(calledWith).toMatchObject(appReducers); // additional app reducer
});

it('throws error when attempting to overwrite a platform reducer', () => {
const invalidReducerKey = Object.keys(platformReducers)[0];
expect(() =>
makeRootReducer({
[invalidReducerKey]: platformReducers[invalidReducerKey],
})
).toThrow();
});
});
2 changes: 1 addition & 1 deletion tests/mockApp.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Helmet from 'react-helmet';
import makeRootReducer from '../src/reducers/platform';
import makeRootReducer from '../src/store/reducer';
import { Redirect } from '../src/router';

export const clientFilename = 'client.whatever.js';
Expand Down

0 comments on commit d21dd86

Please sign in to comment.