Skip to content

Commit

Permalink
fix(Autocomplete): make DrawerList direction observer work (#1535)
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker authored Aug 29, 2022
1 parent a0a0082 commit fcdf9f8
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ export default class Autocomplete extends React.PureComponent {
PropTypes.string,
PropTypes.node,
]),
min_height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
enable_body_lock: PropTypes.bool,

class: PropTypes.string,
Expand Down Expand Up @@ -316,7 +315,6 @@ export default class Autocomplete extends React.PureComponent {
drawer_class: null,
page_offset: null,
observer_element: null,
min_height: null,
enable_body_lock: false,

class: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import Component from '../Autocomplete'
import { SubmitButton } from '../../../components/input/Input'
import { format } from '../../../components/number-format/NumberUtils'
import userEvent from '@testing-library/user-event'
import {
mockImplementationForDirectionObserver,
testDirectionObserver,
} from '../../../fragments/drawer-list/__tests__/DrawerListTestMocks'

const snapshotProps = {
...fakeProps(require.resolve('../Autocomplete'), {
Expand Down Expand Up @@ -61,6 +65,8 @@ const props = {

const mockData = ['AA c', 'BB cc zethx', { content: ['CC', 'cc'] }]

mockImplementationForDirectionObserver()

describe('Autocomplete component', () => {
it('has correct word and in-word highlighting', () => {
const Comp = mount(
Expand Down Expand Up @@ -1945,6 +1951,15 @@ describe('Autocomplete component', () => {
.getAttribute('data-test-id')
).toContain('bell')
})

it('has working direction observer', async () => {
const Comp = mount(<Component {...props} data={mockData} />)

// open first
toggle(Comp)

await testDirectionObserver(Comp)
})
})

describe('Autocomplete markup', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
label_direction="horizontal"
label_sr_only="label_sr_only"
max_height={1}
min_height="min_height"
mode="sync"
no_animation={true}
no_options="no_options"
Expand Down Expand Up @@ -148,7 +147,7 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
label_sr_only="label_sr_only"
list_class={null}
max_height={1}
min_height="min_height"
min_height={10}
mode="sync"
no_animation={true}
no_options="no_options"
Expand Down Expand Up @@ -250,7 +249,6 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
label_direction="horizontal"
label_sr_only="label_sr_only"
max_height={1}
min_height="min_height"
mode="sync"
no_animation={true}
no_options="no_options"
Expand Down Expand Up @@ -1172,7 +1170,6 @@ exports[`Autocomplete markup have to match snapshot 1`] = `
"label_direction": "horizontal",
"label_sr_only": "label_sr_only",
"max_height": 1,
"min_height": "min_height",
"mode": "sync",
"no_animation": true,
"no_options": "no_options",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import {
attachToBody, // in order to use document.activeElement properly
} from '../../../core/jest/jestSetup'
import Component from '../Dropdown'
import {
mockImplementationForDirectionObserver,
testDirectionObserver,
} from '../../../fragments/drawer-list/__tests__/DrawerListTestMocks'

const snapshotProps = {
...fakeProps(require.resolve('../Dropdown'), {
Expand Down Expand Up @@ -82,6 +86,8 @@ const mockData = [
'0y',
]

mockImplementationForDirectionObserver()

describe('Dropdown component', () => {
const Comp = mount(<Component {...props} data={mockData} />)

Expand Down Expand Up @@ -1007,6 +1013,51 @@ describe('Dropdown component', () => {
.hasAttribute('disabled')
).toBe(true)
})

beforeAll(() => {
window.resizeTo = function resizeTo({
width = window.innerWidth,
height = window.innerHeight,
}) {
Object.assign(this, {
innerWidth: width,
innerHeight: height,
}).dispatchEvent(new this.Event('resize'))

// new setDirectionObserver implementation
jest
.spyOn(document.documentElement, 'clientWidth', 'get')
.mockImplementation(() => width)
jest
.spyOn(document.documentElement, 'clientHeight', 'get')
.mockImplementation(() => height)
}

window.scrollTo = function resizeTo({ top = window.pageYOffset }) {
Object.assign(this, {
pageYOffset: top,
}).dispatchEvent(new this.Event('scroll'))

// new setDirectionObserver implementation
jest
.spyOn(document.documentElement, 'scrollTop', 'get')
.mockImplementation(() => top)
}

// make sure we get the correct document.documentElement.clientHeight on startup
window.resizeTo({ height: window.innerHeight })
})

it('has working direction observer', async () => {
const Comp = mount(<Component {...props} data={mockData} />)

// open first
open(Comp)

expect(Comp.props().direction).toBe('auto')

await testDirectionObserver(Comp)
})
})

describe('Dropdown markup', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,12 @@ import {
} from '../../../core/jest/jestSetup'
import Component from '../DrawerList'

beforeAll(() => {
window.resizeTo = function resizeTo({
width = window.innerWidth,
height = window.innerHeight,
}) {
Object.assign(this, {
innerWidth: width,
innerHeight: height,
}).dispatchEvent(new this.Event('resize'))

// new setDirectionObserver implementation
jest
.spyOn(document.documentElement, 'clientWidth', 'get')
.mockImplementation(() => width)
jest
.spyOn(document.documentElement, 'clientHeight', 'get')
.mockImplementation(() => height)
}

window.scrollTo = function resizeTo({ top = window.pageYOffset }) {
Object.assign(this, {
pageYOffset: top,
}).dispatchEvent(new this.Event('scroll'))

// new setDirectionObserver implementation
jest
.spyOn(document.documentElement, 'scrollTop', 'get')
.mockImplementation(() => top)
}

// make sure we get the correct document.documentElement.clientHeight on startup
window.resizeTo({ height: window.innerHeight })
})
import {
mockImplementationForDirectionObserver,
testDirectionObserver,
} from './DrawerListTestMocks'

mockImplementationForDirectionObserver()

const snapshotProps = {
...fakeProps(require.resolve('../DrawerList'), {
Expand Down Expand Up @@ -341,42 +314,7 @@ describe('DrawerList component', () => {

it('has working direction observer', async () => {
const Comp = mount(<Component {...props} data={mockData} />)
expect(Comp.props().direction).toBe('auto')

// the setDirectionObserver fn is changing this
expect(Comp.exists('.dnb-drawer-list--bottom')).toBe(true)
expect(
Comp.find('.dnb-drawer-list__options')
.instance()
.getAttribute('style')
).toBe('max-height: 33.5rem;') // jsdom default is 768 innerHeight

window.resizeTo({
height: 640, // change innerHeight
})
await wait(100)

expect(Comp.exists('.dnb-drawer-list--bottom')).toBe(true)
expect(
Comp.find('.dnb-drawer-list__options')
.instance()
.getAttribute('style')
).toBe('max-height: 28rem;')

window.scrollTo({
top: -640,
})
await wait(100)

// force re-render to get a updated state
Comp.update()

expect(Comp.exists('.dnb-drawer-list--top')).toBe(true)
expect(
Comp.find('.dnb-drawer-list__options')
.instance()
.getAttribute('style')
).toBe('max-height: 28rem;') // is now min_height
await testDirectionObserver(Comp)
})

it('will call on_hide after "esc" key', () => {
Expand Down Expand Up @@ -516,4 +454,3 @@ const keydown = (Comp, keyCode) => {
// keyCode
// })
}
const wait = (t) => new Promise((r) => setTimeout(r, t))
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
export function mockImplementationForDirectionObserver() {
beforeAll(() => {
window.resizeTo = function resizeTo({
width = window.innerWidth,
height = window.innerHeight,
}) {
Object.assign(this, {
innerWidth: width,
innerHeight: height,
}).dispatchEvent(new this.Event('resize'))

// new setDirectionObserver implementation
jest
.spyOn(document.documentElement, 'clientWidth', 'get')
.mockImplementation(() => width)
jest
.spyOn(document.documentElement, 'clientHeight', 'get')
.mockImplementation(() => height)
}

window.scrollTo = function resizeTo({ top = window.pageYOffset }) {
Object.assign(this, {
pageYOffset: top,
}).dispatchEvent(new this.Event('scroll'))

// new setDirectionObserver implementation
jest
.spyOn(document.documentElement, 'scrollTop', 'get')
.mockImplementation(() => top)
}

// make sure we get the correct document.documentElement.clientHeight on startup
window.resizeTo({ height: window.innerHeight })
})
}

export async function testDirectionObserver(Comp) {
expect(Comp.props().direction).toBe('auto')

// the setDirectionObserver fn is changing this
expect(Comp.exists('.dnb-drawer-list--bottom')).toBe(true)
expect(
Comp.find('.dnb-drawer-list__options').instance().getAttribute('style')
).toBe('max-height: 33.5rem;') // jsdom default is 768 innerHeight

window.resizeTo({
height: 640, // change innerHeight
})
await wait(100)

expect(Comp.exists('.dnb-drawer-list--bottom')).toBe(true)
expect(
Comp.find('.dnb-drawer-list__options').instance().getAttribute('style')
).toBe('max-height: 28rem;')

window.scrollTo({
top: -640,
})
await wait(100)

// force re-render to get a updated state
Comp.update()

expect(Comp.exists('.dnb-drawer-list--top')).toBe(true)
expect(
Comp.find('.dnb-drawer-list__options').instance().getAttribute('style')
).toBe('max-height: 28rem;') // is now min_height
}

const wait = (t) => new Promise((r) => setTimeout(r, t))

0 comments on commit fcdf9f8

Please sign in to comment.