import _, { forEach, has } from 'lodash'; import React from 'react'; import { mount, shallow } from 'enzyme'; import assert from 'assert'; import { common } from '../../util/generic-tests'; import { dispatchDOMEvent } from '../../util/dom-helpers'; import StickySection from './StickySection'; describe('StickySection', () => { common(StickySection); describe('render', () => { it('should render a div with class `lucid-StickySection`', () => { const wrapper = shallow(); assert.equal( wrapper.find('div.lucid-StickySection').length, 1, 'StickySection must render the base div at root' ); }); }); describe('props', () => { describe('root pass throughs', () => { let wrapper: any; beforeEach(() => { const props = { lowerBound: 20, topOffset: 200, className: 'wut', style: { marginRight: 10 }, initialState: { test: true }, callbackId: 1, 'data-testid': 10, }; wrapper = shallow(); }); afterEach(() => { wrapper.unmount(); }); it('passes through props not defined in `propTypes` to the root element.', () => { const rootProps = wrapper.find('.lucid-StickySection').props(); expect(wrapper.first().prop(['className'])).toContain('wut'); expect(wrapper.first().prop(['style'])).toMatchObject({ marginRight: 10, }); expect(wrapper.first().prop(['data-testid'])).toBe(10); // 'className' and style are plucked from the pass through object // but still appears becuase each one is also directly added to the root element as a prop forEach(['className', 'data-testid', 'style', 'children'], (prop) => { expect(has(rootProps, prop)).toBe(true); }); }); it('omits the props defined in `propTypes` (plus, in addition, `initialState`, and `callbackId`) from the root element', () => { const rootProps = wrapper.find('.lucid-StickySection').props(); forEach( ['lowerBound', 'topOffset', 'initialState', 'callbackId'], (prop) => { expect(has(rootProps, prop)).toBe(false); } ); }); }); describe('lowerBound', () => { let wrapper: any; let mountTestdiv: any; beforeEach(() => { document.body.style.height = '10000px'; mountTestdiv = document.createElement('div'); document.body.appendChild(mountTestdiv); }); afterEach(() => { if (wrapper) { wrapper.unmount(); wrapper = null; } document.body.style.height = ''; mountTestdiv.parentNode.removeChild(mountTestdiv); }); it.skip('render the sticky section normally (not fixed) when scrolled past the lowerBound value', () => { // set the lowerBound to 500 wrapper = mount(, { attachTo: mountTestdiv, }); // scroll to position 499 (window as any).pageYOffset = 499; dispatchDOMEvent(window, 'scroll'); // check that the fixed position sticky section is rendered assert.equal( _.get( wrapper.find('.lucid-StickySection-sticky-frame').prop('style'), 'position' ), 'fixed', 'sticky frame must be position fixed' ); assert.equal( _.get( wrapper.find('.lucid-StickySection-sticky-section').prop('style'), 'position' ), 'absolute', 'sticky section must be position absolute' ); // scroll to position 501, past the lowerBound value (window as any).pageYOffset = 501; dispatchDOMEvent(window, 'scroll'); // check that the sticky section is no longer fixed position assert.notEqual( _.get( wrapper.find('.lucid-StickySection-sticky-frame').prop('style'), 'position' ), 'fixed', 'sticky frame must not be position fixed' ); assert.notEqual( _.get( wrapper.find('.lucid-StickySection-sticky-section').prop('style'), 'position' ), 'absolute', 'sticky section must not be position absolute' ); }); }); describe('viewportWidth', () => { it('should set the width of the sticky frame to this value when the section `isAboveFold`', () => { const wrapper = shallow().setState( { isAboveFold: true, } ); assert.equal( _.get( wrapper.find('.lucid-StickySection-sticky-frame').prop('style'), 'width' ), 321, 'sticky frame must have width of the prop value' ); }); it('should not set the width of the sticky frame when the section `isAboveFold` is false', () => { const wrapper = shallow().setState( { isAboveFold: false, } ); assert.equal( _.get( wrapper.find('.lucid-StickySection-sticky-frame').prop('style'), 'width' ), undefined, 'sticky frame width must not be set' ); }); it('should set the width of the sticky frame to the container width when value is not given and the section `isAboveFold`', () => { const wrapper = shallow().setState({ isAboveFold: true, containerRect: { width: 432, }, }); assert.equal( _.get( wrapper.find('.lucid-StickySection-sticky-frame').prop('style'), 'width' ), 432, 'sticky frame width must match the container width' ); }); }); }); });