From 2ca10ff3c4c10975fcac79cbd31e071118d6c945 Mon Sep 17 00:00:00 2001 From: shivnshshrma Date: Fri, 25 Jul 2025 13:26:56 +0530 Subject: [PATCH 1/2] feat: add comprehensive unit tests for MetricsScoreCircle component --- .../components/MetricsScoreCircle.test.tsx | 208 ++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx diff --git a/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx b/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx new file mode 100644 index 0000000000..6a7aadb2b2 --- /dev/null +++ b/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx @@ -0,0 +1,208 @@ +import { render, screen } from '@testing-library/react' +import '@testing-library/jest-dom' +import MetricsScoreCircle from 'components/MetricsScoreCircle' + +// Mock the Tooltip component from @heroui/tooltip +jest.mock('@heroui/tooltip', () => ({ + Tooltip: ({ children, content, placement }: any) => ( +
+ {children} +
+ ), +})) + +describe('MetricsScoreCircle', () => { + // Test 1: Renders successfully with minimal required props + it('renders successfully with score prop', () => { + render() + expect(screen.getByText('75')).toBeInTheDocument() + expect(screen.getByText('Health')).toBeInTheDocument() + expect(screen.getByText('Score')).toBeInTheDocument() + }) + + // Test 2: Text and content rendering + it('displays the correct score value', () => { + const score = 85 + render() + expect(screen.getByText(score.toString())).toBeInTheDocument() + }) + + it('displays static labels correctly', () => { + render() + expect(screen.getByText('Health')).toBeInTheDocument() + expect(screen.getByText('Score')).toBeInTheDocument() + }) + + // Test 3: Conditional rendering logic - Color schemes based on score + describe('score-based styling', () => { + it('applies green styling for high scores (>= 75)', () => { + const { container } = render() + // Look for elements with green background classes + const greenElement = container.querySelector('[class*="bg-green"]') + expect(greenElement).toBeInTheDocument() + }) + + it('applies yellow styling for medium scores (50-74)', () => { + const { container } = render() + // Look for elements with yellow background classes + const yellowElement = container.querySelector('[class*="bg-yellow"]') + expect(yellowElement).toBeInTheDocument() + }) + + it('applies red styling for low scores (< 50)', () => { + const { container } = render() + // Look for elements with red background classes + const redElement = container.querySelector('[class*="bg-red"]') + expect(redElement).toBeInTheDocument() + }) + + it('applies correct styling at boundary values', () => { + // Test score = 50 (should be yellow) + const { container: container50 } = render() + expect(container50.querySelector('[class*="bg-yellow"]')).toBeInTheDocument() + + // Test score = 74 (should be yellow) + const { container: container74 } = render() + expect(container74.querySelector('[class*="bg-yellow"]')).toBeInTheDocument() + + // Test score = 75 (should be green) + const { container: container75 } = render() + expect(container75.querySelector('[class*="bg-green"]')).toBeInTheDocument() + }) + }) + + // Test 4: Conditional rendering - Pulse animation for very low scores + it('shows pulse animation for scores below 30', () => { + const { container } = render() + const pulseElement = container.querySelector('[class*="animate-pulse"]') + expect(pulseElement).toBeInTheDocument() + }) + + it('does not show pulse animation for scores 30 and above', () => { + const { container } = render() + const pulseElement = container.querySelector('[class*="animate-pulse"]') + expect(pulseElement).not.toBeInTheDocument() + }) + + // Test 5: Tooltip functionality + it('renders tooltip with correct content', () => { + render() + const tooltipWrapper = screen.getByTestId('tooltip-wrapper') + expect(tooltipWrapper).toHaveAttribute('data-content', 'Current Project Health Score') + expect(tooltipWrapper).toHaveAttribute('data-placement', 'top') + }) + + // Test 6: DOM structure and classNames + it('has correct DOM structure and classes', () => { + const { container } = render() + + // Check for main structural elements + const tooltipWrapper = screen.getByTestId('tooltip-wrapper') + expect(tooltipWrapper).toBeInTheDocument() + + // Check for elements with expected classes + const circularElement = container.querySelector('[class*="rounded-full"]') + expect(circularElement).toBeInTheDocument() + + const flexElement = container.querySelector('[class*="flex"]') + expect(flexElement).toBeInTheDocument() + }) + + // Test 7: Handles edge cases and invalid inputs + describe('edge cases', () => { + it('handles score of 0', () => { + render() + expect(screen.getByText('0')).toBeInTheDocument() + // Should be red styling + const { container } = render() + expect(container.querySelector('[class*="bg-red"]')).toBeInTheDocument() + }) + + it('handles score of 100', () => { + render() + expect(screen.getByText('100')).toBeInTheDocument() + // Should be green styling + const { container } = render() + expect(container.querySelector('[class*="bg-green"]')).toBeInTheDocument() + }) + + it('handles negative scores', () => { + render() + expect(screen.getByText('-10')).toBeInTheDocument() + // Should be red styling + const { container } = render() + expect(container.querySelector('[class*="bg-red"]')).toBeInTheDocument() + }) + + it('handles scores above 100', () => { + render() + expect(screen.getByText('150')).toBeInTheDocument() + // Should be green styling + const { container } = render() + expect(container.querySelector('[class*="bg-green"]')).toBeInTheDocument() + }) + + it('handles decimal scores', () => { + render() + expect(screen.getByText('75.5')).toBeInTheDocument() + }) + }) + + // Test 8: Accessibility + it('has proper accessibility structure', () => { + render() + + // Check that the tooltip provides accessible description + const tooltipWrapper = screen.getByTestId('tooltip-wrapper') + expect(tooltipWrapper).toBeInTheDocument() + + // Verify text content is accessible + expect(screen.getByText('75')).toBeInTheDocument() + expect(screen.getByText('Health')).toBeInTheDocument() + expect(screen.getByText('Score')).toBeInTheDocument() + }) + + // Test 9: Event handling - hover effects (visual testing through classes) + it('has hover effect classes applied', () => { + const { container } = render() + + // Check for hover-related classes + const hoverElement = container.querySelector('[class*="hover:"]') + expect(hoverElement).toBeInTheDocument() + }) + + // Test 10: Component integration test + it('integrates all features correctly for a low score', () => { + const { container } = render() + + // Should have red styling + expect(container.querySelector('[class*="bg-red"]')).toBeInTheDocument() + + // Should have pulse animation + expect(container.querySelector('[class*="animate-pulse"]')).toBeInTheDocument() + + // Should display correct score + expect(screen.getByText('15')).toBeInTheDocument() + + // Should have tooltip + expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute('data-content', 'Current Project Health Score') + }) + + it('integrates all features correctly for a high score', () => { + const { container } = render() + + // Should have green styling + expect(container.querySelector('[class*="bg-green"]')).toBeInTheDocument() + + // Should NOT have pulse animation + expect(container.querySelector('[class*="animate-pulse"]')).not.toBeInTheDocument() + + // Should display correct score + expect(screen.getByText('90')).toBeInTheDocument() + + // Should have tooltip + expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute('data-content', 'Current Project Health Score') + }) +}) + + From 12b4c26d7fe24cbe2016b71c1b946b224269bfdc Mon Sep 17 00:00:00 2001 From: shivnshshrma Date: Sat, 26 Jul 2025 09:41:19 +0530 Subject: [PATCH 2/2] fix: apply code formatting to MetricsScoreCircle test file --- .../components/MetricsScoreCircle.test.tsx | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx b/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx index 6a7aadb2b2..141d550c58 100644 --- a/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx +++ b/frontend/__tests__/unit/components/MetricsScoreCircle.test.tsx @@ -1,10 +1,19 @@ import { render, screen } from '@testing-library/react' +import React from 'react' import '@testing-library/jest-dom' import MetricsScoreCircle from 'components/MetricsScoreCircle' // Mock the Tooltip component from @heroui/tooltip jest.mock('@heroui/tooltip', () => ({ - Tooltip: ({ children, content, placement }: any) => ( + Tooltip: ({ + children, + content, + placement, + }: { + children: React.ReactNode + content: string + placement: string + }) => (
{children}
@@ -95,15 +104,15 @@ describe('MetricsScoreCircle', () => { // Test 6: DOM structure and classNames it('has correct DOM structure and classes', () => { const { container } = render() - + // Check for main structural elements const tooltipWrapper = screen.getByTestId('tooltip-wrapper') expect(tooltipWrapper).toBeInTheDocument() - + // Check for elements with expected classes const circularElement = container.querySelector('[class*="rounded-full"]') expect(circularElement).toBeInTheDocument() - + const flexElement = container.querySelector('[class*="flex"]') expect(flexElement).toBeInTheDocument() }) @@ -151,11 +160,11 @@ describe('MetricsScoreCircle', () => { // Test 8: Accessibility it('has proper accessibility structure', () => { render() - + // Check that the tooltip provides accessible description const tooltipWrapper = screen.getByTestId('tooltip-wrapper') expect(tooltipWrapper).toBeInTheDocument() - + // Verify text content is accessible expect(screen.getByText('75')).toBeInTheDocument() expect(screen.getByText('Health')).toBeInTheDocument() @@ -165,7 +174,7 @@ describe('MetricsScoreCircle', () => { // Test 9: Event handling - hover effects (visual testing through classes) it('has hover effect classes applied', () => { const { container } = render() - + // Check for hover-related classes const hoverElement = container.querySelector('[class*="hover:"]') expect(hoverElement).toBeInTheDocument() @@ -174,35 +183,39 @@ describe('MetricsScoreCircle', () => { // Test 10: Component integration test it('integrates all features correctly for a low score', () => { const { container } = render() - + // Should have red styling expect(container.querySelector('[class*="bg-red"]')).toBeInTheDocument() - + // Should have pulse animation expect(container.querySelector('[class*="animate-pulse"]')).toBeInTheDocument() - + // Should display correct score expect(screen.getByText('15')).toBeInTheDocument() - + // Should have tooltip - expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute('data-content', 'Current Project Health Score') + expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute( + 'data-content', + 'Current Project Health Score' + ) }) it('integrates all features correctly for a high score', () => { const { container } = render() - + // Should have green styling expect(container.querySelector('[class*="bg-green"]')).toBeInTheDocument() - + // Should NOT have pulse animation expect(container.querySelector('[class*="animate-pulse"]')).not.toBeInTheDocument() - + // Should display correct score expect(screen.getByText('90')).toBeInTheDocument() - + // Should have tooltip - expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute('data-content', 'Current Project Health Score') + expect(screen.getByTestId('tooltip-wrapper')).toHaveAttribute( + 'data-content', + 'Current Project Health Score' + ) }) }) - -