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

Fix minimum nights availability issue #1259

Merged
merged 1 commit into from
Jul 12, 2018

Conversation

majapw
Copy link
Collaborator

@majapw majapw commented Jul 11, 2018

Some strange behavior that we noticed on airbnb.com is that after the first render (e.g. when you change focus or change the selected date) on a calendar with minimum nights enabled, while the actual interactivity of the minimum nights days still updates correctly, the aria-label would be the opposite of what was expected. This meant that when the days were grayed out due to not satisfying the minimum nights requirement, the aria label would read them as available and when they were clickable, like when the start date was focused, the aria label would read them as unavailable.

Digging into this issue, it appeared to be related to how the 'blocked' modifier was being updated when the state changed. Looking at componentWillReceiveProps in the DayPickerRangeController, where most of the logic for modifiers lives.

Specifically, the inconsistency happened when focus changed and would remain thereafter. I think that the minimum nights logic would sometimes remove a 'blocked' modifier or forget to add a 'blocked' modifier unintentionally, which would flip the aria label from available to unavailable.

This change in ordering seems to address the issue.

@ljharb @backwardok @sdjidjev @airbnb/webinfra PTAL

@majapw majapw added the semver-patch: fixes/refactors/etc Anything that's not major or minor. label Jul 11, 2018
@coveralls
Copy link

coveralls commented Jul 11, 2018

Coverage Status

Coverage increased (+0.03%) to 84.671% when pulling 9c24607 on maja-fix-min-nights-availability-issue into 2c45275 on master.

Copy link
Contributor

@lencioni lencioni left a comment

Choose a reason for hiding this comment

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

This being order-dependent seems kinda brittle. Can you add a test that would have caught this bug?

@majapw
Copy link
Collaborator Author

majapw commented Jul 11, 2018

@lencioni that's a good idea. I may try to think of a way to make it less order dependent as well 🤔

I was also walking through the function step-by-step and I still don't really understand... why this is happening. :| so maybe I will revisit in addition to writing a test.

@majapw majapw force-pushed the maja-fix-min-nights-availability-issue branch from b723add to cb4517d Compare July 12, 2018 18:20
@majapw
Copy link
Collaborator Author

majapw commented Jul 12, 2018

@lencioni @ljharb I figured out the actual source of the issue: it was that when focus changed, we were applying the blocked modifier based on old values of the startDate/minimumNights/focusedInput via the isDayBlocked function.

I added some tests that check for this specific situation and I also updated the componentWillReceiveProps method to make a bit more sense. :) PTAL!

@majapw majapw force-pushed the maja-fix-min-nights-availability-issue branch from cb4517d to 547bb2c Compare July 12, 2018 18:39
} else {
modifiers = this.deleteModifier(modifiers, momentObj, 'blocked-calendar');
}
}

if (isBlocked) {
Copy link
Member

Choose a reason for hiding this comment

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

this is covering isDayBlocked and isOutsideRange, but this.isBlocked also covers doesNotMeetMinimumNights. should that get a test case also?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That gets covered in a minimum nights specific code path because the triggers for re-calculating min nights are slightly different. It does get handled though!

@@ -95,7 +95,7 @@ describe('DayPickerRangeController', () => {
});
});

describe('#componentWillReceiveProps', () => {
describe.only('#componentWillReceiveProps', () => {
Copy link
Member

Choose a reason for hiding this comment

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

this needs to be reverted

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

whoops! :) good catch.

@@ -673,7 +673,7 @@ describe('DayPickerRangeController', () => {
});
});

describe('focusedInput changed', () => {
describe.only('focusedInput changed', () => {
Copy link
Member

Choose a reason for hiding this comment

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

also this

@majapw majapw force-pushed the maja-fix-min-nights-availability-issue branch from 547bb2c to 38422d7 Compare July 12, 2018 21:31
@majapw majapw force-pushed the maja-fix-min-nights-availability-issue branch from 38422d7 to 9c24607 Compare July 12, 2018 21:39
'blocked-minimum-nights',
);

modifiers = this.addModifierToRange(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here is where the blocked modifier will get added back if it has been removed by line 400 unnecessarily. @ljharb

@majapw
Copy link
Collaborator Author

majapw commented Jul 12, 2018

@ljharb PTAL! I think I have addressed your comments. :)

day.add(1, 'day');
}

wrapper.instance().componentWillReceiveProps({
Copy link
Member

Choose a reason for hiding this comment

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

btw i think this might be covered by wrapper.setProps? not a blocker tho

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is what I've been using in all the tests in this describe block, so if I wanted to update I'd probably do everything all at once at a later date. :)

startDate={startDate}
minimumNights={minimumNights}
/>);
wrapper.instance().componentWillReceiveProps({
Copy link
Member

Choose a reason for hiding this comment

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

ditto

startDate={startDate}
minimumNights={minimumNights}
/>);
wrapper.instance().componentWillReceiveProps({
Copy link
Member

Choose a reason for hiding this comment

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

ditto

@majapw majapw merged commit f79915e into master Jul 12, 2018
@majapw majapw deleted the maja-fix-min-nights-availability-issue branch July 12, 2018 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
semver-patch: fixes/refactors/etc Anything that's not major or minor.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants