Created
May 24, 2019 16:06
-
-
Save willmanduffy/3979b307c7863ccbeec275b3fcdc1112 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { withEvents } from 'react-compose-events'; | |
| import { compose, withHandlers, withState } from 'recompose'; | |
| import { debounce } from './utils'; | |
| const LOAD_DISTANCE_FROM_PAGE_BOTTOM = 500; | |
| const LOAD_MORE_DEBOUNCE_TIME = 100; | |
| const withInfiniteScrolling = (loadMoreFunctionName, startsInfiniteEnabled = false) => compose( | |
| withState('infiniteEnabled', 'setInfiniteEnabled', startsInfiniteEnabled), | |
| withHandlers({ | |
| enableInfinite: ({ setInfiniteEnabled }) => event => setInfiniteEnabled(true) | |
| }), | |
| withEvents(window, ({ infiniteEnabled, [loadMoreFunctionName]: loadMoreFunction }) => ({ | |
| scroll: debounce(() => { | |
| loadMoreAtPageBottom({ infiniteEnabled, loadMoreFunction }); | |
| }, LOAD_MORE_DEBOUNCE_TIME) | |
| }) | |
| )); | |
| export const loadMoreAtPageBottom = ({ infiniteEnabled, loadMoreFunction }) => { | |
| if(infiniteEnabled && nearBottomOfPage()) { | |
| return loadMoreFunction(); | |
| }; | |
| }; | |
| const nearBottomOfPage = () => { | |
| return (window.innerHeight + window.pageYOffset) >= document.body.scrollHeight - LOAD_DISTANCE_FROM_PAGE_BOTTOM; | |
| } | |
| export default withInfiniteScrolling; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { mount } from 'enzyme'; | |
| import React from 'react'; | |
| import { compose, toClass, withProps } from 'recompose'; | |
| import simulant from 'simulant'; | |
| import withInfiniteScrolling, { | |
| loadMoreAtPageBottom | |
| } from './with-infinite-scrolling'; | |
| describe('a wrapped component', () => { | |
| jest.useFakeTimers(); | |
| const WrappedComponent = () => ( | |
| <div>That's a wrap!</div> | |
| ); | |
| const WrappedComponentClass = toClass(WrappedComponent); | |
| const EnhancedComponent = compose( | |
| withProps({ testFunction: jest.fn() }), | |
| withInfiniteScrolling('testFunction') | |
| )(WrappedComponentClass); | |
| const wrapper = mount( | |
| <EnhancedComponent /> | |
| ); | |
| it('has infinite scrolling disabled by default', () => { | |
| const subject = wrapper.find(WrappedComponentClass).props(); | |
| expect(subject.infiniteEnabled).toEqual(false); | |
| }) | |
| it('calling enableInfinite will enable infinite scrolling', () => { | |
| const subject = wrapper.find(WrappedComponentClass).props(); | |
| subject.enableInfinite(); | |
| wrapper.update(); | |
| expect(wrapper.find(WrappedComponentClass).props().infiniteEnabled).toEqual(true); | |
| }); | |
| it('does not call the loadMoreFunction on a scroll event near the page bottom when infinite is disabled', () => { | |
| simulant.fire(window, 'scroll'); | |
| jest.runAllTimers(); | |
| expect(wrapper.find(WrappedComponentClass).props().testFunction).toHaveBeenCalled(); | |
| }); | |
| it('calls the loadMoreFunction on a scroll event near the page bottom when infinite is enabled', () => { | |
| wrapper.find(WrappedComponentClass).props().enableInfinite(); | |
| wrapper.update(); | |
| simulant.fire(window, 'scroll'); | |
| jest.runAllTimers(); | |
| expect(wrapper.find(WrappedComponentClass).props().testFunction).toHaveBeenCalled(); | |
| }); | |
| }); | |
| describe('loadMoreAtPageBottom', () => { | |
| const loadMoreFunction = jest.fn(); | |
| describe('when infinite scrolling is enabled', () => { | |
| beforeEach(() => loadMoreFunction.mockClear()); | |
| describe('when near the bottom of the page', () => { | |
| beforeEach(() => { | |
| Object.defineProperty(document.body, 'scrollHeight', { value: 1500, writable: true }); | |
| global.pageYOffset = 250; | |
| }); | |
| afterEach(() => global.pageYOffset = 0); | |
| it('calls the load more function', () => { | |
| loadMoreAtPageBottom({ infiniteEnabled: true, loadMoreFunction }); | |
| expect(loadMoreFunction).toHaveBeenCalled(); | |
| }); | |
| }); | |
| describe('when near the top of the page', () => { | |
| beforeEach(() => { | |
| Object.defineProperty(document.body, 'scrollHeight', { value: 2000, writable: true }); | |
| }); | |
| it('does not call the load more function', () => { | |
| loadMoreAtPageBottom({ infiniteEnabled: true, loadMoreFunction }); | |
| expect(loadMoreFunction).not.toHaveBeenCalled(); | |
| }); | |
| }); | |
| }); | |
| describe('when infinite scrolling is not enabled', () => { | |
| describe('when near the bottom of the page', () => { | |
| it('does not call the load more function', () => { | |
| loadMoreAtPageBottom({ infiniteEnabled: false, loadMoreFunction }); | |
| expect(loadMoreFunction).not.toHaveBeenCalled(); | |
| }); | |
| }); | |
| }); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment