Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add base logic for getting Topics via redux #11

Merged
merged 9 commits into from
Jun 1, 2018

Conversation

kgajowy
Copy link
Contributor

@kgajowy kgajowy commented May 27, 2018

Added:

  • eslint rules to jest
  • added thunk to have more powerful dispatching (redux-observable does not support redux v4 :(
  • made the state as it should be (divided into props per feature/part of app) instead of 'global')
  • TopicContainer tests (with actions mocking)
  • TopicReducer Tests
  • ActivityIndicator
  • Topic's actions specs

switch (action.type) {
case TOPICS_GET_REQUEST:
//TODO add ..state, and tests!
//TODO add thunk as redux-observable is out of order :(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yay!

@@ -3,7 +3,8 @@ module.exports = {
'browser': true,
'commonjs': true,
'jasmine': true,
'es6': true
'es6': true,
'jest/globals': true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool! WebStrom won't underline these globals?

Copy link
Contributor Author

@kgajowy kgajowy May 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! :) (describe/it only tho:)

package.json Outdated
@@ -9,6 +9,8 @@
"react-redux": "^5.0.7",
"react-scripts": "1.1.4",
"redux": "^4.0.0",
"redux-thunk": "^2.2.0",
"rxjs": "^6.2.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is RX needed if we have redux-thunk?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we don't import anything from this library, so I guess you pushed it accidentally

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to investigate it further, as without it lint-stage is throwing this error:
lint-staged/lint-staged#416

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed in 7646cd7
Please note that in my case it was necessary to totally remove lint-staged from both node_modules and package.json and install it again :(

return TopicService.getSubmittedTopics().then(topics => {
dispatch(topicsFetched(topics));
}).catch(error => {
dispatch(topicsFetchError(error));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

props for error handling 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not reflected anywhere in the app yet - I suppose it would be great to use some Toast/SnackBars to show them!

@@ -38,7 +38,7 @@ TopBar.propTypes = {
};

const mapStateToProps = state => ({
loggedUser: state.loggedUser
loggedUser: state.auth.loggedUser
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, better use this scopes

compose(
applyMiddleware(
thunk),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using window, super pure!


describe('payload received', () => {
const payload = [TopicModel.fromBackendData({})];
const topicState = topicReducer({pending: true}, topicsFetched(payload));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aha! I guess it was the initial state, so maybe empty object in previous cases (no preference here, I just want to open a discussion how to make this in a best way)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing null would actually break the reducer state - as first argument would be null, then default assignment is not used (fun(arg=default, ...) { ...} ), therefore it would blow the whole reducer (try to change undefined to null - reducer always return null instead of initialState)
Empty object {} works the same - no initialState is used. We could just pass initialState which is already exported but I am not sure if it gives us a real value. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, good idea!

case LOGIN:
return Object.assign({}, state, { loggedUser: true });
case LOGOUT:
return Object.assign({}, state, { loggedUser: false });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeh, we stay with es6. I saw recently what problems can there be with Object Rest/Spread is still a proposal! https://github.com/tc39/proposal-object-rest-spread CC: @ulaulala

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I haven't know about any bugs for that. @Tuhaj could you please elaborate more? If I understood correctly from this issue (tc39/proposal-object-rest-spread#52) it uses Object.assign under the hood.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kgajowy No bugs, but a lot of bother in case of deploy on SOME platforms. We recently tried to deploy a node app on Azure, and guess what happened: transpilers needed. Luckly on Heroku it went without any problems.

* 2) while using a dive, we have actions called immediately which may not be what we want
*
* I picked 2) as using 1) would only tell us that prop is called but we would lose the assurance that
* Container is correctly 'connected' (i.e. has correctly mapped dispatchToProps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting, have you experienced some bugs with wrongly connected components before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tuhaj lets say so - lack of correct mapping or lack of connect at all :)

});

it('should have topics array connected correctly from redux', () => {
expect(wrapper.instance().props.topics).toBe(initialState.topic.topics);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this still confuses me, .props().topics won't work here?

Copy link
Contributor Author

@kgajowy kgajowy May 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The full example is provided there http://airbnb.io/enzyme/docs/api/ShallowWrapper/props.html
I think it is worth reading but to make it short: wrapper.props() returns only those props that are directly mentioned within the construction of <Component props....) - while we have some props that are connected by the Redux! thus:

const mapStateToProps = ({ topic }) => ({
    topics: topic.topics,
    pending: topic.pending,
    error: topic.error
});

no prop from those will be visible in wrapper.props()!

so in fact, we actually could pass all props instead of the store there... but it would be a test that doesnt actually test if our component builds correctly in connection to the Redux

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for explanation!

@@ -41,4 +46,14 @@ describe('<TopicsList>', () => {
});
});

describe('when topics are loading', () => {
beforeEach(() => {
wrapper = shallow(<TopicsList pending={true}/>);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is necessary. let wrapper is defined at the very beginning of the test. Or you mean sosmething else than const wrapper ? (btw it wouldn't be visible in the test later or, so rather let wrapper inside describe but this is already done above)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eh, haven't noticed /shrug leave it

@kgajowy kgajowy merged commit 7f1783c into master Jun 1, 2018
@kgajowy kgajowy deleted the feature/topics_getter branch June 1, 2018 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

None yet

2 participants