Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: finished all ui components test #3588

Merged
merged 2 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions joi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
36 changes: 29 additions & 7 deletions joi/src/core/Button/Button.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ 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 })
expect(button).toBeInTheDocument()
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>
Expand Down Expand Up @@ -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 changes: 50 additions & 0 deletions joi/src/core/Checkbox/Checkbox.test.tsx
Original file line number Diff line number Diff line change
@@ -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 changes: 53 additions & 0 deletions joi/src/core/Input/Input.test.tsx
Original file line number Diff line number Diff line change
@@ -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)
})
})
2 changes: 1 addition & 1 deletion joi/src/core/Input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
78 changes: 78 additions & 0 deletions joi/src/core/Modal/Modal.test.tsx
Original file line number Diff line number Diff line change
@@ -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 onOpenChange = jest.fn()
render(
<Modal
trigger={<button>Open Modal</button>}
content={<div>Modal Content</div>}
onOpenChange={onOpenChange}
/>
)

fireEvent.click(screen.getByText('Open Modal'))
expect(onOpenChange).toHaveBeenCalledWith(true)

fireEvent.click(screen.getByLabelText('Close'))
expect(onOpenChange).toHaveBeenCalledWith(false)
})
})
55 changes: 55 additions & 0 deletions joi/src/core/Progress/Progress.test.tsx
Original file line number Diff line number Diff line change
@@ -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')
})
})
9 changes: 8 additions & 1 deletion joi/src/core/Progress/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
47 changes: 47 additions & 0 deletions joi/src/core/ScrollArea/ScrollArea.test.tsx
Original file line number Diff line number Diff line change
@@ -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')
})
})
Loading
Loading