Skip to content

Commit

Permalink
feat: added UTs for becknified components
Browse files Browse the repository at this point in the history
- UTs for page level components.
- UTs for component used in pages.
- setup for getting the code coverage report
  • Loading branch information
aniketceminds committed Jun 20, 2024
1 parent ee2da6b commit b2b96f7
Show file tree
Hide file tree
Showing 65 changed files with 2,883 additions and 312 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ node_modules
.next
out
.env
coverage

# Swap the comments on the following lines if you don't wish to use zero-installs
# Documentation here: https://yarnpkg.com/features/zero-installs
Expand Down
8 changes: 7 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,11 @@ module.exports = {
moduleNameMapper: {
'\\.(css|less|sass|scss)$': '<rootDir>/tests/mocks/mocks.css',
'\\.(svg)$': '<rootDir>/tests/mocks/svgTransform.js'
}
},
collectCoverage: true,
collectCoverageFrom: [
'<rootDir>/packages/**/src/components/**/*.{js,jsx,ts,tsx}',
'<rootDir>/packages/**/src/pages/**/*.{js,jsx,ts,tsx}'
],
coverageReporters: ['clover', 'json', 'lcov', 'text']
}
4 changes: 4 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
import '@testing-library/jest-dom'

if (typeof global.structuredClone === 'undefined') {
global.structuredClone = (obj: any) => JSON.parse(JSON.stringify(obj))
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"@beckn-ui/prettier-config": "workspace:^",
"@commitlint/cli": "^17.7.1",
"@commitlint/config-conventional": "^17.7.0",
"@faker-js/faker": "^8.4.1",
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^14.0.0",
"@types/jest": "^29.5.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react'
import { render, fireEvent, screen } from '@testing-library/react'
import { SearchInputOnSearchResultsPageProps } from '../../src/components/searchInputOnSearchResultsPage/SearchInputOnSearchResultsPage.types'
import SearchInputOnSearchResultsPage from '../../src/components/searchInputOnSearchResultsPage'

describe('SearchInputOnSearchResultsPage Component', () => {
const baseProps: SearchInputOnSearchResultsPageProps = {
handleSubmit: jest.fn(),
searchText: '',
setSearchText: jest.fn()
}

it('renders correctly with default props', () => {
render(<SearchInputOnSearchResultsPage {...baseProps} />)

const input = screen.getByPlaceholderText('Search') as HTMLInputElement
expect(input).toBeInTheDocument()
expect(input.value).toBe('')
})

it('calls setSearchText when input value changes', () => {
render(<SearchInputOnSearchResultsPage {...baseProps} />)

const input = screen.getByPlaceholderText('Search') as HTMLInputElement
fireEvent.change(input, { target: { value: 'test' } })

expect(baseProps.setSearchText).toHaveBeenCalledTimes(1)
expect(baseProps.setSearchText).toHaveBeenCalledWith('test')
})

it('calls handleSubmit when Enter key is pressed', () => {
render(<SearchInputOnSearchResultsPage {...baseProps} />)

const input = screen.getByPlaceholderText('Search') as HTMLInputElement
fireEvent.keyDown(input, { key: 'Enter', keyCode: 13 })

expect(baseProps.handleSubmit).toHaveBeenCalledTimes(1)
})
})
40 changes: 40 additions & 0 deletions packages/becknified-components/__tests__/components/Sort.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import { render, fireEvent, screen } from '@testing-library/react'
import { SortComponentProps } from '../../src/components/sort/Sort.types'
import Sort from '../../src/components/sort'
import { ChakraProvider } from '@chakra-ui/react'

const theme = {
colors: { primary: { '100': '#3182ce' }, secondary: { '100': '#3182ee' } }
}

const renderWithChakra = (ui: React.ReactElement) => {
return render(<ChakraProvider theme={theme}>{ui}</ChakraProvider>)
}
describe('Sort Component', () => {
const baseProps: SortComponentProps = {
selectedBtn: 'all',
onChangeSelectedBtn: jest.fn()
}

it('renders correctly with default props', () => {
renderWithChakra(<Sort {...baseProps} />)

const sortIcon = screen.getByTestId('test-filter-icon')
expect(sortIcon).toBeInTheDocument()

const allRadioBtn = screen.getByLabelText('all') as HTMLInputElement
expect(allRadioBtn).toBeInTheDocument()
expect(allRadioBtn.checked).toBe(true)
})

it('calls onChangeSelectedBtn when radio button is clicked', () => {
renderWithChakra(<Sort {...baseProps} />)

const cheapestRadioBtn = screen.getByLabelText('cheapest')
fireEvent.click(cheapestRadioBtn)

expect(baseProps.onChangeSelectedBtn).toHaveBeenCalledTimes(1)
expect(baseProps.onChangeSelectedBtn).toHaveBeenCalledWith(expect.any(Object))
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React from 'react'
import { render, screen } from '@testing-library/react'
import AccordionDetailCard from '../../src/components/accordion-detail-card'
import { AccordionDetailCardProps } from '../../src/components/accordion-detail-card/accordion-detail-card.types'

jest.mock('@beckn-ui/molecules', () => ({
Accordion: jest.fn(({ children }) => <div data-testid="accordion">{children}</div>),
Typography: jest.fn(({ text, className }) => <p className={className}>{text}</p>)
}))

jest.mock('@chakra-ui/react', () => ({
CardBody: jest.fn(({ children }) => <div data-testid="card-body">{children}</div>),
Flex: jest.fn(({ children }) => <div>{children}</div>)
}))

const renderAccordionComponent = (props: AccordionDetailCardProps) => {
return render(<AccordionDetailCard {...props}></AccordionDetailCard>)
}

describe('AccordionDetailCard Component', () => {
const defaultProps: AccordionDetailCardProps = {
schema: {
accordion: { accordionHeader: 'Test Accordion' },
dataSource: {
source: {
key1: 'value1',
key2: 'value2'
},
className: 'test-class'
}
}
}

it('should render the Accordion component', () => {
renderAccordionComponent({ ...defaultProps })
expect(screen.getByTestId('accordion')).toBeInTheDocument()
})

it('should render CardBody component inside Accordion', () => {
renderAccordionComponent({ ...defaultProps })
expect(screen.getByTestId('card-body')).toBeInTheDocument()
})

it('should render children if provided', () => {
const children = <div data-testid="child">Child Content</div>
renderAccordionComponent({ ...defaultProps, children })
expect(screen.getByTestId('child')).toBeInTheDocument()
})

it('should render data source if children are not provided', () => {
renderAccordionComponent({ ...defaultProps })
expect(screen.getByText('key1')).toBeInTheDocument()
expect(screen.getByText('value1')).toBeInTheDocument()
expect(screen.getByText('key2')).toBeInTheDocument()
expect(screen.getByText('value2')).toBeInTheDocument()
})

it('should apply className from dataSource to Typography components', () => {
renderAccordionComponent({ ...defaultProps })
expect(screen.getByText('key1')).toHaveClass('test-class_key')
expect(screen.getByText('value1')).toHaveClass('test-class_value')
})

it('should render empty content if neither children nor dataSource are provided', () => {
const propsWithoutChildrenOrDataSource: AccordionDetailCardProps = {
schema: {
accordion: { accordionHeader: 'Test Accordion' },
dataSource: { source: {} }
}
}
renderAccordionComponent({ ...propsWithoutChildrenOrDataSource })
expect(screen.getByTestId('card-body')).toBeEmptyDOMElement()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react'
import { render, screen, fireEvent } from '@testing-library/react'
import { CartItemProps } from '../../../src/components/cart/cart.types'
import CartItem from '../../../src/components/cart/cart-item'
import { ChakraProvider } from '@chakra-ui/react'

jest.mock('../../../src/components/product-price', () => ({
__esModule: true,
default: ({ price, currencyType }: { price: number; currencyType: string }) => (
<div>
{currencyType}
{price}
</div>
)
}))

const theme = {
colors: { primary: { '100': '#3182ce' } }
}

const renderCartItemComponent = (props: CartItemProps) => {
return render(
<ChakraProvider theme={theme}>
<CartItem {...props} />
</ChakraProvider>
)
}

describe('CartItem', () => {
const defaultProps: CartItemProps = {
id: '1',
quantity: 2,
name: 'Test Product',
image: 'test-image.jpg',
price: 100,
symbol: 'INR',
handleDecrement: jest.fn(),
handleIncrement: jest.fn(),
className: 'test-class',
totalAmountText: 'Total Amount:'
}

it('should render the CartItem component with initial props', () => {
renderCartItemComponent({ ...defaultProps })

expect(screen.getByText('Test Product')).toBeInTheDocument()
expect(screen.getByRole('img', { name: /test product/i })).toHaveAttribute('src', 'test-image.jpg')
expect(screen.getByDisplayValue('2')).toBeInTheDocument()
expect(screen.getByText('Total Amount:')).toBeInTheDocument()
expect(screen.getByText('INR200')).toBeInTheDocument()
})

it('should increment the counter', () => {
renderCartItemComponent({ ...defaultProps })

const incrementButton = screen.getByTestId('test-increment')
fireEvent.click(incrementButton!)

expect(defaultProps.handleIncrement).toHaveBeenCalledWith('1')
expect(screen.getByDisplayValue('3')).toBeInTheDocument()
})

it('should decrement the counter', () => {
renderCartItemComponent({ ...defaultProps })

const decrementButton = screen.getByTestId('test-decrement')
fireEvent.click(decrementButton)

expect(defaultProps.handleDecrement).toHaveBeenCalledWith('1')
expect(screen.getByDisplayValue('1')).toBeInTheDocument()
})

it('should change the input value', () => {
const renderer = renderCartItemComponent({ ...defaultProps })

const input = renderer.baseElement.querySelector('input[type="number"]')
fireEvent.change(input!, { target: { value: '5' } })

expect(input).toHaveValue(5)
})

it('should change icon to trash when counter is 1', () => {
renderCartItemComponent({ ...defaultProps, quantity: 1 })

const trashButton = screen.getByTestId('test-delete')
fireEvent.click(trashButton)
expect(defaultProps.handleDecrement).toHaveBeenCalledWith('1')
expect(screen.getByDisplayValue('0')).toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react'
import { render } from '@testing-library/react'
import CartList from '../../../src/components/cart/cart-list'
import { CartItemProps, CartListProps } from '../../../src/components/cart/cart.types'
import { ChakraProvider } from '@chakra-ui/react'

const theme = {
colors: { primary: { '100': '#3182ce' }, secondary: { '100': '#3182ee' } }
}

// Mock data
const mockCartItems: CartItemProps[] = [
{
id: '1',
name: 'Item 1',
price: 10,
quantity: 2,
handleDecrement: () => {},
handleIncrement: () => {},
image: '',
symbol: 'INR'
},
{
id: '2',
name: 'Item 2',
price: 15,
quantity: 1,
handleDecrement: () => {},
handleIncrement: () => {},
image: '',
symbol: 'INR'
}
]

const renderCartListComponent = (props: CartListProps) => {
return render(
<ChakraProvider theme={theme}>
<CartList {...props} />
</ChakraProvider>
)
}

describe('CartList Component', () => {
it('renders with empty cartItems', () => {
const { container } = renderCartListComponent({ cartItems: [] })

expect(container.firstChild).toHaveTextContent('')
})

it('renders cartItems correctly', () => {
const renderer = renderCartListComponent({ cartItems: mockCartItems })

const cartItemElements = renderer.baseElement.querySelectorAll('.cart-item')
expect(cartItemElements.length).toBe(mockCartItems.length)
})
})
Loading

0 comments on commit b2b96f7

Please sign in to comment.