-
Notifications
You must be signed in to change notification settings - Fork 400
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
ShowMoreCard should expand if updated content changes #3057
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r+wc
Looks good, if moving away from ReactDOM
in that component would be easy that'd be great, but if not no worries.
it('expands if new child content is smaller', () => { | ||
const root = mount( | ||
<ShowMoreCardBase i18n={getFakeI18nInst()}> | ||
This should be a very long content, but we cannot get `clientHeight` in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick but this would be better written as "This would be very long content, but [...]"
@@ -29,15 +29,13 @@ export class ShowMoreCardBase extends React.Component { | |||
} | |||
|
|||
componentWillReceiveProps() { | |||
this.truncateToMaxHeight(ReactDOM.findDOMNode(this.contents)); | |||
this.setState({ expanded: true }, () => { | |||
this.truncateToMaxHeight(ReactDOM.findDOMNode(this.contents)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we're here, should we still be using ReactDOM.findDOMNode
? I forget if we can do this with refs or not but maybe we could?
Codecov Report
@@ Coverage Diff @@
## master mozilla/addons-frontend#3057 +/- ##
=======================================
Coverage 95.05% 95.05%
=======================================
Files 152 152
Lines 2792 2792
Branches 543 543
=======================================
Hits 2654 2654
Misses 119 119
Partials 19 19
Continue to review full report at Codecov.
|
@tofumatt thanks for the review, just addressed your comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just tested locally: works great. Thanks for removing the findDOMNode call; I think that one was my fault 😅
it('expands if new child content is smaller', () => { | ||
const root = mount( | ||
<ShowMoreCardBase i18n={getFakeI18nInst()}> | ||
This would be a very long content, but we cannot get `clientHeight` in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: should be "This would be very long content" not "a very long content"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doh 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you already merged this but I think it could use a fix-up. Be careful with setState()
callbacks since they are asynchronous.
@@ -29,15 +28,13 @@ export class ShowMoreCardBase extends React.Component { | |||
} | |||
|
|||
componentWillReceiveProps() { | |||
this.truncateToMaxHeight(ReactDOM.findDOMNode(this.contents)); | |||
this.setState({ expanded: true }, () => { | |||
this.truncateToMaxHeight(this.contents); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will work in production but I don't think it will work for our test suite. The problem is that React does not guarantee that the callback to setState()
will be invoked immediately. Thus, the test you wrote will probably pass most of the time but not all of the time. If the setState()
callback is delayed then your test will fail.
There are a few ways to solve this. We could try to wedge promises in here so that the test can use a promise chain. I don't see an easy way to do that.
Alternatively, we could keep the process synchronous which would make the test you already wrote pass 100% of the time. I think restoring componentWillReceiveProps()
to how it was and adding this else
block would accomplish that:
truncateToMaxHeight = (contents) => {
// If the contents are short enough they don't need a "show more" link; the
// contents are expanded by default.
if (contents.clientHeight > MAX_HEIGHT) {
this.setState({ expanded: false });
} else {
this.setState({ expanded: true });
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's possible that Enzyme has some trickery to ensure all batched state changes are applied but they don't document this. I'm skeptical since this kind of state change is triggered from within the component (not from an Enzyme method).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we could do (maybe) is reusing the callback
from Enzyme setState()
(see: enzymejs/enzyme#617) and ensure the test case asserts things once the setState()
has been triggered (and use done()
to ensure the test does not silently fail). WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh, yeah, we really can't rely on setState()
being synchronous anywhere. enzymejs/enzyme#509 (comment)
It would be nice to use promises instead of done()
but your approach will work. Creating a promise wrapper for everywhere we rely on wrapper.setState()
in the tests is probably a better long term solution.
Fix mozilla/addons#10709
This PR fixes an issue when the description of an add-on has a smaller size than the previously browsed one.
Gif