1- import { fireEvent , render , screen } from '@testing-library/react' ;
2- import type { ComponentProps } from 'react' ;
3- import { describe , expect , it , vi } from 'vitest' ;
1+ import '@testing-library/jest-dom' ;
2+ import type { Scale , BadgeSize , Font , ViewMode , DeltaFormat , Language , Timezone } from '../types' ;
3+ import { describe , it , expect , vi , beforeEach } from 'vitest' ;
4+ import { render , screen , fireEvent } from '@testing-library/react' ;
45import { ControlsPanel } from './ControlsPanel' ;
5- import type { BadgeSize , DeltaFormat , Font , Language , Scale , Timezone , ViewMode } from '../types' ;
66
77const defaultProps = {
8- username : 'octocat ' ,
9- theme : 'dark' ,
8+ username : '' ,
9+ theme : 'github- dark' ,
1010 bgHex : '' ,
1111 accentHex : '' ,
1212 textHex : '' ,
1313 scale : 'linear' as Scale ,
1414 speed : '8s' ,
1515 font : '' as Font ,
16- year : '' ,
16+ year : '2025 ' ,
1717 radius : 8 ,
1818 size : 'medium' as BadgeSize ,
19+
1920 onUsernameChange : vi . fn ( ) ,
2021 onThemeChange : vi . fn ( ) ,
2122 onBgHexChange : vi . fn ( ) ,
@@ -28,43 +29,94 @@ const defaultProps = {
2829 onSizeChange : vi . fn ( ) ,
2930 onClearOverrides : vi . fn ( ) ,
3031 onRadiusChange : vi . fn ( ) ,
32+
3133 hideTitle : false ,
3234 hideBackground : false ,
3335 hideStats : false ,
36+
3437 viewMode : 'default' as ViewMode ,
3538 deltaFormat : 'percent' as DeltaFormat ,
36- badgeWidth : '' as const ,
37- badgeHeight : '' as const ,
39+
40+ badgeWidth : 0 ,
41+ badgeHeight : 0 ,
42+
3843 grace : 1 ,
44+
3945 language : 'en' as Language ,
4046 timezone : 'UTC' as Timezone ,
47+
4148 onHideTitleChange : vi . fn ( ) ,
4249 onHideBackgroundChange : vi . fn ( ) ,
4350 onHideStatsChange : vi . fn ( ) ,
51+
4452 onViewModeChange : vi . fn ( ) ,
4553 onDeltaFormatChange : vi . fn ( ) ,
54+
4655 onBadgeWidthChange : vi . fn ( ) ,
4756 onBadgeHeightChange : vi . fn ( ) ,
57+
4858 onGraceChange : vi . fn ( ) ,
59+
4960 onLanguageChange : vi . fn ( ) ,
5061 onTimezoneChange : vi . fn ( ) ,
51- } satisfies ComponentProps < typeof ControlsPanel > ;
62+ } ;
63+ describe ( 'ControlsPanel Component' , ( ) => {
64+ beforeEach ( ( ) => {
65+ vi . clearAllMocks ( ) ;
66+ } ) ;
5267
53- describe ( 'ControlsPanel timezone control' , ( ) => {
54- it ( 'renders UTC as the default timezone option' , ( ) => {
68+ it ( 'renders the GitHub Username label' , ( ) => {
5569 render ( < ControlsPanel { ...defaultProps } /> ) ;
5670
57- expect ( ( screen . getByLabelText ( 'Timezone' ) as HTMLSelectElement ) . value ) . toBe ( 'UTC' ) ;
71+ expect ( screen . getByText ( / G i t H u b U s e r n a m e / i ) ) . toBeTruthy ( ) ;
5872 } ) ;
5973
60- it ( 'calls onTimezoneChange with the selected IANA timezone' , ( ) => {
61- const onTimezoneChange = vi . fn ( ) ;
62- render ( < ControlsPanel { ...defaultProps } onTimezoneChange = { onTimezoneChange } /> ) ;
74+ it ( 'renders username input with correct id' , ( ) => {
75+ render ( < ControlsPanel { ...defaultProps } /> ) ;
76+ const input = document . getElementById ( 'username-input' ) ;
77+
78+ expect ( input ) . toHaveAttribute ( 'id' , 'username-input' ) ;
79+ } ) ;
80+
81+ it ( 'calls onUsernameChange when typing' , ( ) => {
82+ render ( < ControlsPanel { ...defaultProps } /> ) ;
83+
84+ const input = document . getElementById ( 'username-input' ) ;
6385
64- fireEvent . change ( screen . getByLabelText ( 'Timezone' ) , {
65- target : { value : 'Asia/Kolkata ' } ,
86+ fireEvent . change ( input ! , {
87+ target : { value : 'shikhar ' } ,
6688 } ) ;
6789
68- expect ( onTimezoneChange ) . toHaveBeenCalledWith ( 'Asia/Kolkata' ) ;
90+ expect ( defaultProps . onUsernameChange ) . toHaveBeenCalled ( ) ;
91+ } ) ;
92+
93+ it ( 'renders Linear and Logarithmic buttons' , ( ) => {
94+ render ( < ControlsPanel { ...defaultProps } /> ) ;
95+
96+ expect ( screen . getByRole ( 'button' , { name : / L i n e a r / i } ) ) . toBeTruthy ( ) ;
97+
98+ expect ( screen . getByRole ( 'button' , { name : / L o g a r i t h m i c / i } ) ) . toBeTruthy ( ) ;
99+ } ) ;
100+
101+ it ( 'calls onScaleChange with log' , ( ) => {
102+ render ( < ControlsPanel { ...defaultProps } /> ) ;
103+
104+ const logButton = screen . getByText ( / L o g a r i t h m i c / i) ;
105+
106+ fireEvent . click ( logButton ) ;
107+
108+ expect ( defaultProps . onScaleChange ) . toHaveBeenCalledWith ( 'log' ) ;
109+ } ) ;
110+
111+ it ( 'hides Clear overrides button initially' , ( ) => {
112+ render ( < ControlsPanel { ...defaultProps } /> ) ;
113+
114+ expect ( screen . queryByText ( / C l e a r o v e r r i d e s / i) ) . toBeNull ( ) ;
115+ } ) ;
116+
117+ it ( 'shows Clear overrides button when bgHex is provided' , ( ) => {
118+ render ( < ControlsPanel { ...defaultProps } bgHex = "#000000" /> ) ;
119+
120+ expect ( screen . getByText ( / C l e a r o v e r r i d e s / i) ) . toBeTruthy ( ) ;
69121 } ) ;
70122} ) ;
0 commit comments