Skip to content

Commit 2403069

Browse files
committed
feat(redux-saga): multiple things
- name changing - edit tests for stars and counter reducer
1 parent 6be0b5e commit 2403069

12 files changed

Lines changed: 87 additions & 130 deletions

File tree

src/app/Sagas/fetchStars.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/app/containers/Stars.test.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import {Stars} from "./Stars";
44
/** Mock App. State */
55
const state: object = {
66
stars: {
7-
count: 61,
8-
isFetching: false
7+
isFetching: false,
8+
payload: {
9+
stargazers_count: 61
10+
}
911
}
1012
};
1113

src/app/containers/Stars.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as React from "react";
22
import {IStars, IStarsAction} from "../models/starsModel";
3+
import {STARS_LOAD} from "../redux/modules/starsModule";
34
const {connect} = require("react-redux");
45
const {asyncConnect} = require("redux-connect");
56

@@ -10,7 +11,7 @@ interface IProps {
1011

1112
@asyncConnect([{
1213
promise: ({store: {dispatch}}) => {
13-
return dispatch({type: "stars/PAGE_LOAD"});
14+
return dispatch({type: STARS_LOAD});
1415
}
1516
}])
1617
@connect(
@@ -22,7 +23,7 @@ class Stars extends React.Component<IProps, {}> {
2223

2324
return (
2425
<div>
25-
{stars.isFetching ? "Fetching Stars" : stars.count}
26+
{stars.isFetching ? "Fetching Stars" : stars.payload.stargazers_count}
2627
</div>
2728
);
2829
}
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
11
import IBaseAction from "../models/IBaseAction";
22

3-
/**
4-
* @param name todo: change to a better name
5-
* @param state
6-
* @param action
7-
* @returns {any}
8-
*/
9-
export default function baseReducer<TState, TAction>(name: string, state: TState, action: IBaseAction & TAction): TState {
3+
export default function promiseReducer<TState, TAction>(baseAction: string, state: TState, action: IBaseAction & TAction): TState {
104
switch (action.type) {
11-
case name + "_PENDING":
5+
case baseAction + "_PENDING":
126
return Object.assign({}, state, {
137
isFetching: true
148
});
159

16-
case name + "_FULFILLED":
10+
case baseAction + "_FULFILLED":
1711
return Object.assign({}, state, {
1812
isFetching: false,
1913
payload: action.payload
2014
});
2115

22-
case name + "_REJECTED":
16+
case baseAction + "_REJECTED":
2317
return Object.assign({}, state, {
2418
error: true,
2519
isFetching: false,
@@ -29,4 +23,4 @@ export default function baseReducer<TState, TAction>(name: string, state: TState
2923
default:
3024
return state;
3125
}
32-
}
26+
}

src/app/models/starsModel.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
export interface IStars {
22
isFetching?: boolean;
3-
count?: number;
43
error?: boolean;
5-
message?: any;
4+
payload?: {
5+
stargazers_count: number;
6+
};
67
}
78

89
export interface IStarsAction {
910
type: string;
1011
payload?: {
11-
count?: number;
1212
stargazers_count: number;
13-
message?: any;
1413
};
1514
}

src/app/redux/configureStore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {createLogger} from "redux-logger";
66
import reduxPromiseMiddleware from "redux-promise-middleware";
77
import createSagaMiddleware from "redux-saga";
88
import thunk from "redux-thunk";
9-
import rootSaga from "../Sagas/rootSaga";
9+
import rootSaga from "../sagas/rootSaga";
1010
import {IStore} from "./IStore";
1111
import rootReducer from "./rootReducer";
1212

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
11
import {ICounter, ICounterAction} from "models/counterModel";
22
import * as counter from "./counterModule";
33

4-
/** Module */
5-
describe("Counter Module", () => {
6-
7-
/** Actions */
8-
describe("Actions", () => {
9-
describe("Increment", () => {
10-
it("has the correct type", () => {
11-
const action: ICounterAction = counter.increment();
12-
expect(action.type).toBe(counter.INCREMENT);
13-
});
14-
});
15-
16-
describe("Decrement", () => {
17-
it("has the correct type", () => {
18-
const action: ICounterAction = counter.decrement();
19-
expect(action.type).toBe(counter.DECREMENT);
20-
});
21-
});
22-
});
23-
24-
/** Reducer */
25-
describe("Reducer", () => {
26-
4+
describe("Counter Reducer", () => {
275
const state: ICounter = {count: 10};
286

297
it("handles action of type INCREMENT", () => {
@@ -39,7 +17,4 @@ describe("Counter Module", () => {
3917
it("handles actions with unknown type", () => {
4018
expect(counter.counterReducer(state, {type: ""})).toEqual({count: state.count});
4119
});
42-
43-
});
44-
4520
});
Lines changed: 52 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,58 @@
1-
import {IStarsAction} from "models/starsModel";
2-
import {fetchMock, mockStore} from "../../helpers/TestHelper";
3-
import * as stars from "./starsModule";
4-
5-
/** Mock Data */
6-
const githubResponse = {
7-
stargazers_count: 999
8-
};
9-
10-
const errResponse = {
11-
message: "ERROR :-O"
12-
};
13-
14-
/** Stargazers Module */
15-
describe("Stars Module", () => {
16-
17-
/** Action Creators */
18-
describe("Action Creators", () => {
19-
20-
describe("Get Stars (Async)", () => {
21-
22-
afterEach(() => {
23-
fetchMock.restore();
24-
});
25-
26-
/** 200 */
27-
it("dispatches Request and Success Actions on OK requests", (done) => {
28-
29-
fetchMock.mock("https://api.github.com/repos/barbar/vortigern", {
30-
body: githubResponse,
31-
status: 200
32-
});
33-
34-
const expectedActions: IStarsAction[] = [
35-
{type: stars.GET_REQUEST},
36-
{type: stars.GET_SUCCESS, payload: {count: githubResponse.stargazers_count}}
37-
];
38-
39-
const store = mockStore({});
40-
41-
store.dispatch(stars.getStars())
42-
.then(() => expect(store.getActions()).toBe(expectedActions))
43-
.then(() => done())
44-
.catch((err) => done(err));
45-
});
46-
47-
/** 400 */
48-
it("dispatches Failure on failed requests", (done) => {
49-
50-
fetchMock.mock("https://api.github.com/repos/barbar/vortigern", {
51-
body: errResponse,
52-
status: 400
53-
});
54-
55-
const expectedActions: IStarsAction[] = [
56-
{type: stars.GET_REQUEST},
57-
{type: stars.GET_FAILURE, payload: {message: errResponse}}
58-
];
59-
60-
const store = mockStore({});
1+
import {STARS_REQUEST, starsReducer} from "./starsModule";
2+
3+
describe("Stars Reducer", () => {
4+
5+
it("handles action of type STARS_REQUEST_PENDING", () => {
6+
const action = {
7+
type: STARS_REQUEST + "_PENDING"
8+
};
9+
const stateBefore = {};
10+
const stateAfter = {
11+
isFetching: true
12+
};
13+
expect(starsReducer(stateBefore, action)).toEqual(stateAfter);
14+
});
6115

62-
store.dispatch(stars.getStars())
63-
.then(() => expect(store.getActions()).toBe(expectedActions))
64-
.then(() => done())
65-
.catch((err) => done(err));
66-
});
16+
it("handles action of type STARS_REQUEST_FULFILLED", () => {
17+
const action = {
18+
payload: {
19+
stargazers_count: 99
20+
},
21+
type: STARS_REQUEST + "_FULFILLED"
22+
};
23+
const stateBefore = {};
24+
const stateAfter = {
25+
isFetching: false,
26+
payload: {
27+
stargazers_count: 99
28+
}
29+
};
30+
expect(starsReducer(stateBefore, action)).toEqual(stateAfter);
31+
});
6732

68-
});
33+
it("handles action of type STARS_REQUEST_REJECTED", () => {
34+
const action = {
35+
type: STARS_REQUEST + "_REJECTED"
36+
};
37+
const stateBefore = {};
38+
const stateAfter = {
39+
error: true,
40+
isFetching: false
41+
};
42+
expect(starsReducer(stateBefore, action)).toEqual(stateAfter);
43+
});
6944

45+
it("handles actions with unknown type", () => {
46+
const action = {
47+
type: ""
48+
};
49+
const stateBefore = {
50+
isFetching: false
51+
};
52+
const stateAfter = {
53+
isFetching: false
54+
};
55+
expect(starsReducer(stateBefore, action)).toEqual(stateAfter);
7056
});
7157

7258
});
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {IStars, IStarsAction} from "models/starsModel";
2-
import baseReducer from "../../helpers/baseReducer";
2+
import promiseReducer from "../../helpers/promiseReducer";
33

44
/** Action Types */
5-
export const GET_REQUEST: string = "stars/GET_REQUEST";
5+
export const STARS_LOAD: string = "stars/STARS_LOAD";
6+
export const STARS_REQUEST: string = "stars/STARS_REQUEST";
67

78
/** Initial State */
89
const initialState: IStars = {
@@ -11,5 +12,5 @@ const initialState: IStars = {
1112

1213
/** Reducer */
1314
export function starsReducer(state: IStars = initialState, action: IStarsAction): IStars {
14-
return baseReducer<IStars, IStarsAction>("stars/GET_REQUEST", state, action);
15+
return promiseReducer<IStars, IStarsAction>(STARS_REQUEST, state, action);
1516
}

0 commit comments

Comments
 (0)