Skip to content

Conversation

@ahmedxgouda
Copy link
Collaborator

@ahmedxgouda ahmedxgouda commented Jul 17, 2025

Resolves #1702

Screencast.from.2025-07-20.17-34-08.mp4

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 17, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a detailed Project Health Metrics Details page with visual dashboards, compliance indicators, and bar charts for project metrics.
    • Added new components for health score visualization and compliance display.
    • Extended project health metrics data with additional fields, including total issues, total releases, and compliance requirements.
  • Bug Fixes

    • Updated data sources and property names throughout the app to ensure consistent access to health metrics.
  • Tests

    • Added comprehensive unit and end-to-end tests for new dashboard components and metrics details.
    • Updated and extended test data and coverage for new fields and features.
  • Refactor

    • Replaced inline health score styling with a reusable component.
    • Updated property and field names for clarity and consistency across backend and frontend.
  • Chores

    • Added and updated mock data to support new dashboard features and tests.

Walkthrough

This change introduces new fields and resolvers to the backend GraphQL schema for project health metrics, adds corresponding properties to the frontend types, and implements a detailed project health metrics dashboard page in the frontend. It also refactors components and queries to accommodate these schema updates and improve the presentation of health metric details.

Changes

Files/Paths Change Summary
backend/apps/owasp/graphql/nodes/project.py Renamed health_metrics to health_metrics_list; added health_metrics_latest resolver.
backend/apps/owasp/graphql/nodes/project_health_metrics.py Added total_issues_count, total_releases_count fields; added age_days_requirement, last_pull_request_days_requirement, and owasp_page_last_update_days_requirement resolvers.
backend/apps/owasp/models/project_health_metrics.py Added age_days_requirement, last_pull_request_days_requirement, and owasp_page_last_update_days_requirement properties.
backend/tests/apps/owasp/graphql/nodes/project_health_metrics_test.py Updated tests to include new fields in ProjectHealthMetricsNode.
backend/tests/apps/owasp/graphql/queries/project_health_metrics_test.py Updated test data to include new issue and release count fields.
backend/tests/apps/owasp/graphql/nodes/project_test.py Replaced single health_metrics test with separate tests for health_metrics_latest and health_metrics_list.
frontend/tests/unit/data/mockProjectDetailsData.ts Renamed healthMetrics to healthMetricsList in mock project details data.
frontend/src/app/projects/[projectKey]/page.tsx Updated to use project.healthMetricsList instead of project.healthMetrics.
frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx Added new detailed metrics dashboard page component for project health metrics.
frontend/src/components/CardDetailsPage.tsx Replaced inline health score rendering with MetricsScoreCircle component.
frontend/src/components/DashboardCard.tsx Made stats prop optional, added optional className prop, and updated rendering logic.
frontend/src/components/GeneralCompliantComponent.tsx Added new component for compliance status display.
frontend/src/components/MetricsScoreCircle.tsx Added new component for rendering health score as a styled circle.
frontend/src/components/BarChart.tsx Added optional reverseColors prop to invert color logic for specific bars.
frontend/src/server/queries/projectQueries.ts Updated GraphQL query to use healthMetricsList instead of healthMetrics.
frontend/src/server/queries/projectsHealthDashboardQueries.ts Added new GET_PROJECT_HEALTH_METRICS_DETAILS GraphQL query for detailed metrics.
frontend/src/types/healthMetrics.ts Extended HealthMetricsProps with new fields for metrics and requirements.
frontend/src/types/project.ts Renamed healthMetrics property to healthMetricsList in Project type.

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Implement the presentation of the project health metrics details (#1702)
Add charts and detailed metrics to the project health metrics page (#1702)
Update backend and frontend types/queries to support new metrics fields (#1702)

Assessment against linked issues: Out-of-scope changes

No out-of-scope changes found.

Possibly related PRs

Suggested labels

frontend-tests

Suggested reviewers

  • arkid15r
  • aramattamara
  • kasya

📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 373e16f and ed476bc.

📒 Files selected for processing (3)
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (1 hunks)
  • frontend/src/components/GeneralCompliantComponent.tsx (1 hunks)
  • frontend/src/components/MetricsScoreCircle.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/components/MetricsScoreCircle.tsx
  • frontend/src/components/GeneralCompliantComponent.tsx
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
✨ 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 auto-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: 1

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

16-16: Handle undefined className gracefully.

The current template literal concatenation will include "undefined" in the class string when className is not provided.

-      className={`overflow-hidden transition-colors duration-300 hover:bg-blue-100 dark:hover:bg-blue-950 ${className}`}
+      className={`overflow-hidden transition-colors duration-300 hover:bg-blue-100 dark:hover:bg-blue-950 ${className || ''}`}
frontend/src/components/GeneralCompliantComponent.tsx (2)

13-14: Review hover color contrast for accessibility.

The red hover state uses the same color for both light and dark modes (hover:bg-red-600 dark:hover:bg-red-600), which might not provide optimal contrast in dark mode.

-  const redClass = 'bg-red-100 dark:bg-red-700 hover:bg-red-600 dark:hover:bg-red-600'
+  const redClass = 'bg-red-100 dark:bg-red-700 hover:bg-red-200 dark:hover:bg-red-600'

17-25: Consider adding accessibility attributes.

The component would benefit from accessibility attributes to convey the compliance status to screen readers.

     <SecondaryCard
-      className={clsx('pointer-events-auto items-center justify-center text-center font-light', {
+      className={clsx('pointer-events-auto items-center justify-center text-center font-light', {
         [greenClass]: compliant,
         [redClass]: !compliant,
       })}
+      role="status"
+      aria-label={compliant ? 'Compliant' : 'Non-compliant'}
     >
frontend/src/components/MetricsScoreCircle.tsx (1)

20-22: Consider accessibility for pulsing animation.

The pulsing animation for low scores might be problematic for users with motion sensitivity. Consider adding a prefers-reduced-motion check.

   {score < 30 && (
-    <div className="animate-pulse absolute inset-0 rounded-full bg-red-400/20"></div>
+    <div className="motion-safe:animate-pulse absolute inset-0 rounded-full bg-red-400/20"></div>
   )}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 926bd33 and 22ff74d.

📒 Files selected for processing (15)
  • backend/apps/owasp/graphql/nodes/project.py (1 hunks)
  • backend/apps/owasp/graphql/nodes/project_health_metrics.py (3 hunks)
  • backend/apps/owasp/models/project_health_metrics.py (2 hunks)
  • backend/tests/apps/owasp/graphql/nodes/project_health_metrics_test.py (2 hunks)
  • backend/tests/apps/owasp/graphql/queries/project_health_metrics_test.py (1 hunks)
  • frontend/src/app/projects/[projectKey]/page.tsx (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (1 hunks)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
  • frontend/src/components/DashboardCard.tsx (1 hunks)
  • frontend/src/components/GeneralCompliantComponent.tsx (1 hunks)
  • frontend/src/components/MetricsScoreCircle.tsx (1 hunks)
  • frontend/src/server/queries/projectQueries.ts (1 hunks)
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts (1 hunks)
  • frontend/src/types/healthMetrics.ts (1 hunks)
  • frontend/src/types/project.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/app/projects/[projectKey]/page.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/types/project.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/components/CardDetailsPage.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/components/DashboardCard.tsx (3)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.
frontend/src/components/MetricsScoreCircle.tsx (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/types/healthMetrics.ts (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.
backend/apps/owasp/graphql/nodes/project_health_metrics.py (3)
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: backend/apps/mentorship/graphql/queries/module.py:39-50
Timestamp: 2025-07-11T15:57:56.648Z
Learning: In the OWASP Nest mentorship GraphQL queries, Strawberry GraphQL automatically converts between Django Module instances and ModuleNode types, so methods can return Module instances directly without manual conversion even when typed as ModuleNode.
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: backend/apps/mentorship/graphql/mutations/program.py:166-166
Timestamp: 2025-07-13T05:55:46.436Z
Learning: In the OWASP Nest mentorship GraphQL mutations, Strawberry GraphQL automatically converts between Django Program instances and ProgramNode types, so mutations can return Program instances directly without manual conversion even when typed as ProgramNode, similar to the Module/ModuleNode pattern.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
backend/apps/owasp/models/project_health_metrics.py (1)
Learnt from: ahmedxgouda
PR: OWASP/Nest#1633
File: frontend/src/components/GradientRadialChart.tsx:113-113
Timestamp: 2025-06-21T12:22:01.889Z
Learning: In the OWASP Nest project, health metrics requirements (like lastCommitDaysRequirement, lastReleaseDaysRequirement) should never be 0. A requirement value of 0 is considered invalid and should result in displaying 0 on the radial chart.
frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (5)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: frontend/src/components/ModuleCard.tsx:53-55
Timestamp: 2025-07-13T07:31:06.511Z
Learning: In Next.js 13+ app router, useRouter from 'next/navigation' does not provide asPath or query properties. Use useParams to extract route parameters and usePathname to get the current pathname instead.
Learnt from: Rajgupta36
PR: OWASP/Nest#1717
File: frontend/src/app/mentorship/programs/page.tsx:59-61
Timestamp: 2025-07-13T11:29:25.245Z
Learning: In Next.js 13+ app router, components with the 'use client' directive run entirely on the client side and don't require window object existence checks or SSR hydration considerations. Direct access to window.location and other browser APIs is safe in client components.
frontend/src/server/queries/projectQueries.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/server/queries/projectsHealthDashboardQueries.ts (2)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
🧬 Code Graph Analysis (4)
frontend/src/types/project.ts (1)
frontend/src/types/healthMetrics.ts (1)
  • HealthMetricsProps (26-50)
backend/apps/owasp/graphql/nodes/project_health_metrics.py (1)
backend/apps/owasp/models/project_health_metrics.py (2)
  • age_days_requirement (91-93)
  • owasp_page_last_update_days_requirement (134-136)
backend/apps/owasp/models/project_health_metrics.py (1)
backend/apps/owasp/graphql/nodes/project_health_metrics.py (4)
  • age_days_requirement (41-43)
  • age_days (36-38)
  • owasp_page_last_update_days_requirement (86-88)
  • owasp_page_last_update_days (81-83)
frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (3)
frontend/src/types/healthMetrics.ts (1)
  • HealthMetricsProps (26-50)
frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)
  • GET_PROJECT_HEALTH_METRICS_DETAILS (21-51)
frontend/src/app/global-error.tsx (1)
  • handleAppError (66-86)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend unit tests
🔇 Additional comments (23)
frontend/src/app/projects/[projectKey]/page.tsx (1)

95-95: All healthMetrics references have been updated and verified

  • No remaining occurrences of the old healthMetrics prop in TS/TSX files.
  • healthMetricsList is used consistently in:
    • frontend/src/types/project.ts
    • frontend/src/server/queries/projectQueries.ts
    • frontend/src/app/projects/[projectKey]/page.tsx
  • healthMetricsData is passed and consumed correctly in CardDetailsPage, which includes the healthMetricsData.length > 0 safety check, and in the HealthMetrics component.

No further action required.

frontend/src/types/project.ts (1)

22-22: Type definition rename is consistent with backend changes.

The property rename from healthMetrics to healthMetricsList maintains the same type structure and optional nature, ensuring backward compatibility while aligning with the backend schema updates.

backend/tests/apps/owasp/graphql/queries/project_health_metrics_test.py (1)

87-88: Good test coverage for new schema fields.

The addition of total_issues_count and total_releases_count fields to the test data ensures proper coverage for the expanded ProjectHealthMetricsNode schema. The test values are reasonable and maintain existing test logic.

backend/tests/apps/owasp/graphql/nodes/project_health_metrics_test.py (2)

37-38: Comprehensive test coverage for new schema fields.

The addition of total_issues_count and total_releases_count to the expected field names ensures proper schema validation for the new fields.


74-75: Proper type validation for new fields.

The type validation for total_issues_count and total_releases_count as int follows the existing test pattern and ensures schema correctness.

frontend/src/server/queries/projectQueries.ts (1)

15-15: GraphQL query field rename is consistent with backend changes.

The field rename from healthMetrics(limit: 30) to healthMetricsList(limit: 30) maintains the same query structure and parameters while aligning with the backend schema updates.

frontend/src/components/DashboardCard.tsx (2)

10-12: Good API improvements for flexibility.

Making stats optional and adding className prop enhances the component's reusability.


20-20: LGTM on conditional stats rendering.

The conditional rendering prevents empty content when stats is undefined.

frontend/src/components/GeneralCompliantComponent.tsx (1)

1-28: Well-structured compliance indicator component.

The component is well-implemented with proper TypeScript types and clean conditional styling.

frontend/src/components/CardDetailsPage.tsx (2)

22-22: Good import addition for the new component.

The MetricsScoreCircle import is correctly added.


66-66: Excellent refactoring to use MetricsScoreCircle component.

Replacing inline styling logic with a dedicated component improves maintainability and reusability. The data access is safe based on the existing length check (healthMetricsData.length > 0) as confirmed by the retrieved learnings.

backend/apps/owasp/models/project_health_metrics.py (2)

90-93: LGTM on age_days_requirement property.

The implementation follows the established pattern of other requirement properties and provides proper access to the project requirements data.


133-136: LGTM on owasp_page_last_update_days_requirement property.

The implementation is consistent with the existing codebase pattern and provides the necessary requirement data access.

frontend/src/components/MetricsScoreCircle.tsx (1)

1-26: Well-designed health score visualization component.

The component provides excellent visual feedback with appropriate color coding, hover effects, and animations. The circular design and gradient overlay create a professional appearance.

backend/apps/owasp/graphql/nodes/project.py (2)

40-46: LGTM: Method rename improves API clarity.

The rename from health_metrics to health_metrics_list better describes that this method returns a list of metrics, improving API self-documentation.


48-57: Verified existence of get_latest_health_metrics
The get_latest_health_metrics method is defined in backend/apps/owasp/models/project_health_metrics.py at line 155, so the health_metrics_latest resolver will work as expected.

frontend/src/types/healthMetrics.ts (1)

27-47: LGTM: Type extensions correctly represent schema changes.

The new fields properly extend the HealthMetricsProps type to support the detailed dashboard functionality, with appropriate type annotations and consistent naming conventions.

backend/apps/owasp/graphql/nodes/project_health_metrics.py (2)

24-25: LGTM: New fields properly expose model attributes.

The addition of total_issues_count and total_releases_count to the fields list correctly exposes these model attributes through the GraphQL schema.


40-43: LGTM: New resolver methods follow established patterns.

Both age_days_requirement and owasp_page_last_update_days_requirement methods correctly implement the resolver pattern and align with the corresponding model properties shown in the relevant code snippets.

Also applies to: 85-88

frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (3)

32-41: LGTM: Component setup follows Next.js and Apollo Client best practices.

The component correctly uses useParams for route parameter extraction and useQuery for GraphQL data fetching with proper TypeScript typing.


43-50: LGTM: Error handling and data processing implemented correctly.

The useEffect properly handles GraphQL errors with the global error handler and safely processes the nested data structure before updating state.


51-146: LGTM: Well-structured UI with proper component composition.

The rendering logic properly handles loading states, uses conditional rendering for safety, and creates a well-organized dashboard layout with appropriate responsive design and reusable components.

frontend/src/server/queries/projectsHealthDashboardQueries.ts (1)

21-51: LGTM: Query correctly implements the extended schema.

The new GET_PROJECT_HEALTH_METRICS_DETAILS query properly uses the healthMetricsLatest field and requests all the necessary fields to support the detailed dashboard functionality.

Comment on lines 3 to 9
const MetricsScoreCircle: FC<{ score: number }> = ({ score }) => {
let scoreStyle = 'bg-green-400 text-green-900'
if (score < 50) {
scoreStyle = 'bg-red-400 text-red-900'
} else if (score < 75) {
scoreStyle = 'bg-yellow-400 text-yellow-900'
}
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

Extract score thresholds as constants.

The magic numbers for score thresholds should be extracted as constants for better maintainability and consistency with the backend thresholds.

+const SCORE_THRESHOLD_HEALTHY = 75
+const SCORE_THRESHOLD_NEED_ATTENTION = 50
+
 const MetricsScoreCircle: FC<{ score: number }> = ({ score }) => {
   let scoreStyle = 'bg-green-400 text-green-900'
-  if (score < 50) {
+  if (score < SCORE_THRESHOLD_NEED_ATTENTION) {
     scoreStyle = 'bg-red-400 text-red-900'
-  } else if (score < 75) {
+  } else if (score < SCORE_THRESHOLD_HEALTHY) {
     scoreStyle = 'bg-yellow-400 text-yellow-900'
   }
🤖 Prompt for AI Agents
In frontend/src/components/MetricsScoreCircle.tsx around lines 3 to 9, the score
thresholds 50 and 75 are hardcoded magic numbers. Extract these threshold values
into clearly named constants at the top of the file to improve maintainability
and ensure consistency with backend threshold definitions. Replace the hardcoded
numbers in the conditional logic with these constants.

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: 1

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

84-91: Apply optional chaining for cleaner code.

The conditional color logic is well-implemented and adds valuable flexibility for different metric visualizations. However, the condition can be simplified using optional chaining.

Apply this diff to use optional chaining:

-              if (reverseColors && reverseColors[dataPointIndex]) {
+              if (reverseColors?.[dataPointIndex]) {

This change eliminates the redundant null check and makes the code more concise, as suggested by the static analysis tool.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 22ff74d and e8400c4.

📒 Files selected for processing (9)
  • backend/apps/owasp/graphql/nodes/project_health_metrics.py (4 hunks)
  • backend/apps/owasp/models/project_health_metrics.py (3 hunks)
  • backend/tests/apps/owasp/graphql/nodes/project_test.py (1 hunks)
  • frontend/__tests__/unit/data/mockProjectDetailsData.ts (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (1 hunks)
  • frontend/src/components/BarChart.tsx (2 hunks)
  • frontend/src/components/GeneralCompliantComponent.tsx (1 hunks)
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts (1 hunks)
  • frontend/src/types/healthMetrics.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • frontend/tests/unit/data/mockProjectDetailsData.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • frontend/src/components/GeneralCompliantComponent.tsx
  • backend/apps/owasp/models/project_health_metrics.py
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx
  • backend/apps/owasp/graphql/nodes/project_health_metrics.py
  • frontend/src/types/healthMetrics.ts
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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/src/components/BarChart.tsx (3)
Learnt from: ahmedxgouda
PR: OWASP/Nest#1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
🧬 Code Graph Analysis (1)
backend/tests/apps/owasp/graphql/nodes/project_test.py (3)
backend/tests/apps/owasp/graphql/nodes/project_health_metrics_test.py (1)
  • _get_field_by_name (44-52)
backend/tests/apps/github/graphql/nodes/repository_test.py (1)
  • _get_field_by_name (41-44)
backend/apps/owasp/graphql/nodes/project_health_metrics.py (1)
  • ProjectHealthMetricsNode (32-93)
🪛 Biome (1.9.4)
frontend/src/components/BarChart.tsx

[error] 84-84: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run backend tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (2)
frontend/src/components/BarChart.tsx (1)

20-21: LGTM! Well-designed optional prop addition.

The new reverseColors prop is appropriately typed as optional and properly integrated into the component signature.

backend/tests/apps/owasp/graphql/nodes/project_test.py (1)

52-55: LGTM!

The test correctly verifies that the health_metrics_list field exists and returns a list of ProjectHealthMetricsNode objects. The assertion pattern is consistent with other list field tests in the file.

Comment on lines +47 to +50
def test_resolve_health_metrics_latest(self):
field = self._get_field_by_name("health_metrics_latest")
assert field is not None
assert field.type.of_type is ProjectHealthMetricsNode
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify the expected return type for health_metrics_latest field.

The test uses field.type.of_type which is typically used for list types, but the field name health_metrics_latest suggests it should return a single ProjectHealthMetricsNode object, not a list.

If health_metrics_latest returns a single object, the assertion should be:

-        assert field.type.of_type is ProjectHealthMetricsNode
+        assert field.type is ProjectHealthMetricsNode

If it returns a list, then the current assertion is correct.


🏁 Script executed:

#!/bin/bash
# Description: Check the actual field definition in the ProjectNode to determine the correct return type
# Expected: Find the field definition and see if it's a list or single object

ast-grep --pattern 'health_metrics_latest'

Length of output: 161


Incorrect assertion of health_metrics_latest return type

The health_metrics_latest field is defined to return a single ProjectHealthMetricsNode (or null), not a list. The test should assert the field’s type directly, not its element type.

File: backend/tests/apps/owasp/graphql/nodes/project_test.py (lines 47–50)

-        assert field.type.of_type is ProjectHealthMetricsNode
+        assert field.type is ProjectHealthMetricsNode
📝 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
def test_resolve_health_metrics_latest(self):
field = self._get_field_by_name("health_metrics_latest")
assert field is not None
assert field.type.of_type is ProjectHealthMetricsNode
def test_resolve_health_metrics_latest(self):
field = self._get_field_by_name("health_metrics_latest")
assert field is not None
assert field.type is ProjectHealthMetricsNode
🤖 Prompt for AI Agents
In backend/tests/apps/owasp/graphql/nodes/project_test.py around lines 47 to 50,
the test incorrectly asserts that the health_metrics_latest field returns a list
by checking field.type.of_type. Instead, update the assertion to check
field.type directly against ProjectHealthMetricsNode, reflecting that the field
returns a single node or null, not a list.

Copy link
Collaborator

@kasya kasya left a comment

Choose a reason for hiding this comment

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

Some initial thoughts 👍🏼 ⬇️

'Days Since Last Commit',
'Days Since Last Release',
'Days Since Last Pull Request',
'Days Since OWASP Page Last Update',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we add a tooltip to this to show the full text when it gets truncated?
Screenshot 2025-07-18 at 5 16 41 PM

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This text is a part of the apexcharts Chart component. So, I don't have full control on it. Maybe it can be done, I will take a look.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ahmedxgouda Gotcha! I'll check that too! Thank you!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@kasya Didn't find a way, but a tooltip will show when the user hover on the bar itself.

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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e8400c4 and ac69330.

📒 Files selected for processing (6)
  • frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts (1 hunks)
  • frontend/__tests__/unit/data/mockProjectsDashboardMetricsDetailsData.ts (1 hunks)
  • frontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx (1 hunks)
  • frontend/src/components/GeneralCompliantComponent.tsx (1 hunks)
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • frontend/tests/unit/data/mockProjectsDashboardMetricsDetailsData.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/app/projects/dashboard/metrics/[projectKey]/page.tsx
  • frontend/src/components/GeneralCompliantComponent.tsx
  • frontend/src/server/queries/projectsHealthDashboardQueries.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts (3)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
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/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx (4)
Learnt from: ahmedxgouda
PR: OWASP/Nest#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: OWASP/Nest#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.
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.
Learnt from: ahmedxgouda
PR: OWASP/Nest#1703
File: frontend/src/components/BarChart.tsx:33-46
Timestamp: 2025-07-03T03:08:03.290Z
Learning: In the OWASP Nest project's BarChart component (frontend/src/components/BarChart.tsx), the days and requirements arrays are guaranteed to always have the same length in their use cases, so input validation for array length matching is not needed.
🧬 Code Graph Analysis (2)
frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts (1)
frontend/__tests__/unit/data/mockProjectsDashboardMetricsDetailsData.ts (1)
  • mockProjectsDashboardMetricsDetailsData (1-34)
frontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx (1)
frontend/__tests__/unit/data/mockProjectsDashboardMetricsDetailsData.ts (1)
  • mockProjectsDashboardMetricsDetailsData (1-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (5)
frontend/__tests__/e2e/pages/ProjectHealthDashboardMetricsDetails.spec.ts (1)

1-22: LGTM! Well-structured E2E test setup.

The test setup properly mocks GraphQL responses, sets required CSRF token, and navigates to the correct page. The mock data structure aligns with the expected API response format.

frontend/__tests__/unit/pages/ProjectHealthDashboardMetricsDetails.test.tsx (4)

6-27: Excellent mock setup for isolated unit testing.

The mocking strategy properly isolates the component under test by mocking external dependencies like ApexCharts, Apollo Client, Next.js navigation, and FontAwesome icons. This ensures the test focuses on the component's behavior rather than its dependencies.


45-69: Well-implemented loading and error state tests.

Both tests properly mock the Apollo Client's useQuery return values and verify the expected UI behavior for loading and error states. The use of waitFor ensures proper async handling of DOM updates.


86-88: LGTM! Synchronous forEach usage is acceptable here.

Unlike the E2E test, this forEach loop uses synchronous DOM queries within waitFor, which is perfectly acceptable. The screen.getByText() calls are synchronous operations that don't require individual awaiting.


32-43: Proper test lifecycle management.

Good practice using beforeEach to set up consistent mock state and afterEach to clear mocks, preventing test interference.

@ahmedxgouda ahmedxgouda marked this pull request as ready for review July 20, 2025 15:25
@ahmedxgouda ahmedxgouda requested a review from arkid15r as a code owner July 20, 2025 15:25
@ahmedxgouda ahmedxgouda requested a review from kasya July 20, 2025 15:26
Copy link
Collaborator

@kasya kasya left a comment

Choose a reason for hiding this comment

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

@ahmedxgouda I’ve pushed some updates to the Compliance badges styling. Hope that's ok with you.

This looks good for now as an MVP!
We’ll likely revisit this page later once I figure out a clearer way to highlight any missing requirements. The goal is to make it obvious to project admins which requirements are still unmet and how they impact the score, so they know what needs their attention.

Right now, I feel like only our Age BarChart communicates that somewhat clearly. I’ll need to spend a bit more time thinking about the best design approach for this.

If you have any ideas in the meantime, feel free to share too!

@sonarqubecloud
Copy link

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.

Implement the presentation of the project health metrics details

3 participants