Skip to content

Conversation

@ishanBahuguna
Copy link
Contributor

Proposed change

Resolves #2520

Tasks

  • Exclude valid JSX conditional rendering patterns (if not nested)
  • Refactor each nested ternary into independent statements
  • Use descriptive variable names for intermediate values
  • Update unit tests if necessary
  • Verify no breaking changes in functionality

Checklist

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

Summary by CodeRabbit

  • New Features

    • Added "Wall of Fame" label to the top contributors list on the about page.
  • Tests

    • Enhanced test coverage with additional unit tests for milestone progress utilities and alignment validation.
  • Refactor

    • Improved code clarity throughout the application by centralizing milestone progress display logic and simplifying conditional expressions.

Walkthrough

The PR refactors nested ternary operators and inline conditional logic into explicit intermediate variables, if/else statements, and IIFEs across multiple test and production files. A new milestoneProgress utility module is introduced with helper functions for determining milestone progress text and icons. The about page is updated to use this centralized utility instead of inline icon selection logic.

Changes

Cohort / File(s) Summary
Test mock refactorings
frontend/__tests__/unit/components/ModuleList.test.tsx, frontend/__tests__/unit/components/ProgramCard.test.tsx
Refactors FontAwesomeIcon mock components from inline ternary conditionals to explicit iconName variable initialization with if/else branches for improved readability; behavior and test outputs remain unchanged
New utility module and tests
frontend/src/utils/milestoneProgress.ts, frontend/__tests__/unit/utils/milestoneProgress.test.ts
Introduces milestoneProgress utility exporting getMilestoneProgressText() and getMilestoneProgressIcon() helpers that map numeric progress to display text and FontAwesome icons; includes comprehensive unit test coverage for all progress states
About page utility integration
frontend/src/app/about/page.tsx
Removes inline faUserGear icon logic and replaces with centralized milestoneProgress utility functions; adds "Wall of Fame" label prop to TopContributorsList component
Control flow refactorings
frontend/src/app/global-error.tsx, frontend/src/app/projects/dashboard/metrics/page.tsx, frontend/src/components/CardDetailsPage.tsx, frontend/src/components/ProgramCard.tsx, frontend/src/hooks/useSearchPage.ts
Extracts ternary operators and inline conditionals into explicit intermediate variables, IIFEs, or if/else statements (e.g., appError assignment, alignment classes, font icon selection, date formatting, index name computation); no behavior changes
New alignment test
frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx
Adds unit test verifying SortableColumnHeader applies correct justify-center and text-center classes to wrapper elements

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Milestone utility logic: Verify getMilestoneProgressText() and getMilestoneProgressIcon() correctly map all progress ranges (0, 1-99, 100) to expected text and icon values
  • About page integration: Confirm milestoneProgress utility is applied correctly in milestone rendering and TopContributorsList label addition does not break layout
  • Test mock refactorings: Verify the restructured conditional logic in test mocks still produces correct data-testid outputs and className assertions
  • Consistency check: Ensure all refactored variables (appError, alignmentClass, fontAwesomeIconType, etc.) maintain original behavior across their respective contexts

Possibly related PRs

  • Unify main page look #1227: Modifies FontAwesomeIcon mocks and icon handling in frontend components—related through shared changes to icon prop handling and mock structures
  • Adding icons for left headings  #1359: Refactors frontend/src/app/about/page.tsx to modify how milestone icons are displayed—directly overlaps with this PR's about page changes
  • UI/ux mentorship program update #2244: Modifies frontend/src/components/ProgramCard.tsx and related tests—directly affected by this PR's date formatting and test refactorings

Suggested reviewers

  • arkid15r
  • kasya

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.65% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: refactoring nested ternary operators into independent statements, which is the core objective of the PR.
Description check ✅ Passed The description is related to the changeset, clearly stating the PR resolves issue #2520 and detailing the tasks completed for refactoring nested ternary operators.
Linked Issues check ✅ Passed The PR successfully addresses all objectives from issue #2520: refactors nested ternaries into independent statements with descriptive variable names, excludes valid JSX patterns, updates unit tests, and maintains functionality without breaking changes.
Out of Scope Changes check ✅ Passed All changes are in-scope: refactoring nested ternaries into independent statements across test files, utility modules, and component files, plus adding the milestoneProgress utility module as required.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • 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

Comment @coderabbitai help to get the list of available commands and usage tips.

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 (3)
frontend/__tests__/unit/utils/milestoneProgress.test.ts (2)

11-13: Consider testing boundary values in the 1-99 range.

The test only checks the middle value (50). Consider adding tests for edge cases like 1 and 99 to ensure the boundary conditions work correctly. Also, since the backend returns decimal values (e.g., 50.5), consider testing a decimal input.

Example:

     test('returns "In Progress" when progress is between 1 and 99', () => {
+      expect(getMilestoneProgressText(1)).toBe('In Progress')
       expect(getMilestoneProgressText(50)).toBe('In Progress')
+      expect(getMilestoneProgressText(50.5)).toBe('In Progress')
+      expect(getMilestoneProgressText(99)).toBe('In Progress')
     })

25-27: Consider testing boundary values for icon selection.

Similar to the text tests, consider adding tests for edge cases like 1 and 99 to verify boundary behavior.

Example:

     test('returns faUserGear when progress is between 1 and 99', () => {
+      expect(getMilestoneProgressIcon(1)).toBe(faUserGear)
       expect(getMilestoneProgressIcon(50)).toBe(faUserGear)
+      expect(getMilestoneProgressIcon(99)).toBe(faUserGear)
     })
frontend/src/utils/milestoneProgress.ts (1)

13-21: Consider adding an explicit return type annotation.

The function successfully refactors the nested ternary into clear if-else logic. For better type safety and documentation, consider adding an explicit return type.

Example:

+import type { IconDefinition } from '@fortawesome/fontawesome-svg-core'
 import { faCircleCheck, faClock, faUserGear } from '@fortawesome/free-solid-svg-icons'
 
-export const getMilestoneProgressIcon = (progress: number) => {
+export const getMilestoneProgressIcon = (progress: number): IconDefinition => {
   if (progress === 100) {
     return faCircleCheck
   } else if (progress > 0) {
     return faUserGear
   } else {
     return faClock
   }
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f86ed08 and 623b972.

📒 Files selected for processing (11)
  • frontend/__tests__/unit/components/ModuleList.test.tsx (1 hunks)
  • frontend/__tests__/unit/components/ProgramCard.test.tsx (1 hunks)
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (2 hunks)
  • frontend/__tests__/unit/utils/milestoneProgress.test.ts (1 hunks)
  • frontend/src/app/about/page.tsx (2 hunks)
  • frontend/src/app/global-error.tsx (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (2 hunks)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
  • frontend/src/components/ProgramCard.tsx (2 hunks)
  • frontend/src/hooks/useSearchPage.ts (1 hunks)
  • frontend/src/utils/milestoneProgress.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-07-12T17:36:57.255Z
Learnt from: Rajgupta36
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx
  • frontend/__tests__/unit/components/ProgramCard.test.tsx
📚 Learning: 2025-09-17T02:42:41.928Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2288
File: frontend/src/components/ActionButton.tsx:0-0
Timestamp: 2025-09-17T02:42:41.928Z
Learning: In frontend/src/components/ActionButton.tsx, the user Rajgupta36 intentionally changed text-blue-600 to text-[#1D7BD7] to align the text color with the border color (#1D7BD7) for visual consistency, prioritizing design alignment over theme tokens.

Applied to files:

  • frontend/__tests__/unit/components/ProgramCard.test.tsx
  • frontend/src/app/projects/dashboard/metrics/page.tsx
📚 Learning: 2025-07-09T08:37:10.241Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.

Applied to files:

  • frontend/src/app/projects/dashboard/metrics/page.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
🧬 Code graph analysis (5)
frontend/src/components/ProgramCard.tsx (1)
frontend/src/utils/dateFormatter.ts (1)
  • formatDate (1-20)
frontend/src/hooks/useSearchPage.ts (1)
frontend/src/server/fetchAlgoliaData.ts (1)
  • fetchAlgoliaData (6-59)
frontend/__tests__/unit/utils/milestoneProgress.test.ts (1)
frontend/src/utils/milestoneProgress.ts (2)
  • getMilestoneProgressText (3-11)
  • getMilestoneProgressIcon (13-21)
frontend/src/utils/milestoneProgress.ts (1)
backend/apps/github/api/internal/nodes/milestone.py (1)
  • progress (40-45)
frontend/src/app/about/page.tsx (1)
frontend/src/utils/milestoneProgress.ts (2)
  • getMilestoneProgressText (3-11)
  • getMilestoneProgressIcon (13-21)
🔇 Additional comments (10)
frontend/__tests__/unit/components/ProgramCard.test.tsx (1)

9-21: LGTM! Clean refactor of test mock.

The refactor from inline ternary to explicit if-else branches with an intermediate iconName variable improves readability and maintainability while preserving the same test behavior.

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

34-42: LGTM! Excellent refactor of date display logic.

The dateInfo IIFE elegantly extracts the date rendering logic into a descriptive variable with clear conditional branches. This significantly improves readability compared to inline conditionals.

frontend/src/app/projects/dashboard/metrics/page.tsx (1)

80-108: LGTM! Well-structured refactor with clear separation of concerns.

The three IIFEs (alignmentClass, textAlignClass, fontAwesomeIconType) effectively replace nested ternaries with explicit conditional logic. Each IIFE handles a single responsibility, making the code more maintainable and testable.

frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1)

151-161: LGTM! Good test coverage for refactored alignment logic.

This test validates that the refactored alignmentClass and textAlignClass IIFEs produce the correct CSS classes, helping prevent regressions.

frontend/src/app/global-error.tsx (1)

66-74: LGTM! Clear refactor of error handling logic.

The explicit if-else structure with the intermediate appError variable improves readability while preserving the original error handling behavior.

frontend/__tests__/unit/components/ModuleList.test.tsx (1)

8-18: LGTM! Consistent test mock refactor.

The refactor follows the same pattern as other test files in this PR, using explicit if-else branches with an intermediate variable to improve readability.

frontend/src/hooks/useSearchPage.ts (1)

85-95: LGTM! Clean extraction of index name computation.

The computedIndexName variable with the intermediate hasValidSort check effectively replaces inline logic, making the Algolia index name construction explicit and easier to understand.

frontend/src/utils/milestoneProgress.ts (1)

3-11: Excellent refactoring from nested ternary to clear if-else chain.

The function successfully eliminates nested ternary operators and uses a clear, readable if-else structure. The logic correctly handles all progress states including decimal values from the backend.

frontend/src/app/about/page.tsx (2)

36-36: Clean import addition for centralized milestone utilities.

The import correctly brings in the new utility functions, successfully centralizing milestone progress logic and eliminating the need for inline nested ternaries.


221-228: Successfully refactored nested ternaries with utility function calls.

The inline nested ternary operators have been cleanly replaced with calls to the centralized utility functions. This significantly improves readability and maintainability while achieving the PR's objective of eliminating nested ternaries per SonarQube rule S3358.

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

♻️ Duplicate comments (1)
frontend/src/components/CardDetailsPage.tsx (1)

78-78: Inconsistent equality operator.

Line 78 uses loose equality (==) for the module check while using strict equality (===) for the program check. For consistency and to follow TypeScript best practices, use strict equality throughout.

Apply this diff:

-    if (type === 'program' || type == 'module') {
+    if (type === 'program' || type === 'module') {
🧹 Nitpick comments (1)
frontend/src/components/CardDetailsPage.tsx (1)

77-85: Consider a more idiomatic pattern for the conditional logic.

While the IIFE pattern works correctly, a simpler approach using let with if-else statements is more conventional in modern React/TypeScript and avoids the function invocation overhead.

Apply this diff for a more straightforward implementation:

-  const secondaryCardStyles = (() => {
-    if (type === 'program' || type === 'module') {
-      return 'gap-2 md:col-span-7'
-    } else if (type !== 'chapter') {
-      return 'gap-2 md:col-span-5'
-    } else {
-      return 'gap-2 md:col-span-3'
-    }
-  })()
+  let secondaryCardStyles: string
+  if (type === 'program' || type === 'module') {
+    secondaryCardStyles = 'gap-2 md:col-span-7'
+  } else if (type !== 'chapter') {
+    secondaryCardStyles = 'gap-2 md:col-span-5'
+  } else {
+    secondaryCardStyles = 'gap-2 md:col-span-3'
+  }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 623b972 and 7e3e84f.

📒 Files selected for processing (1)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-09-29T06:02:35.566Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/components/SingleModuleCard.tsx:54-54
Timestamp: 2025-09-29T06:02:35.566Z
Learning: In the Module type from types/mentorship.ts, the experienceLevel field is required (experienceLevel: ExperienceLevelEnum), not optional, so null/undefined checks are not needed when accessing this field.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx

@ishanBahuguna
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e3e84f and d7919b8.

📒 Files selected for processing (1)
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-09T08:37:10.241Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.

Applied to files:

  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx

@ishanBahuguna
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

🧹 Nitpick comments (1)
frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1)

151-162: Test correctly verifies alignment classes after addressing null check.

The null check on line 157 addresses the primary concern from the previous review. The test now properly guards against unclear failures when closest('div') doesn't find a match.

One minor TypeScript note: Jest's expect().not.toBeNull() doesn't narrow the type, so wrapperDiv is technically still Element | null on lines 160-161. If you want stricter type safety, you could add a non-null assertion (wrapperDiv!) or wrap the subsequent assertions in an if (wrapperDiv) block. However, this is optional—the test will fail clearly at line 157 if wrapperDiv is null, and your assertion likely handles the type just fine.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7919b8 and 946f8b4.

📒 Files selected for processing (1)
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-09T08:37:10.241Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.

Applied to files:

  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx

@ishanBahuguna
Copy link
Contributor Author

@coderabbitai generate docstrings

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

✅ Actions performed

Initiated docstring generation; will generate only if new commits exist.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 2, 2025

Note

Docstrings generation - SUCCESS
Generated docstrings for this pull request at #2534

coderabbitai bot added a commit that referenced this pull request Nov 2, 2025
Docstrings generation was requested by @ishanBahuguna.

* #2532 (comment)

The following files were modified:

* `frontend/src/hooks/useSearchPage.ts`
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: 0

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

77-86: Great refactoring—nested ternary successfully eliminated!

The if-else structure is clear, readable, and uses strict equality consistently throughout. The descriptive variable name makes the intent obvious.

Optional: Consider simplifying the IIFE pattern.

While the IIFE works correctly, a simpler pattern might be more idiomatic for React components:

// Option 1: Helper function
const getSecondaryCardStyles = () => {
  if (type === 'program' || type === 'module') {
    return 'gap-2 md:col-span-7'
  } else if (type !== 'chapter') {
    return 'gap-2 md:col-span-5'
  } else {
    return 'gap-2 md:col-span-3'
  }
}
const secondaryCardStyles = getSecondaryCardStyles()
// Option 2: Let assignment (if reassignment isn't needed, const is fine)
let secondaryCardStyles = 'gap-2 md:col-span-3'
if (type === 'program' || type === 'module') {
  secondaryCardStyles = 'gap-2 md:col-span-7'
} else if (type !== 'chapter') {
  secondaryCardStyles = 'gap-2 md:col-span-5'
}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 946f8b4 and ad0edeb.

📒 Files selected for processing (4)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
  • frontend/src/components/ProgramCard.tsx (2 hunks)
  • frontend/src/hooks/useSearchPage.ts (1 hunks)
  • frontend/src/utils/milestoneProgress.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/src/hooks/useSearchPage.ts
  • frontend/src/components/ProgramCard.tsx
  • frontend/src/utils/milestoneProgress.ts
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-06-20T16:12:59.256Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest 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.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
📚 Learning: 2025-07-12T17:14:28.536Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/mentorship/programs/[programKey]/edit/page.tsx:90-128
Timestamp: 2025-07-12T17:14:28.536Z
Learning: Both ProgramForm (programCard.tsx) and ModuleForm (mainmoduleCard.tsx) components already implement HTML validation using the `required` attribute on form fields. The browser's native validation prevents form submission and displays error messages when required fields are empty, eliminating the need for additional JavaScript validation before GraphQL mutations.

Applied to files:

  • frontend/src/components/CardDetailsPage.tsx
🔇 Additional comments (1)
frontend/src/components/CardDetailsPage.tsx (1)

137-137: LGTM!

Clean and straightforward usage of the extracted constant.

@ishanBahuguna
Copy link
Contributor Author

@kasya @arkid15r by mistake I generated the Docstring kindly close that PR and sorry for the inconvenience

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.

@ishanBahuguna Thanks for working on this!
I posted one suggestion below ⬇️

Could you also run make check-test locally and address found issues? Thanks!

Comment on lines 78 to 85
const secondaryCardStyles = (() => {
if (type === 'program' || type === 'module') {
return 'gap-2 md:col-span-7'
} else if (type !== 'chapter') {
return 'gap-2 md:col-span-5'
} else {
return 'gap-2 md:col-span-3'
}
})()
Copy link
Collaborator

@kasya kasya Nov 6, 2025

Choose a reason for hiding this comment

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

Let's not introduce negated conditions. This is also one of the issues we happen to have quite a few of in SonarQube and something that makes the code less readable.

Suggested change
const secondaryCardStyles = (() => {
if (type === 'program' || type === 'module') {
return 'gap-2 md:col-span-7'
} else if (type !== 'chapter') {
return 'gap-2 md:col-span-5'
} else {
return 'gap-2 md:col-span-3'
}
})()
const secondaryCardStyles = (() => {
if (type === 'program' || type === 'module') {
return 'gap-2 md:col-span-7'
}
if (type === 'chapter') {
return 'gap-2 md:col-span-3'
}
return 'gap-2 md:col-span-5'
})()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kasya I'have updated the code as you have suggested.

The issue you are talking about is the one which is failing CI/CD ?
or I have to fix something else

Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks! I don't think this was falling CI/CD check. There was a different issue with parseNumber that we now enforce with CI/CD - maybe that was failing. It's all good now 👌🏼

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

🧹 Nitpick comments (1)
frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1)

151-158: Consider testing multiple alignment cases.

The test correctly verifies that the refactored alignment logic produces the expected CSS classes for the center-aligned "Stars" column. However, if the MetricsPage includes columns with different alignment values (e.g., align="left" or align="right"), testing those cases would provide more comprehensive coverage of the refactored ternary logic.

You could extend this test or add a parameterized test covering different columns:

  test('SortableColumnHeader applies correct alignment classes', async () => {
    render(<MetricsPage />)
+   
+   // Test center alignment
    const sortButton = await screen.findByTitle('Sort by Stars')
    const wrapperDiv = sortButton.closest('div')
    expect(wrapperDiv).not.toBeNull()
    expect(wrapperDiv).toHaveClass('justify-center')
    expect(sortButton).toHaveClass('text-center')
+   
+   // Test left alignment (if applicable)
+   const leftAlignButton = await screen.findByTitle('Sort by Forks')
+   const leftWrapper = leftAlignButton.closest('div')
+   expect(leftWrapper).not.toBeNull()
+   expect(leftWrapper).toHaveClass('justify-start')
+   expect(leftAlignButton).toHaveClass('text-left')
  })

Note: Only add additional assertions if other columns actually use different alignment values.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad0edeb and 6d4e998.

📒 Files selected for processing (3)
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1 hunks)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
  • frontend/src/hooks/useSearchPage.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/hooks/useSearchPage.ts
  • frontend/src/components/CardDetailsPage.tsx

@ishanBahuguna ishanBahuguna requested a review from kasya November 7, 2025 05:57
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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d4e998 and 76e3de8.

📒 Files selected for processing (3)
  • frontend/src/app/about/page.tsx (2 hunks)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
  • frontend/src/hooks/useSearchPage.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/app/about/page.tsx
  • frontend/src/components/CardDetailsPage.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
frontend/src/hooks/useSearchPage.ts (1)
frontend/src/server/fetchAlgoliaData.ts (1)
  • fetchAlgoliaData (6-59)
⏰ 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)
🔇 Additional comments (1)
frontend/src/hooks/useSearchPage.ts (1)

99-99: LGTM - correct usage of computed index name.

The change correctly uses computedIndexName instead of the direct indexName, enabling dynamic index selection based on sorting state as intended by the refactoring.

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

🧹 Nitpick comments (8)
frontend/src/hooks/useSearchPage.ts (3)

71-73: Remove redundant empty string check.

The condition sortBy !== '' is redundant because sortBy is already checked for truthiness. An empty string is falsy, so if sortBy is truthy, it cannot be an empty string.

Apply this diff:

-    if (sortBy && sortBy !== 'default' && sortBy !== '') {
+    if (sortBy && sortBy !== 'default') {
       params.set('sortBy', sortBy)
     }

75-77: Remove redundant empty string check.

The condition order !== '' is redundant because order is already checked for truthiness. An empty string is falsy, so if order is truthy, it cannot be an empty string.

Apply this diff:

-    if (sortBy !== 'default' && order && order !== '') {
+    if (sortBy !== 'default' && order) {
       params.set('order', order)
     }

87-96: Good refactoring! Minor comment formatting and redundant check to address.

The refactoring from nested ternary to explicit statements successfully achieves the PR objective and improves readability. The critical bug (sortBy[0] !== 'default') identified in the previous review has been correctly addressed and removed.

Minor improvements needed:

  • Line 89: Add period at end of comment: "Check if valid sort option is selected."
  • Line 93: Capitalize and fix grammar: "If sorting is active then append the sort field and order to the base index name."
  • Line 94: Remove redundant order !== '' check (similar to the issues at lines 71 and 75)

Apply this diff:

-        // Check if valid sort option is selected
+        // Check if valid sort option is selected.
         const hasValidSort = sortBy && sortBy !== 'default'
 
         if (hasValidSort) {
-          // if sorting is active then appends the sort field and order to the base index name.
-          const orderSuffix = order && order !== '' ? `_${order}` : ''
+          // If sorting is active then append the sort field and order to the base index name.
+          const orderSuffix = order ? `_${order}` : ''
           computedIndexName = `${indexName}_${sortBy}${orderSuffix}`
         }
backend/apps/owasp/models/snapshot.py (1)

42-65: Count properties align with API needs; be mindful of potential query overhead

The new new_*_count properties are clear and line up with the snapshot detail schema. Each call issues a .count() on the related manager, which is fine for single‑snapshot detail usage, but if you ever consume these in bulk (e.g., iterating many snapshots), consider aggregations or prefetching to avoid N extra queries.

backend/tests/apps/api/rest/v0/snapshot_test.py (1)

72-262: API tests cover main branches; consider adding list/ordering and stronger resolver assertions

The RequestFactory + MagicMock strategy exercises both 404 and success paths for each endpoint, which is solid. Two optional improvements you might consider:

  • Add tests for list_snapshots (and, if not covered elsewhere, explicit ordering values) to guard the main listing endpoint and ordering behavior.
  • The test_list_snapshot_issues_no_repository / test_list_snapshot_releases_no_repository names suggest resolver behavior, but they currently only assert that the returned list contains the mock object. If you want these to cover the “no repository” semantics, you could either:
    • Assert via SnapshotIssue / SnapshotRelease schemas (e.g., checking organization_login/repository_name), or
    • Rely solely on the dedicated resolver tests at the bottom and rename/remove the “no_repository” tests to avoid redundancy.
backend/apps/api/rest/v0/snapshot.py (3)

29-94: Snapshot schemas and resolvers look consistent with the underlying models

SnapshotBase / SnapshotDetail mirror SnapshotModel’s fields and new_*_count properties, and SnapshotIssue / SnapshotRelease correctly derive organization_login and repository_name from the related repository/organization. This aligns with the dedicated resolver tests in snapshot_test.py and keeps the API shape predictable.

You could factor the repository/organization-to-login/name logic into a small helper (or mixin) shared between SnapshotIssue and SnapshotRelease to avoid duplication, but that’s purely a style choice here.


126-147: Clarify get_snapshot return style vs annotated SnapshotDetail | SnapshotError

The success branch currently returns a SnapshotModel instance while the type annotation and response mapping declare SnapshotDetail. Django Ninja will typically coerce ORM objects to the declared schema, but static type-checkers and readers may find this slightly misleading.

If you want the code to mirror the type hint more closely, consider either:

  • Explicitly constructing the schema (e.g., mapping fields or using from_orm/from_attributes if configured), or
  • Adjusting the annotation/comment to make it clear that Ninja performs the model→schema conversion at the framework layer.

Functionally this is fine; this is about readability and type clarity.


150-276: Snapshot lookup pattern is clear but repeated across endpoints

Each list endpoint repeats:

snapshot = SnapshotModel.objects.filter(
    key__iexact=snapshot_id, status=SnapshotModel.Status.COMPLETED
).first()

followed by either returning related objects or an .objects.none() queryset. This is easy to follow, but you might consider a small helper like get_completed_snapshot(snapshot_id: str) -> SnapshotModel | None to centralize the lookup and make future changes (e.g., additional filters) less error-prone.

Not urgent, but a modest readability/maintainability win.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76e3de8 and 1c4e3f3.

⛔ Files ignored due to path filters (1)
  • frontend/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • backend/apps/api/rest/v0/__init__.py (2 hunks)
  • backend/apps/api/rest/v0/snapshot.py (1 hunks)
  • backend/apps/owasp/models/snapshot.py (1 hunks)
  • backend/tests/apps/api/rest/v0/snapshot_test.py (1 hunks)
  • backend/tests/apps/api/rest/v0/urls_test.py (2 hunks)
  • frontend/.pnpmrc (0 hunks)
  • frontend/__tests__/unit/pages/About.test.tsx (1 hunks)
  • frontend/next.config.ts (1 hunks)
  • frontend/package.json (0 hunks)
  • frontend/src/app/about/page.tsx (3 hunks)
  • frontend/src/hooks/useSearchPage.ts (2 hunks)
💤 Files with no reviewable changes (2)
  • frontend/package.json
  • frontend/.pnpmrc
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-17T02:42:41.928Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 2288
File: frontend/src/components/ActionButton.tsx:0-0
Timestamp: 2025-09-17T02:42:41.928Z
Learning: In frontend/src/components/ActionButton.tsx, the user Rajgupta36 intentionally changed text-blue-600 to text-[#1D7BD7] to align the text color with the border color (#1D7BD7) for visual consistency, prioritizing design alignment over theme tokens.

Applied to files:

  • frontend/src/app/about/page.tsx
🧬 Code graph analysis (7)
backend/apps/owasp/models/snapshot.py (1)
backend/apps/owasp/api/internal/nodes/snapshot.py (5)
  • new_chapters (35-37)
  • new_issues (40-42)
  • new_projects (45-47)
  • new_releases (50-52)
  • new_users (55-57)
backend/tests/apps/api/rest/v0/urls_test.py (1)
backend/apps/owasp/api/internal/queries/snapshot.py (1)
  • snapshot (14-22)
backend/apps/api/rest/v0/snapshot.py (3)
backend/apps/api/decorators/cache.py (1)
  • cache_response (19-56)
backend/apps/owasp/models/snapshot.py (7)
  • Snapshot (7-72)
  • new_chapters_count (43-45)
  • new_issues_count (48-50)
  • new_projects_count (53-55)
  • new_releases_count (58-60)
  • new_users_count (63-65)
  • Status (14-18)
backend/apps/owasp/api/internal/nodes/snapshot.py (5)
  • new_chapters (35-37)
  • new_issues (40-42)
  • new_users (55-57)
  • new_projects (45-47)
  • new_releases (50-52)
backend/tests/apps/api/rest/v0/snapshot_test.py (2)
backend/apps/api/rest/v0/snapshot.py (14)
  • SnapshotDetail (44-51)
  • get_snapshot (137-147)
  • list_snapshot_chapters (158-172)
  • list_snapshot_issues (183-199)
  • list_snapshot_members (210-224)
  • list_snapshot_projects (235-249)
  • list_snapshot_releases (260-276)
  • Snapshot (40-41)
  • SnapshotIssue (54-72)
  • resolve_organization_login (61-67)
  • resolve_organization_login (82-88)
  • resolve_repository_name (70-72)
  • resolve_repository_name (91-93)
  • SnapshotRelease (75-93)
backend/apps/owasp/models/snapshot.py (7)
  • Snapshot (7-72)
  • new_chapters_count (43-45)
  • new_issues_count (48-50)
  • new_projects_count (53-55)
  • new_releases_count (58-60)
  • new_users_count (63-65)
  • Status (14-18)
frontend/src/hooks/useSearchPage.ts (1)
frontend/src/server/fetchAlgoliaData.ts (1)
  • fetchAlgoliaData (6-59)
backend/apps/api/rest/v0/__init__.py (1)
backend/apps/owasp/api/internal/queries/snapshot.py (1)
  • snapshot (14-22)
frontend/src/app/about/page.tsx (1)
frontend/src/utils/milestoneProgress.ts (2)
  • getMilestoneProgressText (4-12)
  • getMilestoneProgressIcon (14-22)
🔇 Additional comments (7)
frontend/next.config.ts (1)

34-34: Verify scope of this change and confirm intentionality.

Verification shows that 'require-in-the-middle' is only a transitive dependency in the lockfile and is not directly imported or used anywhere in the codebase, so removing it from serverExternalPackages is functionally safe. However, this change remains inconsistent with the stated PR objectives of refactoring nested ternary operators.

Please confirm whether this dependency cleanup is an intentional scope expansion for this PR, or if it should be deferred to a separate PR focused on dependency management.

frontend/src/app/about/page.tsx (2)

36-36: Excellent refactoring to extract milestone logic into utility functions!

The extraction of milestone progress text and icon logic into dedicated utility functions (getMilestoneProgressText and getMilestoneProgressIcon) successfully eliminates nested ternaries from the component, improving readability and maintainability. This aligns perfectly with the PR objectives.

Also applies to: 225-225, 232-232


150-150: LGTM! Label change is properly tested.

The label change to "Wall of Fame" for the top contributors section is appropriately reflected in the test expectations.

frontend/__tests__/unit/pages/About.test.tsx (1)

221-221: LGTM! Test updated to match production code.

The test expectation correctly reflects the label change to "Wall of Fame" in the About page component.

backend/tests/apps/api/rest/v0/urls_test.py (1)

15-15: Snapshot router test wiring looks correct

Importing snapshot_router and adding "/snapshots": snapshot_router to EXPECTED_ROUTERS matches the v0 router configuration and ensures the new snapshot router registration is covered by tests.

Also applies to: 34-35

backend/apps/api/rest/v0/__init__.py (1)

19-19: Consistent registration of /snapshots router

Including snapshot_router in ROUTERS under the "/snapshots" prefix is consistent with other resources and aligns with the updated urls_test.py.

Also applies to: 33-35

backend/tests/apps/api/rest/v0/snapshot_test.py (1)

24-69: SnapshotDetail schema test is well-aligned with the schema/model fields

The parametrized coverage for timestamps and all new_*_count fields matches SnapshotDetail/SnapshotModel and should catch schema drift early. Looks good as-is.

@ishanBahuguna ishanBahuguna force-pushed the feature/refactor-nested-ternary-operators branch from 1c4e3f3 to 3f693ab Compare November 14, 2025 16:53
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: 0

🧹 Nitpick comments (2)
frontend/__tests__/unit/utils/milestoneProgress.test.ts (2)

11-13: Test boundary values 1 and 99.

The test uses 50 as a representative value for the "In Progress" range (1–99), but explicitly testing the boundaries 1 and 99 would strengthen confidence that the progress > 0 and progress < 100 conditions work correctly.

Add tests for boundary values:

    test('returns "In Progress" when progress is between 1 and 99', () => {
+     expect(getMilestoneProgressText(1)).toBe('In Progress')
      expect(getMilestoneProgressText(50)).toBe('In Progress')
+     expect(getMilestoneProgressText(99)).toBe('In Progress')
    })

Apply the same pattern to getMilestoneProgressIcon tests (lines 25–27).


5-32: Consider testing invalid inputs to document expected behavior.

The utility functions lack input validation, so invalid values (negative numbers, > 100, NaN, null, undefined) will fall through to the else branch, returning "Not Started" / faClock. Adding tests for these cases would document this behavior and catch future regressions if validation is added.

Example tests for edge cases:

describe('getMilestoneProgressText edge cases', () => {
  test('returns "Not Started" for negative progress', () => {
    expect(getMilestoneProgressText(-10)).toBe('Not Started')
  })

  test('returns "Completed" for progress > 100', () => {
    // or document if this should be clamped or throw
    expect(getMilestoneProgressText(150)).toBe('Completed')
  })
})

If invalid inputs should be rejected, consider adding validation to the utility functions and updating tests accordingly.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1c4e3f3 and 3f693ab.

📒 Files selected for processing (11)
  • frontend/__tests__/unit/components/ModuleList.test.tsx (1 hunks)
  • frontend/__tests__/unit/components/ProgramCard.test.tsx (1 hunks)
  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1 hunks)
  • frontend/__tests__/unit/utils/milestoneProgress.test.ts (1 hunks)
  • frontend/src/app/about/page.tsx (2 hunks)
  • frontend/src/app/global-error.tsx (1 hunks)
  • frontend/src/app/projects/dashboard/metrics/page.tsx (2 hunks)
  • frontend/src/components/CardDetailsPage.tsx (2 hunks)
  • frontend/src/components/ProgramCard.tsx (2 hunks)
  • frontend/src/hooks/useSearchPage.ts (2 hunks)
  • frontend/src/utils/milestoneProgress.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • frontend/src/components/CardDetailsPage.tsx
  • frontend/src/components/ProgramCard.tsx
  • frontend/src/app/projects/dashboard/metrics/page.tsx
  • frontend/src/utils/milestoneProgress.ts
  • frontend/tests/unit/components/ModuleList.test.tsx
  • frontend/src/app/global-error.tsx
  • frontend/src/hooks/useSearchPage.ts
  • frontend/tests/unit/components/ProgramCard.test.tsx
  • frontend/src/app/about/page.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-09T08:37:10.241Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1718
File: frontend/src/app/projects/dashboard/metrics/page.tsx:96-96
Timestamp: 2025-07-09T08:37:10.241Z
Learning: In the OWASP Nest project's MetricsPage component (frontend/src/app/projects/dashboard/metrics/page.tsx), the sorting dropdown intentionally uses selectionMode="multiple" to allow users to select multiple sorting criteria simultaneously. This enables complex sorting scenarios where users can sort by multiple fields in sequence.

Applied to files:

  • frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx
🧬 Code graph analysis (1)
frontend/__tests__/unit/utils/milestoneProgress.test.ts (1)
frontend/src/utils/milestoneProgress.ts (2)
  • getMilestoneProgressText (4-12)
  • getMilestoneProgressIcon (14-22)
🔇 Additional comments (1)
frontend/__tests__/unit/pages/ProjectsHealthDashboardMetrics.test.tsx (1)

151-158: Test correctly verifies alignment refactoring.

The test appropriately validates that the alignment classes are applied correctly after refactoring nested ternaries. The null check addresses the previous review feedback, making failure messages clear if the DOM structure changes.

@sonarqubecloud
Copy link

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.

This is great! One tiny request!

Comment on lines +80 to +98
const alignmentClass = (() => {
if (align === 'center') {
return 'justify-center'
} else if (align === 'right') {
return 'justify-end'
} else {
return 'justify-start'
}
})()

const textAlignClass = (() => {
if (align === 'center') {
return 'text-center'
} else if (align === 'right') {
return 'text-right'
} else {
return 'text-left'
}
})()
Copy link
Collaborator

Choose a reason for hiding this comment

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

@ishanBahuguna I think this would be more clean and readable if we switch to using maps here. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Map would be great , more readable code , avoid repeated if/else logic and easier to extend

 const justifyMap = {
  left: 'justify-start',
  center: 'justify-center',
  right: 'justify-end',
}
const alignmentClass = justifyMap[align] || justifyMap.left

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kasya should I go ahead and make the changes?

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.

Refactor nested ternary operators into independent statements

2 participants