|
1 |
| -import { render, screen } from '@testing-library/react' |
| 1 | +import { render, screen, fireEvent } from '@testing-library/react' |
2 | 2 | import React from 'react'
|
3 | 3 | import '@testing-library/jest-dom'
|
4 | 4 | import MetricsScoreCircle from 'components/MetricsScoreCircle'
|
@@ -172,14 +172,22 @@ describe('MetricsScoreCircle', () => {
|
172 | 172 | })
|
173 | 173 |
|
174 | 174 | // Test 9: Event handling - hover effects (visual testing through classes)
|
175 |
| - it('has hover effect classes applied', () => { |
176 |
| - const { container } = render(<MetricsScoreCircle score={75} />) |
| 175 | + it('has hover effect classes applied when clickable', () => { |
| 176 | + const { container } = render(<MetricsScoreCircle score={75} clickable={true} />) |
177 | 177 |
|
178 | 178 | // Check for hover-related classes
|
179 | 179 | const hoverElement = container.querySelector('[class*="hover:"]')
|
180 | 180 | expect(hoverElement).toBeInTheDocument()
|
181 | 181 | })
|
182 | 182 |
|
| 183 | + it('does not have hover effect classes when not clickable', () => { |
| 184 | + const { container } = render(<MetricsScoreCircle score={75} clickable={false} />) |
| 185 | + |
| 186 | + // Should not have hover-related classes |
| 187 | + const hoverElement = container.querySelector('[class*="hover:"]') |
| 188 | + expect(hoverElement).not.toBeInTheDocument() |
| 189 | + }) |
| 190 | + |
183 | 191 | // Test 10: Component integration test
|
184 | 192 | it('integrates all features correctly for a low score', () => {
|
185 | 193 | const { container } = render(<MetricsScoreCircle score={15} />)
|
@@ -218,4 +226,160 @@ describe('MetricsScoreCircle', () => {
|
218 | 226 | 'Current Project Health Score'
|
219 | 227 | )
|
220 | 228 | })
|
| 229 | + |
| 230 | + // Test 11: Click handling functionality |
| 231 | + describe('click handling', () => { |
| 232 | + it('calls onClick when clickable and onClick provided', () => { |
| 233 | + const mockOnClick = jest.fn() |
| 234 | + render(<MetricsScoreCircle score={75} clickable={true} onClick={mockOnClick} />) |
| 235 | + |
| 236 | + const circleElement = screen.getByText('75').closest('.group') |
| 237 | + if (circleElement) { |
| 238 | + fireEvent.click(circleElement) |
| 239 | + } |
| 240 | + |
| 241 | + expect(mockOnClick).toHaveBeenCalledTimes(1) |
| 242 | + }) |
| 243 | + |
| 244 | + it('does not call onClick when not clickable', () => { |
| 245 | + const mockOnClick = jest.fn() |
| 246 | + render(<MetricsScoreCircle score={75} clickable={false} onClick={mockOnClick} />) |
| 247 | + |
| 248 | + const circleElement = screen.getByText('75').closest('.group') |
| 249 | + if (circleElement) { |
| 250 | + fireEvent.click(circleElement) |
| 251 | + } |
| 252 | + |
| 253 | + expect(mockOnClick).not.toHaveBeenCalled() |
| 254 | + }) |
| 255 | + |
| 256 | + it('does not call onClick when no onClick provided', () => { |
| 257 | + render(<MetricsScoreCircle score={75} clickable={true} />) |
| 258 | + |
| 259 | + const circleElement = screen.getByText('75').closest('.group') |
| 260 | + if (circleElement) { |
| 261 | + fireEvent.click(circleElement) |
| 262 | + } |
| 263 | + // Should not throw any errors - test passes if no exception is thrown |
| 264 | + expect(circleElement).toBeInTheDocument() |
| 265 | + }) |
| 266 | + |
| 267 | + it('has cursor pointer when clickable', () => { |
| 268 | + const { container } = render(<MetricsScoreCircle score={75} clickable={true} />) |
| 269 | + |
| 270 | + const clickableElement = container.querySelector('[class*="cursor-pointer"]') |
| 271 | + expect(clickableElement).toBeInTheDocument() |
| 272 | + }) |
| 273 | + |
| 274 | + it('does not have cursor pointer when not clickable', () => { |
| 275 | + const { container } = render(<MetricsScoreCircle score={75} clickable={false} />) |
| 276 | + |
| 277 | + const clickableElement = container.querySelector('[class*="cursor-pointer"]') |
| 278 | + expect(clickableElement).not.toBeInTheDocument() |
| 279 | + }) |
| 280 | + }) |
| 281 | + |
| 282 | + // Test 12: Accessibility for clickable component |
| 283 | + describe('accessibility for clickable component', () => { |
| 284 | + it('has button role when clickable', () => { |
| 285 | + render(<MetricsScoreCircle score={75} clickable={true} />) |
| 286 | + |
| 287 | + const buttonElement = screen.getByRole('button') |
| 288 | + expect(buttonElement).toBeInTheDocument() |
| 289 | + }) |
| 290 | + |
| 291 | + it('does not have button role when not clickable', () => { |
| 292 | + render(<MetricsScoreCircle score={75} clickable={false} />) |
| 293 | + |
| 294 | + const buttonElement = screen.queryByRole('button') |
| 295 | + expect(buttonElement).not.toBeInTheDocument() |
| 296 | + }) |
| 297 | + |
| 298 | + it('has tabIndex when clickable', () => { |
| 299 | + const { container } = render(<MetricsScoreCircle score={75} clickable={true} />) |
| 300 | + |
| 301 | + const clickableElement = container.querySelector('[tabindex="0"]') |
| 302 | + expect(clickableElement).toBeInTheDocument() |
| 303 | + }) |
| 304 | + |
| 305 | + it('does not have tabIndex when not clickable', () => { |
| 306 | + const { container } = render(<MetricsScoreCircle score={75} clickable={false} />) |
| 307 | + |
| 308 | + const clickableElement = container.querySelector('[tabindex]') |
| 309 | + expect(clickableElement).not.toBeInTheDocument() |
| 310 | + }) |
| 311 | + |
| 312 | + it('handles keyboard navigation when clickable', () => { |
| 313 | + const mockOnClick = jest.fn() |
| 314 | + render(<MetricsScoreCircle score={75} clickable={true} onClick={mockOnClick} />) |
| 315 | + |
| 316 | + const buttonElement = screen.getByRole('button') |
| 317 | + |
| 318 | + // Test Enter key |
| 319 | + fireEvent.keyDown(buttonElement, { key: 'Enter' }) |
| 320 | + expect(mockOnClick).toHaveBeenCalledTimes(1) |
| 321 | + |
| 322 | + // Test Space key |
| 323 | + fireEvent.keyDown(buttonElement, { key: ' ' }) |
| 324 | + expect(mockOnClick).toHaveBeenCalledTimes(2) |
| 325 | + }) |
| 326 | + |
| 327 | + it('does not handle keyboard navigation when not clickable', () => { |
| 328 | + const mockOnClick = jest.fn() |
| 329 | + render(<MetricsScoreCircle score={75} clickable={false} onClick={mockOnClick} />) |
| 330 | + |
| 331 | + const circleElement = screen.getByText('75').closest('.group') |
| 332 | + if (circleElement) { |
| 333 | + fireEvent.keyDown(circleElement, { key: 'Enter' }) |
| 334 | + fireEvent.keyDown(circleElement, { key: ' ' }) |
| 335 | + } |
| 336 | + |
| 337 | + expect(mockOnClick).not.toHaveBeenCalled() |
| 338 | + }) |
| 339 | + }) |
| 340 | + |
| 341 | + // Test 13: Maintains existing functionality with new props |
| 342 | + it('maintains all existing functionality when clickable is true', () => { |
| 343 | + const { container } = render(<MetricsScoreCircle score={25} clickable={true} />) |
| 344 | + |
| 345 | + // Should still have red styling |
| 346 | + expect(container.querySelector('[class*="bg-red"]')).toBeInTheDocument() |
| 347 | + |
| 348 | + // Should still have pulse animation |
| 349 | + expect(container.querySelector('[class*="animate-pulse"]')).toBeInTheDocument() |
| 350 | + |
| 351 | + // Should still display correct score |
| 352 | + expect(screen.getByText('25')).toBeInTheDocument() |
| 353 | + |
| 354 | + // Should still have tooltip |
| 355 | + expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute( |
| 356 | + 'data-content', |
| 357 | + 'Current Project Health Score' |
| 358 | + ) |
| 359 | + |
| 360 | + // Should have hover effects |
| 361 | + expect(container.querySelector('[class*="hover:"]')).toBeInTheDocument() |
| 362 | + }) |
| 363 | + |
| 364 | + it('maintains all existing functionality when clickable is false', () => { |
| 365 | + const { container } = render(<MetricsScoreCircle score={25} clickable={false} />) |
| 366 | + |
| 367 | + // Should still have red styling |
| 368 | + expect(container.querySelector('[class*="bg-red"]')).toBeInTheDocument() |
| 369 | + |
| 370 | + // Should still have pulse animation |
| 371 | + expect(container.querySelector('[class*="animate-pulse"]')).toBeInTheDocument() |
| 372 | + |
| 373 | + // Should still display correct score |
| 374 | + expect(screen.getByText('25')).toBeInTheDocument() |
| 375 | + |
| 376 | + // Should still have tooltip |
| 377 | + expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute( |
| 378 | + 'data-content', |
| 379 | + 'Current Project Health Score' |
| 380 | + ) |
| 381 | + |
| 382 | + // Should NOT have hover effects |
| 383 | + expect(container.querySelector('[class*="hover:"]')).not.toBeInTheDocument() |
| 384 | + }) |
221 | 385 | })
|
0 commit comments