Skip to content

Conversation

@VrajVed
Copy link

@VrajVed VrajVed commented Jul 23, 2025

Proposed change

Resolves #1807

Added fallback checks,
Tested edge cases with missing values,
Tested if props pass and components render

Checklist

  • I've read and followed the contributing guidelines.
  • I've run make check-test locally; all checks and tests passed.

@VrajVed VrajVed requested review from arkid15r and kasya as code owners July 23, 2025 18:53
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 23, 2025

Summary by CodeRabbit

  • New Features
    • Dashboard cards now display a default title and icon when none are provided.
  • Tests
    • Added unit tests to verify DashboardCard behavior for rendering titles, icons, and default values.

Walkthrough

A new unit test file for the DashboardCard React component was added, testing rendering, prop-based behavior, and default fallbacks. The component itself was updated to make the icon prop optional, provide default values for missing title and icon, and add test IDs to icon elements for improved testability.

Changes

File(s) Change Summary
frontend/tests/unit/components/DashboardCard.test.tsx Added new unit tests for DashboardCard, covering rendering, props, and default fallbacks.
frontend/src/components/DashboardCard.tsx Made icon prop optional, added default title/icon logic, and included test IDs for icons.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
frontend/src/components/DashboardCard.tsx (1)

16-16: Consider using nullish coalescing for cleaner fallback logic.

The current title fallback logic works but could be simplified using nullish coalescing for better readability.

-title={title ? (<AnchorTitle title={title} />) : (<AnchorTitle title="Default" />)}
+title={<AnchorTitle title={title || "Default"} />}
frontend/__tests__/unit/components/DashboardCard.test.tsx (1)

17-21: Add test coverage for missing edge cases.

The current tests don't cover all possible combinations of props. Consider adding tests for scenarios like undefined title, missing required props, and className prop functionality.

Add additional test cases:

it("renders default title when title is undefined", () => {
    render(<DashboardCard title={undefined as any} />)
    expect(screen.getByText("Default")).toBeInTheDocument()
})

it("applies custom className when provided", () => {
    const { container } = render(<DashboardCard title="Test" className="custom-class" />)
    expect(container.querySelector('.custom-class')).toBeInTheDocument()
})
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 609477c and 28fa32f.

📒 Files selected for processing (2)
  • frontend/__tests__/unit/components/DashboardCard.test.tsx (1 hunks)
  • frontend/src/components/DashboardCard.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#1714
File: frontend/src/components/ProjectTypeDashboardCard.tsx:8-12
Timestamp: 2025-07-08T17:07:50.988Z
Learning: In the OWASP/Nest project, union types for component props are not necessary when they would require creating separate type definitions. The project prefers inline prop type definitions even for props with specific string values, maintaining consistency with the single-use component prop pattern.
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: frontend/__tests__/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.
frontend/src/components/DashboardCard.tsx (3)

Learnt from: ahmedxgouda
PR: #1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: healthMetricsData.length > 0. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Learnt from: ahmedxgouda
PR: #1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Learnt from: ahmedxgouda
PR: #1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a safety check that ensures HealthMetrics component is only rendered when healthMetricsData exists and has at least one element: healthMetricsData && healthMetricsData.length > 0. This makes accessing data[0] safe within the HealthMetrics component.

frontend/__tests__/unit/components/DashboardCard.test.tsx (3)

Learnt from: Rajgupta36
PR: #1717
File: frontend/tests/unit/pages/createProgram.test.tsx:70-86
Timestamp: 2025-07-12T17:36:57.255Z
Learning: When testing React page components that use mocked form components, validation logic should be tested at the form component level, not the page level. Page-level tests should focus on authentication, role checking, submission handling, and navigation logic.

Learnt from: ahmedxgouda
PR: #1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a length check before rendering HealthMetrics: healthMetricsData.length > 0. This ensures that when HealthMetrics is rendered, the data array has at least one element, making accessing data[0] safe within the HealthMetrics component.

Learnt from: ahmedxgouda
PR: #1633
File: frontend/src/components/HealthMetrics.tsx:30-30
Timestamp: 2025-06-20T16:12:59.256Z
Learning: In the DetailsCard component (frontend/src/components/CardDetailsPage.tsx), there's a safety check that ensures HealthMetrics component is only rendered when healthMetricsData exists and has at least one element: healthMetricsData && healthMetricsData.length > 0. This makes accessing data[0] safe within the HealthMetrics component.

🔇 Additional comments (4)
frontend/src/components/DashboardCard.tsx (2)

10-10: LGTM: Optional icon prop.

Making the icon prop optional aligns well with the fallback functionality and improves component flexibility.


21-23: Consistent test ID usage and good fallback logic.

The conditional icon rendering with fallback to faUser is well-implemented, and the consistent use of data-testid attributes will facilitate reliable testing.

frontend/__tests__/unit/components/DashboardCard.test.tsx (2)

6-10: Good basic rendering test.

The test correctly verifies that both title and icon are rendered when provided.


12-15: Good stats rendering coverage.

The test appropriately covers the optional stats prop functionality.

@@ -0,0 +1,22 @@
import {render, screen } from '@testing-library/react'
import DashboardCard from 'components/DashboardCard'
import { faUser } from '@fortawesome/free-solid-svg-icons'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Import mismatch with component.

The test imports faUser from @fortawesome/free-solid-svg-icons while the component imports it from @fortawesome/free-regular-svg-icons. This inconsistency should be resolved for consistency.

Update the import to match the component:

-import { faUser } from '@fortawesome/free-solid-svg-icons'
+import { faUser } from '@fortawesome/free-regular-svg-icons'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { faUser } from '@fortawesome/free-solid-svg-icons'
import { faUser } from '@fortawesome/free-regular-svg-icons'
🤖 Prompt for AI Agents
In frontend/__tests__/unit/components/DashboardCard.test.tsx at line 3, the test
imports faUser from @fortawesome/free-solid-svg-icons, but the component imports
it from @fortawesome/free-regular-svg-icons. Change the import statement in the
test file to import faUser from @fortawesome/free-regular-svg-icons to ensure
consistency between the test and the component.

Comment on lines 17 to 21
it("checks if icon, title values are null, if yes, fall back to defaults", ()=> {
render(<DashboardCard title="" icon={null} />)
expect(screen.getByText("Default")).toBeInTheDocument()
expect(screen.getByTestId("dashboardcard-icon")).toBeInTheDocument()
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance fallback test with more specific assertions.

The test covers the fallback scenario but could be more comprehensive by verifying the specific fallback values and testing different edge cases.

Consider enhancing the test with more specific assertions:

-it("checks if icon, title values are null, if yes, fall back to defaults", ()=> {
+it("renders default values when title is empty and icon is null", () => {
     render(<DashboardCard title="" icon={null} />)
     expect(screen.getByText("Default")).toBeInTheDocument()
     expect(screen.getByTestId("dashboardcard-icon")).toBeInTheDocument()
+    
+    // Additional test cases for edge scenarios
+    render(<DashboardCard title="Valid Title" icon={null} />)
+    expect(screen.getByText("Valid Title")).toBeInTheDocument()
+    expect(screen.getByTestId("dashboardcard-icon")).toBeInTheDocument()
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("checks if icon, title values are null, if yes, fall back to defaults", ()=> {
render(<DashboardCard title="" icon={null} />)
expect(screen.getByText("Default")).toBeInTheDocument()
expect(screen.getByTestId("dashboardcard-icon")).toBeInTheDocument()
});
it("renders default values when title is empty and icon is null", () => {
render(<DashboardCard title="" icon={null} />)
expect(screen.getByText("Default")).toBeInTheDocument()
expect(screen.getByTestId("dashboardcard-icon")).toBeInTheDocument()
// Additional test case for when title is provided but icon is null
render(<DashboardCard title="Valid Title" icon={null} />)
expect(screen.getByText("Valid Title")).toBeInTheDocument()
expect(screen.getByTestId("dashboardcard-icon")).toBeInTheDocument()
});
🤖 Prompt for AI Agents
In frontend/__tests__/unit/components/DashboardCard.test.tsx around lines 17 to
21, the test for fallback values only checks for generic presence of default
text and icon. Improve it by adding assertions that verify the exact fallback
title string and the specific default icon rendered. Also, add tests for other
edge cases like undefined or missing props to ensure all fallback scenarios are
covered comprehensively.

import React from 'react'
import AnchorTitle from 'components/AnchorTitle'
import SecondaryCard from 'components/SecondaryCard'
import { faUser } from '@fortawesome/free-regular-svg-icons'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Import mismatch detected.

The component imports faUser from @fortawesome/free-regular-svg-icons but the test file imports it from @fortawesome/free-solid-svg-icons. This inconsistency could lead to different icons being rendered.

Ensure consistent icon imports across the codebase:

-import { faUser } from '@fortawesome/free-regular-svg-icons'
+import { faUser } from '@fortawesome/free-solid-svg-icons'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { faUser } from '@fortawesome/free-regular-svg-icons'
-import { faUser } from '@fortawesome/free-regular-svg-icons'
+import { faUser } from '@fortawesome/free-solid-svg-icons'
🤖 Prompt for AI Agents
In frontend/src/components/DashboardCard.tsx at line 6, the import of faUser is
from @fortawesome/free-regular-svg-icons, but the test imports it from
@fortawesome/free-solid-svg-icons. To fix this, update the import statement to
use the same icon package as the test file, which is
@fortawesome/free-solid-svg-icons, ensuring consistent icon usage across the
codebase.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you change the component's code?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did that to add fallbacks to defaults in case the values passed are missing/null, is there a different way to do it ??

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I just didn't expect any changes to the source code unless it's a bug fix.

As for the changes -- both title/icon are mandatory params but you've changed icon to optional for some reason. I suggest reverting the component code changes and keeping the tests for review. Also we don't use testids I guess.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I just didn't expect any changes to the source code unless it's a bug fix.

As for the changes -- both title/icon are mandatory params but you've changed icon to optional for some reason. I suggest reverting the component code changes and keeping the tests for review. Also we don't use testids I guess.

@sonarqubecloud
Copy link

@VrajVed
Copy link
Author

VrajVed commented Jul 24, 2025

@arkid15r

image

This is what happens when I keep icon as compulsory because the icon value doesn't take null as an argument. Also to add the defaults and fall backs, the component needs to be changed. I needed to add the title attribute to test for the icon

expect(screen.getByTitle('user-icon')).toBeInTheDocument() /*Test Passed*/
<FontAwesomeIcon icon={icon} title='user-icon'/>

@VrajVed VrajVed mentioned this pull request Jul 25, 2025
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add tests for <DashboardCard> component

2 participants