test: finished all ui components test (#3588)
* test: finished all ui components test * chore: update naming of mock handle change modal test
This commit is contained in:
parent
fe9936cf5b
commit
ac67247636
@ -52,6 +52,7 @@
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/jest-dom": "^6.5.0",
|
||||
"@testing-library/react": "^16.0.1",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/jest": "^29.5.12",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-transform-css": "^6.0.1",
|
||||
|
||||
@ -6,7 +6,7 @@ import { Button, buttonConfig } from './index'
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('Button', () => {
|
||||
describe('@joi/core/Button', () => {
|
||||
it('renders with default props', () => {
|
||||
render(<Button>Click me</Button>)
|
||||
const button = screen.getByRole('button', { name: /click me/i })
|
||||
@ -14,6 +14,12 @@ describe('Button', () => {
|
||||
expect(button).toHaveClass('btn btn--primary btn--medium btn--solid')
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
render(<Button className="custom-class">Test Button</Button>)
|
||||
const badge = screen.getByText('Test Button')
|
||||
expect(badge).toHaveClass('custom-class')
|
||||
})
|
||||
|
||||
it('renders as a child component when asChild is true', () => {
|
||||
render(
|
||||
<Button asChild>
|
||||
@ -58,11 +64,27 @@ describe('Button', () => {
|
||||
expect(button).toHaveClass('btn btn--block')
|
||||
})
|
||||
|
||||
it('merges custom className with generated classes', () => {
|
||||
render(<Button className="custom-class">Custom Class Button</Button>)
|
||||
const button = screen.getByRole('button', { name: /custom class button/i })
|
||||
expect(button).toHaveClass(
|
||||
'btn btn--primary btn--medium btn--solid custom-class'
|
||||
)
|
||||
it('fails when a new theme is added without updating the test', () => {
|
||||
const expectedThemes = ['primary', 'ghost', 'icon', 'destructive']
|
||||
const actualThemes = Object.keys(buttonConfig.variants.theme)
|
||||
expect(actualThemes).toEqual(expectedThemes)
|
||||
})
|
||||
|
||||
it('fails when a new variant is added without updating the test', () => {
|
||||
const expectedVariant = ['solid', 'soft', 'outline']
|
||||
const actualVariants = Object.keys(buttonConfig.variants.variant)
|
||||
expect(actualVariants).toEqual(expectedVariant)
|
||||
})
|
||||
|
||||
it('fails when a new size is added without updating the test', () => {
|
||||
const expectedSizes = ['small', 'medium', 'large']
|
||||
const actualSizes = Object.keys(buttonConfig.variants.size)
|
||||
expect(actualSizes).toEqual(expectedSizes)
|
||||
})
|
||||
|
||||
it('fails when a new variant CVA is added without updating the test', () => {
|
||||
const expectedVariantsCVA = ['theme', 'variant', 'size', 'block']
|
||||
const actualVariant = Object.keys(buttonConfig.variants)
|
||||
expect(actualVariant).toEqual(expectedVariantsCVA)
|
||||
})
|
||||
})
|
||||
|
||||
50
joi/src/core/Checkbox/Checkbox.test.tsx
Normal file
50
joi/src/core/Checkbox/Checkbox.test.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import React from 'react'
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Checkbox } from './index'
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('@joi/core/Checkbox', () => {
|
||||
it('renders correctly with label', () => {
|
||||
render(<Checkbox id="test-checkbox" label="Test Checkbox" />)
|
||||
expect(screen.getByLabelText('Test Checkbox')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders with helper description', () => {
|
||||
render(<Checkbox id="test-checkbox" helperDescription="Helper text" />)
|
||||
expect(screen.getByText('Helper text')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders error message when provided', () => {
|
||||
render(<Checkbox id="test-checkbox" errorMessage="Error occurred" />)
|
||||
expect(screen.getByText('Error occurred')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('calls onChange when clicked', () => {
|
||||
const mockOnChange = jest.fn()
|
||||
render(
|
||||
<Checkbox
|
||||
id="test-checkbox"
|
||||
label="Test Checkbox"
|
||||
onChange={mockOnChange}
|
||||
/>
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByLabelText('Test Checkbox'))
|
||||
expect(mockOnChange).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
render(<Checkbox id="test-checkbox" className="custom-class" />)
|
||||
expect(screen.getByRole('checkbox').parentElement).toHaveClass(
|
||||
'custom-class'
|
||||
)
|
||||
})
|
||||
|
||||
it('disables the checkbox when disabled prop is true', () => {
|
||||
render(<Checkbox id="test-checkbox" label="Disabled Checkbox" disabled />)
|
||||
expect(screen.getByLabelText('Disabled Checkbox')).toBeDisabled()
|
||||
})
|
||||
})
|
||||
53
joi/src/core/Input/Input.test.tsx
Normal file
53
joi/src/core/Input/Input.test.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React from 'react'
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Input } from './index'
|
||||
|
||||
// Mock the styles import
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('@joi/core/Input', () => {
|
||||
it('renders correctly', () => {
|
||||
render(<Input placeholder="Test input" />)
|
||||
expect(screen.getByPlaceholderText('Test input')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
render(<Input className="custom-class" />)
|
||||
expect(screen.getByRole('textbox')).toHaveClass('custom-class')
|
||||
})
|
||||
|
||||
it('aligns text to the right when textAlign prop is set', () => {
|
||||
render(<Input textAlign="right" />)
|
||||
expect(screen.getByRole('textbox')).toHaveClass('text-right')
|
||||
})
|
||||
|
||||
it('renders prefix icon when provided', () => {
|
||||
render(<Input prefixIcon={<span data-testid="prefix-icon">Prefix</span>} />)
|
||||
expect(screen.getByTestId('prefix-icon')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders suffix icon when provided', () => {
|
||||
render(<Input suffixIcon={<span data-testid="suffix-icon">Suffix</span>} />)
|
||||
expect(screen.getByTestId('suffix-icon')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders clear icon when clearable is true', () => {
|
||||
render(<Input clearable />)
|
||||
expect(screen.getByTestId('cross-2-icon')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('calls onClick when input is clicked', () => {
|
||||
const onClick = jest.fn()
|
||||
render(<Input onClick={onClick} />)
|
||||
fireEvent.click(screen.getByRole('textbox'))
|
||||
expect(onClick).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('calls onClear when clear icon is clicked', () => {
|
||||
const onClear = jest.fn()
|
||||
render(<Input clearable onClear={onClear} />)
|
||||
fireEvent.click(screen.getByTestId('cross-2-icon'))
|
||||
expect(onClear).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
@ -42,7 +42,7 @@ const Input = forwardRef<HTMLInputElement, Props>(
|
||||
)}
|
||||
{clearable && (
|
||||
<div className="input__clear-icon" onClick={onClear}>
|
||||
<Cross2Icon className="text-red-200" />
|
||||
<Cross2Icon data-testid="cross-2-icon" className="text-red-200" />
|
||||
</div>
|
||||
)}
|
||||
<input
|
||||
|
||||
78
joi/src/core/Modal/Modal.test.tsx
Normal file
78
joi/src/core/Modal/Modal.test.tsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React from 'react'
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Modal } from './index'
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('Modal', () => {
|
||||
it('renders the modal with trigger and content', () => {
|
||||
render(
|
||||
<Modal
|
||||
trigger={<button>Open Modal</button>}
|
||||
content={<div>Modal Content</div>}
|
||||
/>
|
||||
)
|
||||
|
||||
expect(screen.getByText('Open Modal')).toBeInTheDocument()
|
||||
fireEvent.click(screen.getByText('Open Modal'))
|
||||
expect(screen.getByText('Modal Content')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders the modal with title', () => {
|
||||
render(
|
||||
<Modal
|
||||
trigger={<button>Open Modal</button>}
|
||||
content={<div>Modal Content</div>}
|
||||
title="Modal Title"
|
||||
/>
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('Open Modal'))
|
||||
expect(screen.getByText('Modal Title')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('renders full page modal', () => {
|
||||
render(
|
||||
<Modal
|
||||
trigger={<button>Open Modal</button>}
|
||||
content={<div>Modal Content</div>}
|
||||
fullPage
|
||||
/>
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('Open Modal'))
|
||||
expect(screen.getByRole('dialog')).toHaveClass('modal__content--fullpage')
|
||||
})
|
||||
|
||||
it('hides close button when hideClose is true', () => {
|
||||
render(
|
||||
<Modal
|
||||
trigger={<button>Open Modal</button>}
|
||||
content={<div>Modal Content</div>}
|
||||
hideClose
|
||||
/>
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('Open Modal'))
|
||||
expect(screen.queryByLabelText('Close')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('calls onOpenChange when opening and closing the modal', () => {
|
||||
const onOpenChangeMock = jest.fn()
|
||||
render(
|
||||
<Modal
|
||||
trigger={<button>Open Modal</button>}
|
||||
content={<div>Modal Content</div>}
|
||||
onOpenChange={onOpenChangeMock}
|
||||
/>
|
||||
)
|
||||
|
||||
fireEvent.click(screen.getByText('Open Modal'))
|
||||
expect(onOpenChangeMock).toHaveBeenCalledWith(true)
|
||||
|
||||
fireEvent.click(screen.getByLabelText('Close'))
|
||||
expect(onOpenChangeMock).toHaveBeenCalledWith(false)
|
||||
})
|
||||
})
|
||||
55
joi/src/core/Progress/Progress.test.tsx
Normal file
55
joi/src/core/Progress/Progress.test.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Progress } from './index'
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('@joi/core/Progress', () => {
|
||||
it('renders with default props', () => {
|
||||
render(<Progress value={50} />)
|
||||
const progressElement = screen.getByRole('progressbar')
|
||||
expect(progressElement).toBeInTheDocument()
|
||||
expect(progressElement).toHaveClass('progress')
|
||||
expect(progressElement).toHaveClass('progress--medium')
|
||||
expect(progressElement).toHaveAttribute('aria-valuenow', '50')
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
render(<Progress value={50} className="custom-class" />)
|
||||
const progressElement = screen.getByRole('progressbar')
|
||||
expect(progressElement).toHaveClass('custom-class')
|
||||
})
|
||||
|
||||
it('renders with different sizes', () => {
|
||||
const { rerender } = render(<Progress value={50} size="small" />)
|
||||
let progressElement = screen.getByRole('progressbar')
|
||||
expect(progressElement).toHaveClass('progress--small')
|
||||
|
||||
rerender(<Progress value={50} size="large" />)
|
||||
progressElement = screen.getByRole('progressbar')
|
||||
expect(progressElement).toHaveClass('progress--large')
|
||||
})
|
||||
|
||||
it('sets the correct transform style based on value', () => {
|
||||
render(<Progress value={75} />)
|
||||
const progressElement = screen.getByRole('progressbar')
|
||||
const indicatorElement = progressElement.firstChild as HTMLElement
|
||||
expect(indicatorElement).toHaveStyle('transform: translateX(-25%)')
|
||||
})
|
||||
|
||||
it('handles edge cases for value', () => {
|
||||
const { rerender } = render(<Progress value={0} />)
|
||||
let progressElement = screen.getByRole('progressbar')
|
||||
let indicatorElement = progressElement.firstChild as HTMLElement
|
||||
expect(indicatorElement).toHaveStyle('transform: translateX(-100%)')
|
||||
expect(progressElement).toHaveAttribute('aria-valuenow', '0')
|
||||
|
||||
rerender(<Progress value={100} />)
|
||||
progressElement = screen.getByRole('progressbar')
|
||||
indicatorElement = progressElement.firstChild as HTMLElement
|
||||
expect(indicatorElement).toHaveStyle('transform: translateX(-0%)')
|
||||
expect(progressElement).toHaveAttribute('aria-valuenow', '100')
|
||||
})
|
||||
})
|
||||
@ -27,7 +27,14 @@ export interface ProgressProps
|
||||
|
||||
const Progress = ({ className, size, value, ...props }: ProgressProps) => {
|
||||
return (
|
||||
<div className={twMerge(progressVariants({ size, className }))} {...props}>
|
||||
<div
|
||||
role="progressbar"
|
||||
aria-valuenow={value}
|
||||
aria-valuemin={0}
|
||||
aria-valuemax={100}
|
||||
className={twMerge(progressVariants({ size, className }))}
|
||||
{...props}
|
||||
>
|
||||
<div
|
||||
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
||||
className="progress--indicator"
|
||||
|
||||
47
joi/src/core/ScrollArea/ScrollArea.test.tsx
Normal file
47
joi/src/core/ScrollArea/ScrollArea.test.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { ScrollArea } from './index'
|
||||
|
||||
declare const global: typeof globalThis
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
class ResizeObserverMock {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
}
|
||||
|
||||
global.ResizeObserver = ResizeObserverMock
|
||||
|
||||
describe('@joi/core/ScrollArea', () => {
|
||||
it('renders children correctly', () => {
|
||||
render(
|
||||
<ScrollArea>
|
||||
<div data-testid="child">Test Content</div>
|
||||
</ScrollArea>
|
||||
)
|
||||
|
||||
const child = screen.getByTestId('child')
|
||||
expect(child).toBeInTheDocument()
|
||||
expect(child).toHaveTextContent('Test Content')
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
const { container } = render(<ScrollArea className="custom-class" />)
|
||||
|
||||
const root = container.firstChild as HTMLElement
|
||||
expect(root).toHaveClass('scroll-area__root')
|
||||
expect(root).toHaveClass('custom-class')
|
||||
})
|
||||
|
||||
it('forwards ref to the Viewport component', () => {
|
||||
const ref = React.createRef<HTMLDivElement>()
|
||||
render(<ScrollArea ref={ref} />)
|
||||
|
||||
expect(ref.current).toBeInstanceOf(HTMLDivElement)
|
||||
expect(ref.current).toHaveClass('scroll-area__viewport')
|
||||
})
|
||||
})
|
||||
107
joi/src/core/Select/Select.test.tsx
Normal file
107
joi/src/core/Select/Select.test.tsx
Normal file
@ -0,0 +1,107 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { Select } from './index'
|
||||
import '@testing-library/jest-dom'
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
jest.mock('tailwind-merge', () => ({
|
||||
twMerge: (...classes: string[]) => classes.filter(Boolean).join(' '),
|
||||
}))
|
||||
|
||||
const mockOnValueChange = jest.fn()
|
||||
jest.mock('@radix-ui/react-select', () => ({
|
||||
Root: ({
|
||||
children,
|
||||
onValueChange,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
onValueChange?: (value: string) => void
|
||||
}) => {
|
||||
mockOnValueChange.mockImplementation(onValueChange)
|
||||
return <div data-testid="select-root">{children}</div>
|
||||
},
|
||||
Trigger: ({
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
}) => (
|
||||
<button data-testid="select-trigger" className={className}>
|
||||
{children}
|
||||
</button>
|
||||
),
|
||||
Value: ({ placeholder }: { placeholder?: string }) => (
|
||||
<span data-testid="select-value">{placeholder}</span>
|
||||
),
|
||||
Icon: ({ children }: { children: React.ReactNode }) => (
|
||||
<span data-testid="select-icon">{children}</span>
|
||||
),
|
||||
Portal: ({ children }: { children: React.ReactNode }) => (
|
||||
<div data-testid="select-portal">{children}</div>
|
||||
),
|
||||
Content: ({ children }: { children: React.ReactNode }) => (
|
||||
<div data-testid="select-content">{children}</div>
|
||||
),
|
||||
Viewport: ({ children }: { children: React.ReactNode }) => (
|
||||
<div data-testid="select-viewport">{children}</div>
|
||||
),
|
||||
Item: ({ children, value }: { children: React.ReactNode; value: string }) => (
|
||||
<div
|
||||
data-testid={`select-item-${value}`}
|
||||
onClick={() => mockOnValueChange(value)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
ItemText: ({ children }: { children: React.ReactNode }) => (
|
||||
<span data-testid="select-item-text">{children}</span>
|
||||
),
|
||||
ItemIndicator: ({ children }: { children: React.ReactNode }) => (
|
||||
<span data-testid="select-item-indicator">{children}</span>
|
||||
),
|
||||
Arrow: () => <div data-testid="select-arrow" />,
|
||||
}))
|
||||
describe('@joi/core/Select', () => {
|
||||
const options = [
|
||||
{ name: 'Option 1', value: 'option1' },
|
||||
{ name: 'Option 2', value: 'option2' },
|
||||
]
|
||||
|
||||
it('renders with placeholder', () => {
|
||||
render(<Select placeholder="Select an option" options={options} />)
|
||||
expect(screen.getByTestId('select-value')).toHaveTextContent(
|
||||
'Select an option'
|
||||
)
|
||||
})
|
||||
|
||||
it('renders options', () => {
|
||||
render(<Select options={options} />)
|
||||
expect(screen.getByTestId('select-item-option1')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('select-item-option2')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('calls onValueChange when an option is selected', async () => {
|
||||
const user = userEvent.setup()
|
||||
const onValueChange = jest.fn()
|
||||
render(<Select options={options} onValueChange={onValueChange} />)
|
||||
|
||||
await user.click(screen.getByTestId('select-trigger'))
|
||||
await user.click(screen.getByTestId('select-item-option1'))
|
||||
|
||||
expect(onValueChange).toHaveBeenCalledWith('option1')
|
||||
})
|
||||
|
||||
it('applies disabled class when disabled prop is true', () => {
|
||||
render(<Select options={options} disabled />)
|
||||
expect(screen.getByTestId('select-trigger')).toHaveClass('select__disabled')
|
||||
})
|
||||
|
||||
it('applies block class when block prop is true', () => {
|
||||
render(<Select options={options} block />)
|
||||
expect(screen.getByTestId('select-trigger')).toHaveClass('w-full')
|
||||
})
|
||||
})
|
||||
65
joi/src/core/Slider/Slider.test.tsx
Normal file
65
joi/src/core/Slider/Slider.test.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
import React from 'react'
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Slider } from './index'
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
// Mock Radix UI Slider
|
||||
jest.mock('@radix-ui/react-slider', () => ({
|
||||
Root: ({ children, onValueChange, ...props }: any) => (
|
||||
<div
|
||||
data-testid="slider-root"
|
||||
{...props}
|
||||
onChange={(e: any) =>
|
||||
onValueChange && onValueChange([parseInt(e.target.value)])
|
||||
}
|
||||
>
|
||||
<input type="range" {...props} />
|
||||
{children}
|
||||
</div>
|
||||
),
|
||||
Track: ({ children }: any) => (
|
||||
<div data-testid="slider-track">{children}</div>
|
||||
),
|
||||
Range: () => <div data-testid="slider-range" />,
|
||||
Thumb: () => <div data-testid="slider-thumb" />,
|
||||
}))
|
||||
|
||||
describe('@joi/core/Slider', () => {
|
||||
it('renders correctly with default props', () => {
|
||||
render(<Slider />)
|
||||
expect(screen.getByTestId('slider-root')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('slider-track')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('slider-range')).toBeInTheDocument()
|
||||
expect(screen.getByTestId('slider-thumb')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('passes props correctly to SliderPrimitive.Root', () => {
|
||||
const props = {
|
||||
name: 'test-slider',
|
||||
min: 0,
|
||||
max: 100,
|
||||
value: [50],
|
||||
step: 1,
|
||||
disabled: true,
|
||||
}
|
||||
render(<Slider {...props} />)
|
||||
const sliderRoot = screen.getByTestId('slider-root')
|
||||
expect(sliderRoot).toHaveAttribute('name', 'test-slider')
|
||||
expect(sliderRoot).toHaveAttribute('min', '0')
|
||||
expect(sliderRoot).toHaveAttribute('max', '100')
|
||||
expect(sliderRoot).toHaveAttribute('value', '50')
|
||||
expect(sliderRoot).toHaveAttribute('step', '1')
|
||||
expect(sliderRoot).toHaveAttribute('disabled', '')
|
||||
})
|
||||
|
||||
it('calls onValueChange when value changes', () => {
|
||||
const onValueChange = jest.fn()
|
||||
render(<Slider onValueChange={onValueChange} min={0} max={100} step={1} />)
|
||||
const input = screen.getByTestId('slider-root').querySelector('input')
|
||||
fireEvent.change(input!, { target: { value: '75' } })
|
||||
expect(onValueChange).toHaveBeenCalledWith([75])
|
||||
})
|
||||
})
|
||||
52
joi/src/core/Switch/Switch.test.tsx
Normal file
52
joi/src/core/Switch/Switch.test.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Switch } from './index'
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('@joi/core/Switch', () => {
|
||||
it('renders correctly', () => {
|
||||
const { getByRole } = render(<Switch />)
|
||||
const checkbox = getByRole('checkbox')
|
||||
expect(checkbox).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
const { container } = render(<Switch className="custom-class" />)
|
||||
expect(container.firstChild).toHaveClass('switch custom-class')
|
||||
})
|
||||
|
||||
it('can be checked and unchecked', () => {
|
||||
const { getByRole } = render(<Switch />)
|
||||
const checkbox = getByRole('checkbox') as HTMLInputElement
|
||||
|
||||
expect(checkbox.checked).toBe(false)
|
||||
fireEvent.click(checkbox)
|
||||
expect(checkbox.checked).toBe(true)
|
||||
fireEvent.click(checkbox)
|
||||
expect(checkbox.checked).toBe(false)
|
||||
})
|
||||
|
||||
it('can be disabled', () => {
|
||||
const { getByRole } = render(<Switch disabled />)
|
||||
const checkbox = getByRole('checkbox') as HTMLInputElement
|
||||
expect(checkbox).toBeDisabled()
|
||||
})
|
||||
|
||||
it('calls onChange when clicked', () => {
|
||||
const handleChange = jest.fn()
|
||||
const { getByRole } = render(<Switch onChange={handleChange} />)
|
||||
const checkbox = getByRole('checkbox')
|
||||
|
||||
fireEvent.click(checkbox)
|
||||
expect(handleChange).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('can have a default checked state', () => {
|
||||
const { getByRole } = render(<Switch defaultChecked />)
|
||||
const checkbox = getByRole('checkbox') as HTMLInputElement
|
||||
expect(checkbox.checked).toBe(true)
|
||||
})
|
||||
})
|
||||
99
joi/src/core/Tabs/Tabs.test.tsx
Normal file
99
joi/src/core/Tabs/Tabs.test.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
import React from 'react'
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { Tabs, TabsContent } from './index'
|
||||
|
||||
// Mock the Tooltip component
|
||||
jest.mock('../Tooltip', () => ({
|
||||
Tooltip: ({ children, content, trigger }) => (
|
||||
<div data-testid="mock-tooltip" data-tooltip-content={content}>
|
||||
{trigger || children}
|
||||
</div>
|
||||
),
|
||||
}))
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('@joi/core/Tabs', () => {
|
||||
const mockOptions = [
|
||||
{ name: 'Tab 1', value: 'tab1' },
|
||||
{ name: 'Tab 2', value: 'tab2' },
|
||||
{
|
||||
name: 'Tab 3',
|
||||
value: 'tab3',
|
||||
disabled: true,
|
||||
tooltipContent: 'Disabled tab',
|
||||
},
|
||||
]
|
||||
|
||||
it('renders tabs correctly', () => {
|
||||
render(
|
||||
<Tabs options={mockOptions} value="tab1" onValueChange={() => {}}>
|
||||
<TabsContent value="tab1">Content 1</TabsContent>
|
||||
<TabsContent value="tab2">Content 2</TabsContent>
|
||||
<TabsContent value="tab3">Content 3</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
|
||||
expect(screen.getByText('Tab 1')).toBeInTheDocument()
|
||||
expect(screen.getByText('Tab 2')).toBeInTheDocument()
|
||||
expect(screen.getByText('Tab 3')).toBeInTheDocument()
|
||||
expect(screen.getByText('Content 1')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('changes tab content when clicked', () => {
|
||||
const { rerender } = render(
|
||||
<Tabs options={mockOptions} value="tab1" onValueChange={() => {}}>
|
||||
<TabsContent value="tab1">Content 1</TabsContent>
|
||||
<TabsContent value="tab2">Content 2</TabsContent>
|
||||
<TabsContent value="tab3">Content 3</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
|
||||
expect(screen.getByText('Content 1')).toBeInTheDocument()
|
||||
expect(screen.queryByText('Content 2')).not.toBeInTheDocument()
|
||||
|
||||
fireEvent.click(screen.getByText('Tab 2'))
|
||||
|
||||
// Rerender with the new value to simulate the state change
|
||||
rerender(
|
||||
<Tabs options={mockOptions} value="tab2" onValueChange={() => {}}>
|
||||
<TabsContent value="tab1">Content 1</TabsContent>
|
||||
<TabsContent value="tab2">Content 2</TabsContent>
|
||||
<TabsContent value="tab3">Content 3</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
|
||||
expect(screen.queryByText('Content 1')).not.toBeInTheDocument()
|
||||
expect(screen.getByText('Content 2')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('disables tab when specified', () => {
|
||||
render(
|
||||
<Tabs options={mockOptions} value="tab1" onValueChange={() => {}}>
|
||||
<TabsContent value="tab1">Content 1</TabsContent>
|
||||
<TabsContent value="tab2">Content 2</TabsContent>
|
||||
<TabsContent value="tab3">Content 3</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
|
||||
expect(screen.getByText('Tab 3')).toHaveAttribute('disabled')
|
||||
})
|
||||
|
||||
it('renders tooltip for disabled tab', () => {
|
||||
render(
|
||||
<Tabs options={mockOptions} value="tab1" onValueChange={() => {}}>
|
||||
<TabsContent value="tab1">Content 1</TabsContent>
|
||||
<TabsContent value="tab2">Content 2</TabsContent>
|
||||
<TabsContent value="tab3">Content 3</TabsContent>
|
||||
</Tabs>
|
||||
)
|
||||
|
||||
const tooltipWrapper = screen.getByTestId('mock-tooltip')
|
||||
expect(tooltipWrapper).toHaveAttribute(
|
||||
'data-tooltip-content',
|
||||
'Disabled tab'
|
||||
)
|
||||
})
|
||||
})
|
||||
34
joi/src/core/TextArea/TextArea.test.tsx
Normal file
34
joi/src/core/TextArea/TextArea.test.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React from 'react'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { TextArea } from './index'
|
||||
|
||||
// Mock the styles import
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
describe('@joi/core/TextArea', () => {
|
||||
it('renders correctly', () => {
|
||||
render(<TextArea placeholder="Enter text here" />)
|
||||
const textareaElement = screen.getByPlaceholderText('Enter text here')
|
||||
expect(textareaElement).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('applies custom className', () => {
|
||||
render(<TextArea className="custom-class" />)
|
||||
const textareaElement = screen.getByRole('textbox')
|
||||
expect(textareaElement).toHaveClass('textarea')
|
||||
expect(textareaElement).toHaveClass('custom-class')
|
||||
})
|
||||
|
||||
it('forwards ref correctly', () => {
|
||||
const ref = React.createRef<HTMLTextAreaElement>()
|
||||
render(<TextArea ref={ref} />)
|
||||
expect(ref.current).toBeInstanceOf(HTMLTextAreaElement)
|
||||
})
|
||||
|
||||
it('passes through additional props', () => {
|
||||
render(<TextArea data-testid="custom-textarea" rows={5} />)
|
||||
const textareaElement = screen.getByTestId('custom-textarea')
|
||||
expect(textareaElement).toHaveAttribute('rows', '5')
|
||||
})
|
||||
})
|
||||
121
joi/src/core/Tooltip/Tooltip.test.tsx
Normal file
121
joi/src/core/Tooltip/Tooltip.test.tsx
Normal file
@ -0,0 +1,121 @@
|
||||
import React from 'react'
|
||||
import '@testing-library/jest-dom'
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { Tooltip } from './index'
|
||||
|
||||
declare const global: typeof globalThis
|
||||
|
||||
// Mock the styles
|
||||
jest.mock('./styles.scss', () => ({}))
|
||||
|
||||
class ResizeObserverMock {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
}
|
||||
|
||||
global.ResizeObserver = ResizeObserverMock
|
||||
|
||||
describe('@joi/core/Tooltip', () => {
|
||||
it('renders trigger content', () => {
|
||||
render(
|
||||
<Tooltip trigger={<button>Hover me</button>} content="Tooltip content" />
|
||||
)
|
||||
expect(screen.getByText('Hover me')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows tooltip content on hover', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<Tooltip
|
||||
trigger={<button data-testid="tooltip-trigger">Hover me</button>}
|
||||
content={<span data-testid="tooltip-content">Tooltip content</span>}
|
||||
/>
|
||||
)
|
||||
|
||||
const trigger = screen.getByTestId('tooltip-trigger')
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
const tooltipContents = screen.queryAllByTestId('tooltip-content')
|
||||
expect(tooltipContents.length).toBeGreaterThan(0)
|
||||
expect(tooltipContents[tooltipContents.length - 1]).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
it('does not show tooltip when disabled', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<Tooltip
|
||||
trigger={<button data-testid="tooltip-trigger">Hover me</button>}
|
||||
content={<span data-testid="tooltip-content">Tooltip content</span>}
|
||||
disabled
|
||||
/>
|
||||
)
|
||||
|
||||
const trigger = screen.getByTestId('tooltip-trigger')
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
const tooltipContents = screen.queryAllByTestId('tooltip-content')
|
||||
tooltipContents.forEach((content) => {
|
||||
expect(content).not.toBeVisible()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('renders arrow when withArrow is true', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<Tooltip
|
||||
trigger={<button data-testid="tooltip-trigger">Hover me</button>}
|
||||
content={<span data-testid="tooltip-content">Tooltip content</span>}
|
||||
withArrow
|
||||
/>
|
||||
)
|
||||
|
||||
const trigger = screen.getByTestId('tooltip-trigger')
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
const tooltipContents = screen.queryAllByTestId('tooltip-content')
|
||||
const visibleTooltip = tooltipContents.find((content) =>
|
||||
content.matches(':not([style*="display: none"])')
|
||||
)
|
||||
expect(visibleTooltip?.closest('.tooltip__content')).toBeInTheDocument()
|
||||
expect(
|
||||
visibleTooltip
|
||||
?.closest('.tooltip__content')
|
||||
?.querySelector('.tooltip__arrow')
|
||||
).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('does not render arrow when withArrow is false', async () => {
|
||||
const user = userEvent.setup()
|
||||
render(
|
||||
<Tooltip
|
||||
trigger={<button data-testid="tooltip-trigger">Hover me</button>}
|
||||
content={<span data-testid="tooltip-content">Tooltip content</span>}
|
||||
withArrow={false}
|
||||
/>
|
||||
)
|
||||
|
||||
const trigger = screen.getByTestId('tooltip-trigger')
|
||||
await user.hover(trigger)
|
||||
|
||||
await waitFor(() => {
|
||||
const tooltipContents = screen.queryAllByTestId('tooltip-content')
|
||||
const visibleTooltip = tooltipContents.find((content) =>
|
||||
content.matches(':not([style*="display: none"])')
|
||||
)
|
||||
expect(visibleTooltip?.closest('.tooltip__content')).toBeInTheDocument()
|
||||
expect(
|
||||
visibleTooltip
|
||||
?.closest('.tooltip__content')
|
||||
?.querySelector('.tooltip__arrow')
|
||||
).not.toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
x
Reference in New Issue
Block a user