Skip to content

Commit

Permalink
test(COREL): add core tests (#7119)
Browse files Browse the repository at this point in the history
* test(sanity): try to find solution for test

* wip: add theme provider to test

* test(sanity): add test to bundleForm & add createWrapper in core

* test(sanity): add test to BundleIconEditorPicker

* chore(sanity): update createWrapper

* test(sanity): update bundleForm test

* test(sanity) add createBundleDialog tests

* test(sanity) add BundleMenu tests

* refactor(sanity): add prop to createWrapper to access TestProviderOptions

---------

Co-authored-by: Ash <[email protected]>
  • Loading branch information
RitaDias and juice49 committed Oct 2, 2024
1 parent 8e6b6ee commit d694447
Show file tree
Hide file tree
Showing 11 changed files with 440 additions and 26 deletions.
15 changes: 10 additions & 5 deletions packages/sanity/src/core/bundles/components/BundleMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,27 +48,30 @@ export function BundleMenu(props: BundleListProps): JSX.Element {
<>
<MenuButton
button={button}
id="global-version-menu"
id="bundle-menu"
menu={
<StyledMenu>
<StyledMenu data-testid="bundle-menu">
{loading ? (
<Flex padding={4} justify="center">
<Flex padding={4} justify="center" data-testid="spinner">
<Spinner muted />
</Flex>
) : (
<>
<MenuItem
iconRight={
currentGlobalBundle.name === LATEST.name ? <CheckmarkIcon /> : undefined
currentGlobalBundle.name === LATEST.name ? (
<CheckmarkIcon data-testid="latest-checkmark-icon" />
) : undefined
}
onClick={handleBundleChange(LATEST)}
pressed={false}
text={LATEST.title}
data-testid="latest-menu-item"
/>
{hasBundles && (
<>
<MenuDivider />
<StyledBox>
<StyledBox data-testid="bundles-list">
{bundles
.filter((b) => !isDraftOrPublished(b.name) && !b.archivedAt)
.map((b) => (
Expand All @@ -77,6 +80,7 @@ export function BundleMenu(props: BundleListProps): JSX.Element {
onClick={handleBundleChange(b)}
padding={1}
pressed={false}
data-testid={`bundle-${b.name}`}
>
<Flex>
<BundleBadge hue={b.hue} icon={b.icon} padding={2} />
Expand All @@ -102,6 +106,7 @@ export function BundleMenu(props: BundleListProps): JSX.Element {
<Text size={1}>
<CheckmarkIcon
style={{opacity: currentGlobalBundle.name === b.name ? 1 : 0}}
data-testid={`${b.name}-checkmark-icon`}
/>
</Text>
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import {beforeEach, describe, expect, it, jest} from '@jest/globals'
import {Button} from '@sanity/ui'
import {fireEvent, render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {act} from 'react'
import {type BundleDocument} from 'sanity'

import {usePerspective} from '../../hooks/usePerspective'
import {LATEST} from '../../util/const'
import {createWrapper} from '../../util/tests/createWrapper'
import {BundleMenu} from '../BundleMenu'

jest.mock('../../hooks/usePerspective', () => ({
usePerspective: jest.fn().mockReturnValue({
currentGlobalBundle: {},
setPerspective: jest.fn(),
}),
}))

jest.mock('../../util/dummyGetters', () => ({
isDraftOrPublished: jest.fn(),
}))

describe('BundleMenu', () => {
const mockUsePerspective = usePerspective as jest.Mock
const ButtonTest = <Button>Button Test</Button>
const mockBundles: BundleDocument[] = [
{
hue: 'magenta',
_id: 'db76c50e-358b-445c-a57c-8344c588a5d5',
_type: 'bundle',
name: 'spring-drop',
_rev: '6z08CvvPnPe5pWSKJ5zPRR',
icon: 'heart-filled',
description: 'What a spring drop, allergies galore 🌸',
title: 'Spring Drop',
_updatedAt: '2024-07-02T11:37:51Z',
_createdAt: '2024-07-02T11:37:51Z',
authorId: '',
},
{
icon: 'drop',
title: 'Autumn Drop',
_type: 'bundle',
hue: 'yellow',
_id: '0e87530e-4378-45ff-9d6f-58207e89f3ed',
_createdAt: '2024-07-02T11:37:06Z',
_rev: '6z08CvvPnPe5pWSKJ5zJiK',
_updatedAt: '2024-07-02T11:37:06Z',
name: 'autumn-drop',
authorId: '',
},
{
_createdAt: '2024-07-02T11:36:00Z',
_rev: '22LTUf6tptoEq53N9U5CzE',
icon: 'sun',
description: 'What a summer drop woo hoo! ☀️',
_updatedAt: '2024-07-02T11:36:00Z',
title: 'Summer Drop',
_type: 'bundle',
hue: 'red',
_id: 'f6b2c2cc-1732-4465-bfb3-dd205b5d78e9',
name: 'summer-drop',
authorId: '',
},
]

beforeEach(() => {
mockUsePerspective.mockClear()
})

it('should render loading spinner when loading is true', async () => {
const wrapper = await createWrapper()
render(<BundleMenu button={ButtonTest} bundles={[]} loading />, {
wrapper,
})

expect(screen.getByRole('button', {name: 'Button Test'})).toBeInTheDocument()

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
expect(screen.getByTestId('bundle-menu')).toBeInTheDocument()
expect(screen.getByTestId('spinner')).toBeInTheDocument()
})
})

it('should render latest bundle menu item when bundles are null', async () => {
const wrapper = await createWrapper()
render(<BundleMenu button={ButtonTest} bundles={null} loading={false} />, {
wrapper,
})

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
expect(screen.getByTestId('latest-menu-item')).toBeInTheDocument()
expect(screen.queryByTestId('bundles-list')).not.toBeInTheDocument()
})
})

it('should render latest bundle menu item as selected when currentGlobalBundle is LATEST', async () => {
mockUsePerspective.mockReturnValue({
currentGlobalBundle: LATEST,
setPerspective: jest.fn(),
})

const wrapper = await createWrapper()
render(<BundleMenu button={ButtonTest} bundles={[]} loading={false} />, {
wrapper,
})

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
expect(screen.getByTestId('latest-menu-item')).toBeInTheDocument()
expect(screen.getByTestId('latest-checkmark-icon')).toBeInTheDocument()
})
})

it('should render bundle as selected when currentGlobalBundle is that bundle', async () => {
mockUsePerspective.mockReturnValue({
currentGlobalBundle: mockBundles[0],
setPerspective: jest.fn(),
})

const wrapper = await createWrapper()
render(<BundleMenu button={ButtonTest} bundles={mockBundles} loading={false} />, {
wrapper,
})

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
expect(screen.getByText(mockBundles[0].title)).toBeInTheDocument()
expect(screen.getByTestId(`${mockBundles[0].name}-checkmark-icon`)).toBeInTheDocument()
})
})

it('should render bundle menu items when bundles are provided', async () => {
const wrapper = await createWrapper()
render(<BundleMenu button={ButtonTest} bundles={mockBundles} loading={false} />, {
wrapper,
})

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
expect(screen.getByText('Spring Drop')).toBeInTheDocument()
expect(screen.getByText('Autumn Drop')).toBeInTheDocument()
expect(screen.getByText('Summer Drop')).toBeInTheDocument()
})
})

it('should call setPerspective when a bundle menu item is clicked', async () => {
const setPerspective = jest.fn()
mockUsePerspective.mockReturnValue({
currentGlobalBundle: LATEST,
setPerspective,
})

const wrapper = await createWrapper()
render(<BundleMenu button={ButtonTest} bundles={mockBundles} loading={false} />, {
wrapper,
})

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
userEvent.click(screen.getByTestId('bundle-spring-drop'))
expect(setPerspective).toHaveBeenCalledWith('spring-drop')
})
})

it('should render actions when actions prop is provided', async () => {
const actions = <Button>Actions</Button>

const wrapper = await createWrapper()
render(
<BundleMenu button={ButtonTest} bundles={mockBundles} loading={false} actions={actions} />,
{
wrapper,
},
)

fireEvent.click(screen.getByRole('button', {name: 'Button Test'}))

act(() => {
expect(screen.getByRole('button', {name: 'Actions'})).toBeInTheDocument()
})
})
})
23 changes: 17 additions & 6 deletions packages/sanity/src/core/bundles/components/dialog/BundleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,18 @@ export function BundleForm(props: {

const handlePublishAtInputChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const dateValue = event.target.value.trim()

// there's likely a better way of doing this
// needs to check that the date is not invalid & not empty
// in which case it can update the input value but not the actual bundle value
if (new Date(event.target.value).toString() === 'Invalid Date' && event.target.value !== '') {
if (new Date(event.target.value).toString() === 'Invalid Date' && dateValue !== '') {
setShowDateValidation(true)
setDisplayDate(event.target.value)
setDisplayDate(dateValue)
} else {
setShowDateValidation(false)
setDisplayDate(event.target.value)
onChange({...value, publishAt: event.target.value})
setDisplayDate(dateValue)
onChange({...value, publishAt: dateValue})
}
},
[onChange, value],
Expand Down Expand Up @@ -124,15 +126,23 @@ export function BundleForm(props: {
{/* localize text */}
Title
</Text>
<TextInput onChange={handleBundleTitleChange} value={title} />
<TextInput
onChange={handleBundleTitleChange}
value={title}
data-testid="bundle-form-title"
/>
</Stack>

<Stack space={3}>
<Text size={1} weight="medium">
{/* localize text */}
Description
</Text>
<TextArea onChange={handleBundleDescriptionChange} value={description} />
<TextArea
onChange={handleBundleDescriptionChange}
value={description}
data-testid="bundle-form-description"
/>
</Stack>

<Stack space={3}>
Expand Down Expand Up @@ -179,6 +189,7 @@ export function BundleForm(props: {
}
value={displayDate}
onChange={handlePublishAtInputChange}
data-testid="bundle-form-publish-at"
/>
</Stack>
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import {COLOR_HUES, type ColorHueKey} from '@sanity/color'
import {icons, type IconSymbol, SearchIcon} from '@sanity/icons'
import {Avatar, Box, Button, Flex, Popover, Stack, TextInput, useClickOutside} from '@sanity/ui'
import {
Avatar,
Box,
Button,
Container,
Flex,
Popover,
Stack,
TextInput,
useClickOutside,
} from '@sanity/ui'
import {useCallback, useState} from 'react'
import {styled} from 'styled-components'

Expand Down Expand Up @@ -60,7 +70,7 @@ export function BundleIconEditorPicker(props: {
return (
<Popover
content={
<>
<Container data-testid="popover-content">
<Flex gap={1} padding={1}>
{COLOR_HUES.map((hue) => (
<Button
Expand All @@ -69,6 +79,7 @@ export function BundleIconEditorPicker(props: {
onClick={handleHueChange(hue)}
padding={1}
selected={value.hue === hue}
data-testid={`hue-button-${hue}`}
>
<Avatar color={hue} size={0} />
</Button>
Expand Down Expand Up @@ -96,11 +107,12 @@ export function BundleIconEditorPicker(props: {
mode="bleed"
onClick={handleIconChange(key as IconSymbol)}
padding={2}
data-testId={`icon-button-${key}`}
/>
))}
</IconPickerFlex>
</StyledStack>
</>
</Container>
}
open={open}
placement="bottom-start"
Expand All @@ -115,6 +127,7 @@ export function BundleIconEditorPicker(props: {
ref={setButton}
selected={open}
radius="full"
data-testid="icon-picker-button"
>
<BundleBadge hue={value.hue} icon={value.icon} />
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export function CreateBundleDialog(props: CreateBundleDialogProps): JSX.Element
// localize Text
text="Create release"
loading={isCreating}
data-testid="create-release-button"
/>
</Flex>
</form>
Expand Down
Loading

0 comments on commit d694447

Please sign in to comment.