Skip to content

Commit

Permalink
Merge pull request #30 from vtex-apps/patch/add-tests
Browse files Browse the repository at this point in the history
Patch/add tests
  • Loading branch information
Rafael Klynger authored May 18, 2020
2 parents 518592c + 1b3bebb commit 30c7a21
Show file tree
Hide file tree
Showing 20 changed files with 218 additions and 67 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Changed
- Update dependencies.
- Add tests.

## [0.4.1] - 2020-05-13
### Changed
Expand Down
1 change: 1 addition & 0 deletions react/BaseModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export default function BaseModal(props: Props) {
onClick={handleClick}
onKeyDown={handleKeyDown}
style={inlineStyles.container}
data-testid="base-modal"
>
<TrapFocus open={open}>
{React.cloneElement(children, childProps)}
Expand Down
2 changes: 1 addition & 1 deletion react/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ interface Props {
backdrop?: MaybeResponsiveInput<BackdropMode>
}

const CSS_HANDLES = ['paper', 'topRow', 'container', 'closeButton']
const CSS_HANDLES = ['paper', 'topRow', 'container', 'closeButton'] as const

const responsiveProps = ['backdrop', 'fullScreen', 'showCloseButton'] as const

Expand Down
2 changes: 1 addition & 1 deletion react/ModalActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const CSS_HANDLES = [
'actionsContainer',
'actionsContentWrapper',
'actionsContainerEndOfContent',
]
] as const

export default function ModalActions(props: Props) {
const { children } = props
Expand Down
2 changes: 1 addition & 1 deletion react/ModalContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import styles from './styles.css'
import { useModalDispatch } from './components/ModalContext'
import useIntersection from './modules/useIntersection'

const CSS_HANDLES = ['contentContainer']
const CSS_HANDLES = ['contentContainer'] as const

const ModalContent: React.FC = props => {
const { children } = props
Expand Down
2 changes: 1 addition & 1 deletion react/ModalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const CSS_HANDLES = [
'closeButton',
'headerContent',
'closeButtonContainer',
]
] as const

export default React.memo(function ModalHeader(props: Props) {
const {
Expand Down
2 changes: 1 addition & 1 deletion react/ModalTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
ModalContextProvider,
} from './components/ModalContext'

const CSS_HANDLES = ['triggerContainer']
const CSS_HANDLES = ['triggerContainer'] as const

enum TriggerMode {
click = 'click',
Expand Down
13 changes: 13 additions & 0 deletions react/__mocks__/testUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export function findCSSHandles(
container: HTMLElement,
handles: readonly string[]
) {
const foundNodes = handles
.map(handle => {
const foundNodesInner = container.getElementsByClassName(handle)
return foundNodesInner.length > 0 ? handle : ''
})
.filter(result => result !== '')

return foundNodes
}
12 changes: 12 additions & 0 deletions react/__mocks__/vtex.css-handles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function useCssHandles(input: string[]) {
const acc: Record<string, string> = {}
input.forEach(value => {
acc[value] = value
})

return acc
}

export const applyModifiers = (input: string, modifier: string) => {
return modifier ? `${input}--${modifier}` : input
}
1 change: 1 addition & 0 deletions react/__mocks__/vtex.render-runtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const canUseDOM = true
48 changes: 48 additions & 0 deletions react/__tests__/Backdrop.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react'
import { render, fireEvent } from '@vtex/test-tools/react'

// eslint-disable-next-line jest/no-mocks-import
import { findCSSHandles } from '../__mocks__/testUtils'
import Backdrop, { CSS_HANDLES } from '../components/Backdrop'

describe('<Backdrop />', () => {
it('should render', () => {
const { baseElement } = render(<Backdrop open />)

expect(baseElement).toBeTruthy()
})

it('should find all declared handles', () => {
const { container } = render(<Backdrop open />)

const foundHandles = findCSSHandles(container, CSS_HANDLES)
expect(foundHandles).toEqual(CSS_HANDLES)
})

it('should have visibility hidden and opacity 0 if open === false', () => {
const { getByTestId } = render(<Backdrop open={false} />)

const container = getByTestId('modal-backdrop-container')

expect(container.style.getPropertyValue('opacity')).toBe('0')
expect(container.style.getPropertyValue('visibility')).toBe('hidden')
})

it('should call onClick when backdrop is clicked', () => {
const spy = jest.fn()
const { getByRole } = render(<Backdrop open onClick={spy} />)

const backdropElement = getByRole('presentation')
fireEvent.click(backdropElement, { bubbles: true, cancelable: true })

expect(spy).toBeCalledTimes(1)
})

it('should have a role="presentation"', () => {
const spy = jest.fn()
const { queryByRole } = render(<Backdrop open onClick={spy} />)

const container = queryByRole('presentation')
expect(container).toBeTruthy()
})
})
111 changes: 111 additions & 0 deletions react/__tests__/BaseModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import React from 'react'
import { render, fireEvent } from '@vtex/test-tools/react'

import BaseModal from '../BaseModal'
import Fade from '../components/Animations/Fade'
import { BackdropMode } from '../components/Backdrop'

describe('<BaseModal />', () => {
it('should render the modal with the children', () => {
const onClose = jest.fn()
const { queryByText, queryByRole } = render(
<BaseModal open onClose={onClose} backdrop={BackdropMode.none}>
<Fade in>
<div>Hello VTEX</div>
</Fade>
</BaseModal>
)

expect(queryByText('Hello VTEX')).toBeTruthy()
expect(queryByRole('presentation')).toBeTruthy()
})

it("shouldn't render anything if open is false", () => {
const { queryByText, queryByRole } = render(
<BaseModal open={false} onClose={() => {}}>
<Fade in>
<div>Hello VTEX</div>
</Fade>
</BaseModal>
)

expect(queryByText('Hello VTEX')).toBeNull()
expect(queryByRole('presentation')).toBeNull()
})

it('should call onClose if Esc is pressed', () => {
const onClose = jest.fn()
const { getByRole } = render(
<BaseModal open onClose={onClose} backdrop={BackdropMode.none}>
<Fade in>
<div>Hello VTEX</div>
</Fade>
</BaseModal>
)

fireEvent.keyDown(getByRole('presentation'), {
key: 'Escape',
code: 27,
})

expect(onClose).toBeCalledTimes(1)
})

it("shouldn't call onClose if disableEscapeKeyDown", () => {
const onClose = jest.fn()
const { getByTestId } = render(
<BaseModal open onClose={onClose} disableEscapeKeyDown>
<Fade in>
<div data-testid="base-modal-child">Hello VTEX</div>
</Fade>
</BaseModal>
)

fireEvent.keyDown(getByTestId('base-modal-child'), {
key: 'Escape',
code: 27,
})

expect(onClose).not.toBeCalled()
})

it('should have role="presentation"', () => {
const onClose = jest.fn()
const { queryByRole } = render(
<BaseModal open onClose={onClose} backdrop={BackdropMode.none}>
<Fade in>
<div>Hello VTEX</div>
</Fade>
</BaseModal>
)

expect(queryByRole('presentation')).toBeTruthy()
})

it('should not propagate click events to outside of the modal', () => {
const onClose = jest.fn()
const outsideClick = jest.fn()
const onClick = jest.fn()

const { getByTestId } = render(
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
<div onClick={outsideClick}>
<BaseModal open onClick={onClick} onClose={onClose}>
<Fade in>
<div>Hello VTEX</div>
</Fade>
</BaseModal>
</div>
)

const baseModal = getByTestId('base-modal')

fireEvent.click(baseModal, {
bubbles: true,
cancelable: true,
})

expect(onClick).toBeCalledTimes(1)
expect(outsideClick).not.toBeCalled()
})
})
5 changes: 0 additions & 5 deletions react/__tests__/index.test.tsx

This file was deleted.

7 changes: 5 additions & 2 deletions react/components/Backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface Props {
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void
}

const CSS_HANDLES = ['backdropContainer', 'backdrop']
export const CSS_HANDLES = ['backdropContainer', 'backdrop'] as const

const Backdrop: React.FC<Props> = props => {
const { children, open, onClick, transitionDuration } = props
Expand All @@ -30,7 +30,10 @@ const Backdrop: React.FC<Props> = props => {

return (
<Fade in={open} timeout={transitionDuration}>
<div className={handles.backdropContainer}>
<div
className={handles.backdropContainer}
data-testid="modal-backdrop-container"
>
<div
role="presentation"
onClick={handleClick}
Expand Down
5 changes: 4 additions & 1 deletion react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
"@types/react": "^16.9.2",
"@types/react-transition-group": "^4.2.3",
"@vtex/test-tools": "^1.1.0",
"typescript": "3.8.3"
"typescript": "3.8.3",
"vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.css-handles",
"vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.render-runtime",
"vtex.store-icons": "http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.store-icons"
},
"version": "0.4.1"
}
5 changes: 0 additions & 5 deletions react/typings/vtex.css-handles.d.ts

This file was deleted.

39 changes: 3 additions & 36 deletions react/typings/vtex.render-runtime.d.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,5 @@
/* Typings for `render-runtime` */
declare module 'vtex.render-runtime' {
import { Component, ComponentType, ReactElement, ReactType } from 'react'

export interface NavigationOptions {
page: string
params?: any
}

export interface RenderContextProps {
runtime: {
navigate: (options: NavigationOptions) => void
}
}

interface ExtensionPointProps {
id: string
[key: string]: any
}
import 'vtex.render-runtime'

export const ExtensionPoint: ComponentType<ExtensionPointProps>

interface ChildBlockProps {
id: string
}

export const ChildBlock: ComponentType<ChildBlockProps>
export const useChildBlock = function({ id: string }): object {}

export const Helmet: ReactElement
export const Link: ReactType
export const NoSSR: ReactElement
export const RenderContextConsumer: ReactElement
export const canUseDOM: boolean
export const withRuntimeContext: <TOriginalProps extends {}>(
Component: ComponentType<TOriginalProps & RenderContextProps>
) => ComponentType<TOriginalProps>
declare module 'vtex.render-runtime' {
const canUseDOM: boolean
}
4 changes: 0 additions & 4 deletions react/typings/vtex.store-icons.d.ts

This file was deleted.

9 changes: 0 additions & 9 deletions react/typings/vtex.styleguide.d.ts

This file was deleted.

12 changes: 12 additions & 0 deletions react/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4678,6 +4678,18 @@ [email protected]:
core-util-is "1.0.2"
extsprintf "^1.2.0"

"vtex.css-handles@http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.css-handles":
version "0.4.2"
resolved "http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.css-handles#62ee61d1bb9efdc919e5cf4bb44fabcf9050d255"

"vtex.render-runtime@http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.render-runtime":
version "8.100.4"
resolved "http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.render-runtime#b94c966be2d1c3d8bc9f1caf2dd9f462d88e98d2"

"vtex.store-icons@http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.store-icons":
version "0.17.0"
resolved "http://vtex.vtexassets.com/_v/public/typings/v1/[email protected]/public/@types/vtex.store-icons#1da7ec2f89522d8c5ed3418fec8fbc82817499db"

w3c-hr-time@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
Expand Down

0 comments on commit 30c7a21

Please sign in to comment.