Completed redux-logic transition for linkGithubIdentity code#1672
Completed redux-logic transition for linkGithubIdentity code#1672outoftime merged 37 commits intopopcodeorg:masterfrom
Conversation
…gic. Still need to get react-saga and react-logic to play nicely.
These libraries are set up in code that runs at module load time, which is probably not a great practice, but for now we just mock out the libraries themselves so our modules will load without error.
# Conflicts: # src/logic/index.js # src/sagas/user.js # test/unit/sagas/user.js
outoftime
left a comment
There was a problem hiding this comment.
@jwang1919 Nice work! Left some feedback, but it’s all either minor style nits or musings on my vision for the new test suite that you’d have had no way to anticipate : )
|
|
||
| describe('linkGithubIdentity', () => { | ||
| test('success', async() => { | ||
| const mockCredential = {providerId: 'github.com'}; |
There was a problem hiding this comment.
One thing that is really important to me as we build out this new test suite is that test data is always generated from a centralized, reusable place, rather than defined ad-hoc in test files. This was an ambition for the old test suite but it was not fully realized.
The specific approach I had in mind was this:
- Create a
__factories__directory at the root of the project. This would have different submodules for different categories of test data:__factories__/clientsfor data that comes from clients (such asmockCredentialhere, which comes from Firebase)__factories__/statefor data that comes from the Redux store- Maybe more categories will spring up
- Use a factory definition library, probably Rosie, to define the factories (N.B. I think we want unregistered factories)
- Use Jest’s
moduleNameMapperconfiguration to map@factoriesto<rootDir>/__factories__so we can do e.g.import {credential as createCredential} from '@factories/clients/firebase'without worrying about a bunch of../..nonsense
What do you think? Are you down to take this on? I was hoping to get some of the scaffolding set up myself so you wouldn’t have to deal with it, but you beat me to the first case of needing it : )
There was a problem hiding this comment.
Hmm... okay, that sounds okay with me. Never worked with Rosie before so will take a bit more time to complete this.
There was a problem hiding this comment.
I actually ended up running into a situation where I needed factories too… stay tuned, currently wrangling eslint 😭
| const mockCredential = {providerId: 'github.com'}; | ||
|
|
||
| linkGithub.mockResolvedValue({ | ||
| user: {}, |
There was a problem hiding this comment.
A corollary to the above is that I think all of our test data should be realistic, even if realism doesn’t seem important to the test as written. So I would propose using a factory here to generate a realistic Firebase user object as well.
There was a problem hiding this comment.
To answer your question the Firebase API docs are pretty good for figuring out the shape of a Firebase User; and again throwing a debugger or console.log() in the application code is a good way to see what the object actually looks like in a concrete instance.
| test('credential already in use in experimental mode', async() => { | ||
| const error = new Error('credential already in use'); | ||
| error.code = 'auth/credential-already-in-use'; | ||
| error.credential = {providerId: 'github.com', accessToken: 'abc123'}; |
There was a problem hiding this comment.
For avoidance of doubt I would include any client-generated error objects in the factories.
| error.code = 'auth/credential-already-in-use'; | ||
| error.credential = {providerId: 'github.com', accessToken: 'abc123'}; | ||
|
|
||
| const githubProfile = {login: 'popcoder'}; |
There was a problem hiding this comment.
Another one for the factories
|
@outoftime Can this be merged? As discussed in chat the Rosie implementation will be coming later rather than sooner. |
|
@jwang1919 it's not ideal to have this held up, but I think it's important not to introduce patterns into the new year suite that we don't want to see there in the long run—in this case, ad-hoc definition of test data. Once #1670 is merged, I think it should be pretty quick for you to add the factories you need |
Cherry-picked from CodeMirror branch
|
@jwang1919 the CodeMirror branch is going to take a bit more work before it’s ready for primetime, so I cherry-picked over the bit that sets you up to write factories and pushed it to your branch here. I recommend checking out the documentation for rosie but you can also take a look at the factory I set up in the CodeMirror branch and the reasonably non-annoying way to import factories into jest tests employed therein. |
|
@outoftime okay. Used Rosie with |
outoftime
left a comment
There was a problem hiding this comment.
@jwang1919 Rosie usage looking good! Left some comments on the details but the overall approach looks just right.
__factories__/clients/firebase.js
Outdated
|
|
||
| export const githubProfile = new Factory().attrs({ | ||
| login: 'popcoder', | ||
| }); |
There was a problem hiding this comment.
The top-level principle for organizing factories should be where the data they’re generating would come from in the real application—in this case this profile object would come from the GitHub client, so this should live in __factories__/clients/github.js.
Also, as I mentioned before, we’ll want to generate factory data that is a reasonably complete representation of what the code we’re testing will see. I don’t necessarily think we need to capture every property of large objects like a GitHub profile, but we should try to capture a subset that generously covers all the properties Popcode might care about (this is a bit subjective, but I trust your judgement). As for where to find that information, API docs are probably your best bet; throwing a debugger or a console.log in the application code and then capturing a real example is another fine approach.
There was a problem hiding this comment.
Looks like this is still outstanding?
There was a problem hiding this comment.
Huh, I thought I changed this already. I'll check it out again.
There was a problem hiding this comment.
Sorry, to be clear—this looks good (very complete!) but it belongs in a __factories__/clients/github.js module because it is synthesizing GitHub client data, not Firebase client data.
|
|
||
| export const firebaseError = Factory.define( | ||
| 'firebaseError', | ||
| FirebaseError, |
There was a problem hiding this comment.
This seems like the right approach to me! 👍
| const mockCredential = {providerId: 'github.com'}; | ||
|
|
||
| linkGithub.mockResolvedValue({ | ||
| user: {}, |
There was a problem hiding this comment.
To answer your question the Firebase API docs are pretty good for figuring out the shape of a Firebase User; and again throwing a debugger or console.log() in the application code is a good way to see what the object actually looks like in a concrete instance.
outoftime
left a comment
There was a problem hiding this comment.
@jwang1919 looks like still a handful of lint errors—let me know if you get stuck with the import one, that plugin has been a Major Payne with the factory setup. i can jump in.
btw you know you don’t have to push and wait for Travis to run to see test results, right? you can run yarn test to get the whole thing, or yarn lint just to see lint errors…
__factories__/clients/firebase.js
Outdated
|
|
||
| export const githubProfile = new Factory().attrs({ | ||
| login: 'popcoder', | ||
| }); |
There was a problem hiding this comment.
Looks like this is still outstanding?
|
So the lint errors seem to only be showing up in Travis but not when I run |
|
@outoftime anyway yeah I need help, Major Payne is kicking my ass. |
* master: Archive projects (popcodeorg#1485)
As expected, `eslint-plugin-import` released a fix that corrects the behavior with internal modules that use module lookup aliases. So now the modules aliased under `@factory` are correctly recognized as internal.
|
@jwang1919 got u |
outoftime
left a comment
There was a problem hiding this comment.
@jwang1919 all looks good aside from moving that one factory! (and the one test desc)
__factories__/clients/firebase.js
Outdated
|
|
||
| export const githubProfile = new Factory().attrs({ | ||
| login: 'popcoder', | ||
| }); |
There was a problem hiding this comment.
Sorry, to be clear—this looks good (very complete!) but it belongs in a __factories__/clients/github.js module because it is synthesizing GitHub client data, not Firebase client data.
| expect(user).toEqual(mockUser); | ||
| }); | ||
|
|
||
| test('credential already in use in experimental mode', async() => { |
There was a problem hiding this comment.
You can drop the “in experimental mode” from this, that’s an outdated description in the old test.
…djusted test description.
|
@jwang1919 looks like you might have forgotten to commit the new factory? |
|
Oops! My bad. |
Followed same code conventions of when I did unlinkGithubIdentity. Replicated the same tests but in Jest and added a few more assertions.