Skip to content

Commit

Permalink
Added unit tests and added AppSwitch to storybook
Browse files Browse the repository at this point in the history
  • Loading branch information
amoutens committed Nov 21, 2024
1 parent 66bbdb1 commit ce78107
Show file tree
Hide file tree
Showing 4 changed files with 220 additions and 13 deletions.
10 changes: 9 additions & 1 deletion src/components/app-switch/AppSwitch.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,16 @@ const getMixins = (
)
}
}
export const styles: Record<string, object> = {
export const switchStyles: Record<string, object> = {
[SizeEnum.Small.toString()]: getMixins(45, 21, 15, 1),
[SizeEnum.Medium.toString()]: getMixins(60, 28, 20, 2),
[SizeEnum.Large.toString()]: getMixins(75, 35, 25, 3)
}
export const formLabelStyles = {
formLabelBox: {
display: 'flex',
alignItems: 'center',
gap: '10px',
overflow: 'visible'
}
}
19 changes: 7 additions & 12 deletions src/components/app-switch/AppSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,30 @@
import { SizeEnum } from '~/types'
import Switch, { SwitchProps } from '@mui/material/Switch'
import { styles } from './AppSwitch.styles'
import { switchStyles, formLabelStyles } from './AppSwitch.styles'
import { FormControlLabel } from '@mui/material'
interface AppSwitchProps extends Omit<SwitchProps, 'size'> {
labelPosition?: 'start' | 'end' | 'top' | 'bottom'
size?: SizeEnum
label: string
label?: string
loading?: boolean
}
export const AppSwitch = ({
labelPosition,
size = SizeEnum.Medium,
labelPosition = 'end',
size = SizeEnum.Small,
label,
loading,
disabled,
...props
}: AppSwitchProps) => {
const sizeStyle = styles[size]
const sizeStyle = switchStyles[size]
return (
<FormControlLabel
control={
<Switch disabled={loading || disabled} sx={sizeStyle} {...props} />
}
label={label}
label={label ? label : ''}
labelPlacement={labelPosition}
sx={{
display: 'flex',
alignItems: 'center',
gap: '10px',
overflow: 'visible'
}}
sx={formLabelStyles.formLabelBox}
/>
)
}
110 changes: 110 additions & 0 deletions src/stories/AppSwitch.stories.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { AppSwitch } from '~/components/app-switch/AppSwitch'
import { SizeEnum } from '~/types'

export default {
title: 'Components/AppSwitch',
component: AppSwitch,
argTypes: {
label: {
control: 'text',
description: 'Label for the switch',
defaultValue: ''
},
labelPosition: {
control: { type: 'radio' },
options: ['start', 'end', 'top', 'bottom'],
description: 'Position of the label relative to the switch',
defaultValue: 'end'
},
size: {
control: { type: 'radio' },
options: [SizeEnum.Small, SizeEnum.Medium, SizeEnum.Large],
description: 'Size of the switch',
defaultValue: SizeEnum.Medium
},
loading: {
control: 'boolean',
description: 'Disables the switch and displays loading state',
defaultValue: false
},
disabled: {
control: 'boolean',
description: 'Disables the switch',
defaultValue: false
}
}
}

const Template = (args) => <AppSwitch {...args} />

export const Default = Template.bind({})
Default.args = {
size: SizeEnum.Medium,
disabled: false,
loading: false
}

export const DefaultWithLabel = Template.bind({})
DefaultWithLabel.args = {
label: 'Default Switch with Label',
size: SizeEnum.Medium,
labelPosition: 'end',
disabled: false,
loading: false
}

export const Disabled = Template.bind({})
Disabled.args = {
label: 'Disabled Switch',
size: SizeEnum.Medium,
labelPosition: 'end',
disabled: true
}

export const Loading = Template.bind({})
Loading.args = {
label: 'Loading Switch',
size: SizeEnum.Medium,
labelPosition: 'end',
loading: true
}

export const LargeSize = Template.bind({})
LargeSize.args = {
label: 'Large Switch',
size: SizeEnum.Large,
labelPosition: 'end',
disabled: false
}

export const SmallSize = Template.bind({})
SmallSize.args = {
label: 'Small Switch',
size: SizeEnum.Small,
labelPosition: 'end',
disabled: false
}

export const TopPosition = Template.bind({})
TopPosition.args = {
label: 'Top Position',
size: SizeEnum.Medium,
labelPosition: 'top',
disabled: false
}

export const StartPosition = Template.bind({})
StartPosition.args = {
label: 'Start Position',
size: SizeEnum.Medium,
labelPosition: 'start',
disabled: false
}

export const BottomPosition = Template.bind({})
BottomPosition.args = {
label: 'Bottom Position',
size: SizeEnum.Medium,
labelPosition: 'bottom',
disabled: false
}
94 changes: 94 additions & 0 deletions tests/unit/components/app-switch/AppSwitch.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { render, screen } from '@testing-library/react'
import { fireEvent } from '@testing-library/react'
import {AppSwitch} from '~/components/app-switch/AppSwitch'
import {SizeEnum} from '~/types'

describe('AppSwitch Component', () => {
it('renders correctly with default props', () => {
render(<AppSwitch />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})

it('triggers `onChange` when toggled', () => {
const handleChange = vi.fn()
render(<AppSwitch onChange={handleChange} />)

const switchEl = screen.getByRole('checkbox')
fireEvent.click(switchEl)

expect(handleChange).toHaveBeenCalledTimes(1)
})

it('displays the label when provided', () => {
render(<AppSwitch label="Test Label" />)

const labelEl = screen.getByText('Test Label')
expect(labelEl).toBeInTheDocument()
})

it('applies the correct Large size style', () => {
render(<AppSwitch size={SizeEnum.Large} />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})

it('applies the correct Medium size style', () => {
render(<AppSwitch size={SizeEnum.Medium} />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})

it('applies the correct Small size style', () => {
render(<AppSwitch size={SizeEnum.Small} />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeInTheDocument()
})

it('is disabled when loading is true', () => {
render(<AppSwitch loading />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeDisabled()
})

it('is disabled when disabled prop is true', () => {
render(<AppSwitch disabled />)

const switchEl = screen.getByRole('checkbox')
expect(switchEl).toBeDisabled()
})

it('renders the label in the correct end position', () => {
render(<AppSwitch label="End Label" labelPosition="end" />)

const labelEl = screen.getByText('End Label')
expect(labelEl).toBeInTheDocument()
})

it('renders the label in the correct start position', () => {
render(<AppSwitch label="Start Label" labelPosition="start" />)

const labelEl = screen.getByText('Start Label')
expect(labelEl).toBeInTheDocument()
})

it('renders the label in the correct top position', () => {
render(<AppSwitch label="Top Label" labelPosition="top" />)

const labelEl = screen.getByText('Top Label')
expect(labelEl).toBeInTheDocument()
})

it('renders the label in the correct bottom position', () => {
render(<AppSwitch label="Bottom Label" labelPosition="bottom" />)

const labelEl = screen.getByText('Bottom Label')
expect(labelEl).toBeInTheDocument()
})

})

0 comments on commit ce78107

Please sign in to comment.