Skip to content

E2e/merge update 1#3151

Merged
arkid15r merged 18 commits intofeature/e2e-backendfrom
e2e/merge-update-1
Jan 2, 2026
Merged

E2e/merge update 1#3151
arkid15r merged 18 commits intofeature/e2e-backendfrom
e2e/merge-update-1

Conversation

@arkid15r
Copy link
Collaborator

@arkid15r arkid15r commented Jan 2, 2026

No description provided.

saichethana28 and others added 18 commits December 29, 2025 20:46
Bumps [strawberry-graphql-django](https://github.com/strawberry-graphql/strawberry-django) from 0.71.0 to 0.72.0.
- [Release notes](https://github.com/strawberry-graphql/strawberry-django/releases)
- [Changelog](https://github.com/strawberry-graphql/strawberry-django/blob/main/CHANGELOG.md)
- [Commits](strawberry-graphql/strawberry-django@v0.71.0...v0.72.0)

---
updated-dependencies:
- dependency-name: strawberry-graphql-django
  dependency-version: 0.72.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Add keyboard navigation support to various components

* Refactor ActionButton to utilize onKeyDown prop for keyboard navigation support

* Update code

* Add stopPropagation()

* Make check update

---------

Co-authored-by: Kate <kate@kgthreads.com>
…test class (#3036)

* remove unused function parameter from save method in test class

* Update code

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
Bumps [pymdown-extensions](https://github.com/facelessuser/pymdown-extensions) from 10.19.1 to 10.20.
- [Release notes](https://github.com/facelessuser/pymdown-extensions/releases)
- [Commits](facelessuser/pymdown-extensions@10.19.1...10.20)

---
updated-dependencies:
- dependency-name: pymdown-extensions
  dependency-version: '10.20'
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Fix race condition in About page and update unit tests

* Update code

---------

Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
* Remove unnecessary zero-fraction literals

* refactoring barchat tests : use dataset instead of getAttributes

---------

Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
…3106)

* fix(ui): unify badge shapes by replacing icon background with css circle

* Update code after make-check

---------

Co-authored-by: Kate <kate@kgthreads.com>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
* fix: incorrect Error syntax

* fix: unhandled promise rejection in ModuleForm

* improve error message in ModuleForm

* fix: fix syntax error in ModuleForm

* fix: improve error messages in route.ts

---------

Co-authored-by: Kate Golovanova <kate@kgthreads.com>
* Removed nested ternary

* fixed coderabbit review

* fixed soanrqube warning

* fixed warning

* Added check

* Fixed review

* Fixed sonarqube warning
* Prefer tag over ARIA role

* updated aria

* Run check command

---------

Co-authored-by: anurag2787 <anurag2787@gmail.com>
* Refactor snapshot API to remove duplicated ordering description

Signed-off-by: Tejas Tiwari <tt160705@outlook.com>

* Update code

---------

Signed-off-by: Tejas Tiwari <tt160705@outlook.com>
Co-authored-by: Arkadii Yakovets <arkadii.yakovets@owasp.org>
…s null (#3084)

* fix(board): render error state instead of infinite loader when data is null

* Address make-check

---------

Co-authored-by: Kate <kate@kgthreads.com>
Co-authored-by: Arkadii Yakovets <2201626+arkid15r@users.noreply.github.com>
@github-actions github-actions bot added docs Improvements or additions to documentation backend frontend backend-tests frontend-tests labels Jan 2, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Summary by CodeRabbit

  • New Features

    • Added keyboard navigation (Enter/Space keys) to interactive components for improved accessibility.
    • Enhanced accessibility attributes with improved ARIA labels and loading state indicators.
  • Bug Fixes

    • Fixed accessibility attribute error and improved modal rendering with native dialog elements.
    • Enhanced error messages with additional context for better debugging.
  • Documentation

    • Simplified environment setup instructions.
    • Clarified API key configuration guidance.
  • Chores

    • Updated dependencies across backend and frontend projects.
    • Code refactoring for improved maintainability and consistency.
  • Tests

    • Updated test implementations to reflect component structural changes.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

This PR introduces a broad set of updates spanning documentation, configuration, and frontend/backend code. Changes include environment setup documentation refinements, dependency version bumps, keyboard accessibility enhancements across frontend components, state management refactoring, test mock structural adjustments, backend constant extraction, and minor API improvements. No breaking changes to exported entities.

Changes

Cohort / File(s) Summary
Documentation & Configuration
CONTRIBUTING.md, docs/pyproject.toml, frontend/package.json, backend/pyproject.toml
Updated environment setup instructions to use file copying from templates; refined Algolia onboarding narrative; bumped devDependencies (@swc/core, @typescript-eslint/\*, eslint-plugin-jest) and pymdown-extensions.
Backend Utilities
backend/apps/api/rest/v0/snapshot.py
Extracted "Ordering field" description into module constant ORDERING_FIELD_DESCRIPTION and applied to six endpoint parameter descriptions.
Backend Models & Tests
backend/apps/owasp/models/common.py, backend/tests/apps/common/management/commands/add_project_custom_tags_test.py
Simplified regex pattern in get_metadata for YAML extraction; added inline NOSONAR comment to test mock method.
Frontend Test Mocks: Component Structure
frontend/__tests__/unit/components/CardDetailsPage.test.tsx, frontend/__tests__/unit/components/ProjectsDashboardDropDown.test.tsx, frontend/__tests__/unit/pages/ApiKeysPage.test.tsx, frontend/__tests__/unit/pages/Home.test.tsx
Updated MetricsScoreCircle mock to conditionally render button vs div based on clickable prop; changed DropdownSection from div to fieldset/legend; replaced Modal div with native dialog element.
Frontend Test Mocks: Query & Detection
frontend/__tests__/unit/components/GeneralCompliantComponent.test.tsx, frontend/__tests__/unit/components/Pagination.test.tsx, frontend/__tests__/unit/components/BarChart.test.tsx, frontend/__tests__/unit/pages/About.test.tsx
Refactored tests to verify color classes instead of SVG icons for GeneralCompliantComponent; updated ellipsis detection to DOM structure filtering; changed test expectations from 100.0 to 100; refined GraphQL query mock responses to differentiate document types.
Frontend State Management
frontend/src/app/about/page.tsx, frontend/src/app/board/[year]/candidates/page.tsx
Removed local useState for projectMetadata/topContributors in about page, deriving directly from GraphQL responses; replaced manual isLoading state with Apollo's loading flag in candidates page.
Frontend Page Components
frontend/src/app/api/auth/[...nextauth]/route.ts, frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx, frontend/src/app/settings/api-keys/page.tsx
Enhanced error messages in auth route catch blocks; refactored issue page with extracted helpers (getPRStatus, getAssignButtonTitle, issueStatusClass/Label); introduced structured UI state handling (ErrorState, EmptyState, ApiKeysTable) in API keys page.
Frontend Components: Keyboard Accessibility
frontend/src/components/ActionButton.tsx, frontend/src/components/Card.tsx, frontend/src/components/ModuleCard.tsx, frontend/src/components/MultiSearch.tsx, frontend/src/components/Release.tsx, frontend/src/components/RepositoryCard.tsx, frontend/src/components/Search.tsx, frontend/src/components/ShowMoreButton.tsx, frontend/src/components/SortBy.tsx, frontend/src/components/ToggleableList.tsx, frontend/src/components/ModuleForm.tsx
Added onKeyDown handlers enabling activation on Enter or Space across multiple components; added focus styling improvements; enhanced error handling in ModuleForm.
Frontend Components: Structural & Rendering
frontend/src/components/GeneralCompliantComponent.tsx, frontend/src/components/Pagination.tsx
Simplified GeneralCompliantComponent to single circular container with dynamic colors instead of two-icon structure; changed Pagination ellipsis from span to div with adjusted accessibility attributes.
Frontend Accessibility Enhancements
frontend/src/components/skeletons/Card.tsx, frontend/src/components/skeletons/UserCard.tsx
Added aria-live, aria-busy, and aria-label attributes to loading skeleton containers.
Frontend Type Definitions
frontend/src/types/button.ts
Introduced onkeydown optional property to Button type supporting keyboard event handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

frontend, backend, frontend-tests, backend-tests, docs, accessibility, refactor

Suggested reviewers

  • kasya

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided by the author, making it impossible to assess whether the description relates to the changeset. Add a clear description explaining the purpose and scope of changes, including which areas (documentation, backend refactoring, frontend accessibility, dependencies) are affected.
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title "E2e/merge update 1" is vague and uses generic phrasing that does not convey meaningful information about the changeset's primary purpose. Replace with a more descriptive title that clearly indicates the main change, such as referencing specific refactoring, dependency updates, or accessibility improvements covered in the PR.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch e2e/merge-update-1

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.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 2, 2026

@arkid15r arkid15r marked this pull request as ready for review January 2, 2026 18:30
@arkid15r arkid15r requested a review from kasya as a code owner January 2, 2026 18:30
coderabbitai[bot]
coderabbitai bot previously requested changes Jan 2, 2026
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: 6

🧹 Nitpick comments (6)
frontend/__tests__/unit/components/CardDetailsPage.test.tsx (1)

726-739: Consider making the button query more specific.

The test uses screen.getByRole('button'), which assumes there's only one button on the page. If additional buttons are added to the component in the future, this test could fail or become less specific about what it's verifying.

🔎 Proposed refinement for test specificity
-    const healthButton = screen.getByRole('button')
+    const healthButton = screen.getByRole('button', { name: /score/i })
     expect(healthButton).toBeInTheDocument()
     expect(screen.getByTestId('metrics-score-circle')).toBeInTheDocument()

Alternatively, you could query directly by testid if role semantics aren't the primary concern:

-    const healthButton = screen.getByRole('button')
-    expect(healthButton).toBeInTheDocument()
-    expect(screen.getByTestId('metrics-score-circle')).toBeInTheDocument()
+    const healthButton = screen.getByTestId('metrics-score-circle')
+    expect(healthButton).toBeInTheDocument()
+    expect(healthButton.tagName).toBe('BUTTON')
frontend/src/components/ToggleableList.tsx (1)

28-33: Optional: The explicit keyboard handler duplicates native button behavior.

Buttons already trigger onClick when Enter or Space is pressed, so the onKeyDown handler and handleKeyDown function are redundant. Additionally, the !isDisabled checks in both onClick (line 50) and onKeyDown (line 51) are unnecessary since disabled={isDisabled} (line 53) already prevents interaction.

🔎 Optional simplification

You can remove the handleKeyDown function and onKeyDown handler entirely:

-  const handleKeyDown = (e: React.KeyboardEvent, item: string) => {
-    if (e.key === 'Enter' || e.key === ' ') {
-      e.preventDefault()
-      handleButtonClick({ item })
-    }
-  }

And simplify the button:

           <button
             type="button"
             key={`${item}-${index}`}
             className={`rounded-lg border border-gray-400 px-3 py-1 text-sm hover:bg-gray-200 dark:border-gray-300 dark:hover:bg-gray-700 ${isDisabled ? 'cursor-default' : 'cursor-pointer'}`}
-            onClick={() => !isDisabled && handleButtonClick({ item })}
-            onKeyDown={(e) => !isDisabled && handleKeyDown(e, item)}
+            onClick={() => handleButtonClick({ item })}
             aria-label={`Search for projects with ${item}`}
             disabled={isDisabled}
           >

Also applies to: 51-51

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx (2)

112-151: Good refactoring to centralize status logic.

The extraction of status computation into dedicated variables and helper functions improves code organization and reduces repetition. The logic correctly handles all status states.

However, consider these optional improvements:

  1. Styling consistency: issueStatusClass uses Tailwind classes (e.g., bg-[#238636]), while getPRStatus returns raw hex colors (e.g., #238636). Consider standardizing on one approach for maintainability.

  2. Performance optimization: These helpers are recreated on every render. For better performance, consider:

    • Moving getPRStatus and getAssignButtonTitle outside the component as pure functions
    • Memoizing with useCallback if they need closure dependencies
Example: Move helpers outside component
+const getPRStatus = (pr: { state: string; mergedAt: string | null }) => {
+  let backgroundColor: string
+  let label: string
+  if (pr.state === 'closed' && pr.mergedAt) {
+    backgroundColor = '#8657E5'
+    label = 'Merged'
+  } else if (pr.state === 'closed') {
+    backgroundColor = '#DA3633'
+    label = 'Closed'
+  } else {
+    backgroundColor = '#238636'
+    label = 'Open'
+  }
+  return { backgroundColor, label }
+}
+
+const getAssignButtonTitle = (issueId: string | undefined, assigning: boolean) => {
+  if (!issueId) return 'Loading issue…'
+  if (assigning) return 'Assigning…'
+  return 'Assign to this user'
+}
+
 const ModuleIssueDetailsPage = () => {
   // ... component code
-  const getPRStatus = (pr: Exclude<typeof issue.pullRequests, undefined>[0]) => {
-    // ... moved outside
-  }
-
-  const getAssignButtonTitle = (assigning: boolean) => {
-    // ... moved outside
-  }

Then update the call on line 450:

-title={getAssignButtonTitle(assigning)}
+title={getAssignButtonTitle(issueId, assigning)}

386-396: Consider simplifying the IIFE pattern.

The immediately invoked function expression (IIFE) wrapping getPRStatus is functional but adds unnecessary verbosity. You can simplify this by computing the status before the JSX.

Suggested simplification
                  </div>
                  <div className="flex items-center gap-2">
-                    {(() => {
-                      const { backgroundColor, label } = getPRStatus(pr)
-                      return (
-                        <span
-                          className="inline-flex items-center rounded-lg px-2 py-0.5 text-xs font-medium text-white"
-                          style={{ backgroundColor }}
-                        >
-                          {label}
-                        </span>
-                      )
-                    })()}
+                    <span
+                      className="inline-flex items-center rounded-lg px-2 py-0.5 text-xs font-medium text-white"
+                      style={{ backgroundColor: getPRStatus(pr).backgroundColor }}
+                    >
+                      {getPRStatus(pr).label}
+                    </span>
                  </div>

Or if you prefer to avoid calling getPRStatus twice, compute it in the parent scope:

            {issue.pullRequests?.length ? (
              issue.pullRequests.map((pr) => {
+               const prStatus = getPRStatus(pr)
                return (
                  <div
                    key={pr.id}
frontend/src/components/Search.tsx (1)

69-74: Keyboard handler is redundant for native button elements.

The clear button is a native <button> element, which already handles Enter and Space key presses through the onClick handler. The explicit onKeyDown handler duplicates this built-in behavior.

While this doesn't cause any issues, it adds unnecessary code. Consider removing the handleKeyDown function and the onKeyDown prop unless there's a specific requirement for custom keyboard handling.

🔎 Simplify by removing redundant keyboard handler
-  const handleKeyDown = (e: React.KeyboardEvent) => {
-    if (e.key === 'Enter' || e.key === ' ') {
-      e.preventDefault()
-      handleClearSearch()
-    }
-  }
-
   return (
     <div className="w-full max-w-md p-4">
       <div className="relative">
         {isLoaded ? (
           <>
             <FaSearch
               data-testid="search-icon"
               className="pointer-events-none absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400"
               aria-hidden="true"
             />
             <input
               ref={inputRef}
               type="text"
               value={searchQuery}
               onChange={handleSearchChange}
               placeholder={placeholder}
               className="h-12 w-full rounded-lg border-1 border-gray-300 bg-white pr-10 pl-10 text-lg text-black focus:ring-1 focus:ring-blue-500 focus:outline-hidden dark:border-gray-600 dark:bg-gray-800 dark:text-white dark:focus:ring-blue-300"
             />
             {searchQuery && (
               <button
                 type="button"
                 className="absolute top-1/2 right-2 h-8 w-8 -translate-y-1/2 rounded-md p-1 text-gray-400 hover:bg-gray-400 hover:text-gray-200 focus:ring-2 focus:ring-gray-300 focus:outline-hidden dark:hover:bg-gray-600"
                 onClick={handleClearSearch}
-                onKeyDown={handleKeyDown}
                 aria-label="Clear search"
               >
                 <FaTimes className="h-4 w-4" aria-hidden="true" />
               </button>
             )}
           </>

Also applies to: 99-99

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

47-52: Keyboard handler is redundant for native button elements.

The repository title button is a native <button> element, which already handles Enter and Space key presses through the onClick handler. The explicit onKeyDown handler duplicates this built-in behavior.

While this doesn't cause any issues, it adds unnecessary code. Consider removing the handleKeyDown function and the onKeyDown prop unless there's a specific requirement for custom keyboard handling.

🔎 Simplify by removing redundant keyboard handler
   const handleClick = () => {
     router.push(`/organizations/${details.organization?.login}/repositories/${details.key}`)
   }
 
-  const handleKeyDown = (e: React.KeyboardEvent) => {
-    if (e.key === 'Enter' || e.key === ' ') {
-      e.preventDefault()
-      handleClick()
-    }
-  }
-
   return (
     <div className="flex h-46 w-full flex-col gap-3 rounded-lg border-1 border-gray-200 p-4 shadow-xs ease-in-out hover:shadow-md dark:border-gray-700 dark:bg-gray-800">
       <div className="flex items-start justify-between gap-2">
         <button
           type="button"
           onClick={handleClick}
-          onKeyDown={handleKeyDown}
           className="min-w-0 flex-1 cursor-pointer text-start font-semibold text-blue-400 hover:underline focus:rounded focus:outline-2 focus:outline-offset-2 focus:outline-blue-500"
         >
           <TruncatedText text={details?.name} />
         </button>

Also applies to: 60-60

📜 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 5e7e5d4 and 7b84444.

⛔ Files ignored due to path filters (3)
  • backend/poetry.lock is excluded by !**/*.lock
  • docs/poetry.lock is excluded by !**/*.lock
  • frontend/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (36)
  • CONTRIBUTING.md
  • backend/apps/api/rest/v0/snapshot.py
  • backend/apps/owasp/models/common.py
  • backend/pyproject.toml
  • backend/tests/apps/common/management/commands/add_project_custom_tags_test.py
  • docs/pyproject.toml
  • frontend/__tests__/unit/components/BarChart.test.tsx
  • frontend/__tests__/unit/components/CardDetailsPage.test.tsx
  • frontend/__tests__/unit/components/GeneralCompliantComponent.test.tsx
  • frontend/__tests__/unit/components/Pagination.test.tsx
  • frontend/__tests__/unit/components/ProjectsDashboardDropDown.test.tsx
  • frontend/__tests__/unit/pages/About.test.tsx
  • frontend/__tests__/unit/pages/ApiKeysPage.test.tsx
  • frontend/__tests__/unit/pages/Home.test.tsx
  • frontend/package.json
  • frontend/src/app/about/page.tsx
  • frontend/src/app/api/auth/[...nextauth]/route.ts
  • frontend/src/app/board/[year]/candidates/page.tsx
  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx
  • frontend/src/app/settings/api-keys/page.tsx
  • frontend/src/components/ActionButton.tsx
  • frontend/src/components/Card.tsx
  • frontend/src/components/GeneralCompliantComponent.tsx
  • frontend/src/components/ModuleCard.tsx
  • frontend/src/components/ModuleForm.tsx
  • frontend/src/components/MultiSearch.tsx
  • frontend/src/components/Pagination.tsx
  • frontend/src/components/Release.tsx
  • frontend/src/components/RepositoryCard.tsx
  • frontend/src/components/Search.tsx
  • frontend/src/components/ShowMoreButton.tsx
  • frontend/src/components/SortBy.tsx
  • frontend/src/components/ToggleableList.tsx
  • frontend/src/components/skeletons/Card.tsx
  • frontend/src/components/skeletons/UserCard.tsx
  • frontend/src/types/button.ts
🧰 Additional context used
🧠 Learnings (21)
📚 Learning: 2025-08-10T11:08:47.258Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/src/app/api/auth/[...nextauth]/route.ts:13-25
Timestamp: 2025-08-10T11:08:47.258Z
Learning: In the OWASP Nest codebase (frontend/src/app/api/auth/[...nextauth]/route.ts), input validation and string trimming for authentication-related queries like `isProjectLeader` and `isMentor` are handled in the backend rather than the frontend. The backend is responsible for sanitizing and validating input parameters.

Applied to files:

  • frontend/src/app/api/auth/[...nextauth]/route.ts
📚 Learning: 2025-07-13T07:31:06.511Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 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.

Applied to files:

  • frontend/src/components/ModuleCard.tsx
📚 Learning: 2025-07-13T11:29:25.245Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 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.

Applied to files:

  • frontend/src/components/ModuleCard.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/ModuleForm.tsx
📚 Learning: 2025-11-17T17:30:42.139Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:169-171
Timestamp: 2025-11-17T17:30:42.139Z
Learning: In the OWASP/Nest frontend tests (PR #2671 context), wrapper functions like `expectChaptersCountEqualsThree` that simply call another helper with a fixed parameter (e.g., `expectChaptersCountEquals(3)`) are intentionally used to avoid arrow function callbacks in `waitFor` calls. This pattern prevents adding nesting depth that would trigger rule typescript:S2004. Example: `await waitFor(expectChaptersCountEqualsThree)` avoids the extra nesting from `await waitFor(() => expectChaptersCountEquals(3))`.

Applied to files:

  • frontend/__tests__/unit/components/Pagination.test.tsx
📚 Learning: 2025-07-12T17:12:25.807Z
Learnt from: Rajgupta36
Repo: OWASP/Nest PR: 1717
File: frontend/__tests__/unit/pages/ProgramDetails.test.tsx:35-0
Timestamp: 2025-07-12T17:12:25.807Z
Learning: In React applications, button elements should always have an explicit type attribute (type="button", type="submit", or type="reset") to prevent unintended form submission behavior, even when the button appears to be outside of a form context. The default type is "submit" which can cause unexpected behavior.

Applied to files:

  • frontend/src/components/ToggleableList.tsx
  • frontend/src/types/button.ts
  • frontend/src/components/ActionButton.tsx
  • frontend/src/components/Card.tsx
📚 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/Home.test.tsx
  • frontend/__tests__/unit/pages/ApiKeysPage.test.tsx
  • frontend/__tests__/unit/components/ProjectsDashboardDropDown.test.tsx
  • frontend/__tests__/unit/components/CardDetailsPage.test.tsx
📚 Learning: 2025-07-03T03:08:03.290Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 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.

Applied to files:

  • frontend/__tests__/unit/components/BarChart.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/GeneralCompliantComponent.test.tsx
  • frontend/src/components/ShowMoreButton.tsx
  • frontend/src/components/ActionButton.tsx
  • frontend/src/components/Card.tsx
  • frontend/src/components/SortBy.tsx
  • frontend/src/components/GeneralCompliantComponent.tsx
📚 Learning: 2025-11-17T16:47:05.578Z
Learnt from: anurag2787
Repo: OWASP/Nest PR: 2671
File: frontend/__tests__/unit/components/MultiSearch.test.tsx:427-427
Timestamp: 2025-11-17T16:47:05.578Z
Learning: In the frontend test files for the OWASP/Nest repository, `expect(true).toBe(true)` no-op assertions may be intentionally added as workarounds when ESLint rule jest/expect-expect doesn't detect expectations inside helper functions or waitFor callbacks. These can be resolved by configuring the ESLint rule's assertFunctionNames option to recognize custom assertion helpers instead of flagging them as redundant.

Applied to files:

  • frontend/__tests__/unit/components/GeneralCompliantComponent.test.tsx
📚 Learning: 2025-12-29T22:01:53.874Z
Learnt from: ShashaankS
Repo: OWASP/Nest PR: 3086
File: frontend/src/components/SortBy.tsx:45-45
Timestamp: 2025-12-29T22:01:53.874Z
Learning: In frontend/src/components/SortBy.tsx, the SelectItem uses hover:bg-transparent intentionally for better visual appeal and theme consistency. This design choice prioritizes a cleaner aesthetic over hover background feedback.

Applied to files:

  • frontend/src/components/ShowMoreButton.tsx
  • frontend/src/components/SortBy.tsx
📚 Learning: 2025-12-31T05:17:39.659Z
Learnt from: kart-u
Repo: OWASP/Nest PR: 3101
File: backend/apps/common/extensions.py:92-98
Timestamp: 2025-12-31T05:17:39.659Z
Learning: In this codebase, import OperationType for GraphQL operations from the graphql-core package rather than from strawberry. Use 'from graphql import OperationType'. Strawberry re-exports via graphql-core internally, so relying on strawberry's API may be brittle. Apply this rule to all Python files that deal with GraphQL operation types; ensure imports come from graphql (graphql-core) and not from strawberry packages. This improves compatibility and avoids coupling to strawberry's internals.

Applied to files:

  • backend/apps/api/rest/v0/snapshot.py
  • backend/apps/owasp/models/common.py
  • backend/tests/apps/common/management/commands/add_project_custom_tags_test.py
📚 Learning: 2026-01-01T17:48:23.963Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:41-47
Timestamp: 2026-01-01T17:48:23.963Z
Learning: In Django code, be aware that a QuerySet's boolean evaluation (e.g., if not queryset) runs a database query to determine emptiness. While it is technically valid to use the queryset in a boolean context, use queryset.exists() for existence checks to avoid unnecessary queries and improve performance. Applicable broadly to Python/Django files rather than just this specific path.

Applied to files:

  • backend/apps/api/rest/v0/snapshot.py
  • backend/apps/owasp/models/common.py
  • backend/tests/apps/common/management/commands/add_project_custom_tags_test.py
📚 Learning: 2025-09-21T17:04:48.154Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2178
File: frontend/src/app/snapshots/[id]/page.tsx:0-0
Timestamp: 2025-09-21T17:04:48.154Z
Learning: User rudransh-shrivastava confirmed that suggested type safety improvements during Apollo Client migration were no longer relevant, reinforcing their preference to keep migration PRs focused on core migration changes rather than additional improvements.

Applied to files:

  • frontend/src/app/about/page.tsx
📚 Learning: 2025-08-31T13:47:15.861Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2155
File: frontend/src/server/queries/programsQueries.ts:81-81
Timestamp: 2025-08-31T13:47:15.861Z
Learning: In frontend/src/server/queries/programsQueries.ts, GET_PROGRAM_DETAILS is actively used in frontend/src/app/my/mentorship/programs/[programKey]/edit/page.tsx for program editing functionality and cannot be removed. It serves a different purpose than GET_PROGRAM_ADMIN_DETAILS, providing comprehensive program information needed for editing.

Applied to files:

  • frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx
📚 Learning: 2025-06-21T12:21:32.372Z
Learnt from: ahmedxgouda
Repo: OWASP/Nest PR: 1633
File: frontend/src/components/GradientRadialChart.tsx:67-116
Timestamp: 2025-06-21T12:21:32.372Z
Learning: The react-apexcharts Chart component does not support ARIA attributes like aria-label and role as direct props. To add accessibility attributes to ApexCharts in React, wrap the Chart component in a container div with the appropriate ARIA attributes.

Applied to files:

  • frontend/src/components/skeletons/UserCard.tsx
📚 Learning: 2026-01-01T18:57:05.007Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/video.py:189-215
Timestamp: 2026-01-01T18:57:05.007Z
Learning: In the OWASP backend area, maintain the established pattern: when dealing with sponsors, include all entries from Sponsor.objects.all() (including NOT_SPONSOR) and perform in-memory sorting using the same criteria/pattern used by the GraphQL sponsor query implemented in backend/apps/owasp/api/internal/queries/sponsor.py. Apply this behavior consistently to files in backend/apps/owasp (not just video.py), and ensure code paths that render sponsor lists follow this in-code sorting approach rather than pre-filtering NOT_SPONSOR entries before sorting.

Applied to files:

  • backend/apps/owasp/models/common.py
📚 Learning: 2025-12-18T05:39:42.678Z
Learnt from: rudransh-shrivastava
Repo: OWASP/Nest PR: 2948
File: backend/apps/owasp/management/commands/owasp_generate_community_snapshot_video.py:40-40
Timestamp: 2025-12-18T05:39:42.678Z
Learning: In Django management commands, prefer using self.stdout.write(...) over print(...) for user-facing stdout output. This aligns with Django conventions and improves testability. When emitting messages, consider using self.stdout.write and, for styled messages, use self.style.SUCCESS/ERROR as appropriate to maintain consistent command output formatting. Apply this guideline to all Python files within any project's management/commands directory.

Applied to files:

  • backend/tests/apps/common/management/commands/add_project_custom_tags_test.py
📚 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/components/SortBy.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/__tests__/unit/components/CardDetailsPage.test.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/__tests__/unit/components/CardDetailsPage.test.tsx
🧬 Code graph analysis (6)
frontend/src/app/board/[year]/candidates/page.tsx (1)
frontend/src/types/__generated__/boardQueries.generated.ts (1)
  • GetBoardCandidatesDocument (33-33)
frontend/src/components/ActionButton.tsx (2)
frontend/src/types/link.ts (1)
  • Link (1-7)
frontend/src/types/button.ts (1)
  • Button (5-11)
frontend/src/app/settings/api-keys/page.tsx (2)
frontend/src/types/apiKey.ts (1)
  • ApiKey (9-15)
frontend/src/types/button.ts (1)
  • Button (5-11)
frontend/src/app/about/page.tsx (1)
frontend/src/types/__generated__/projectQueries.generated.ts (2)
  • GetProjectMetadataDocument (37-37)
  • GetTopContributorsDocument (38-38)
frontend/__tests__/unit/pages/About.test.tsx (2)
frontend/src/types/__generated__/projectQueries.generated.ts (2)
  • GetProjectMetadataDocument (37-37)
  • GetTopContributorsDocument (38-38)
frontend/__tests__/unit/data/mockProjectData.ts (1)
  • mockProjectData (1-26)
frontend/src/components/MultiSearch.tsx (5)
frontend/src/types/chapter.ts (1)
  • Chapter (4-21)
frontend/src/types/project.ts (1)
  • Project (20-49)
frontend/src/types/user.ts (1)
  • User (11-35)
frontend/src/types/event.ts (1)
  • Event (1-10)
frontend/src/types/organization.ts (1)
  • Organization (1-17)
🪛 LanguageTool
CONTRIBUTING.md

[grammar] ~254-~254: Use a hyphen to join words.
Context: ...u when you sign up. - During the sign up process, you may be asked to import d...

(QB_NEW_EN_HYPHEN)

⏰ 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). (5)
  • GitHub Check: Run fuzz tests
  • GitHub Check: Run frontend e2e tests
  • GitHub Check: Run frontend unit tests
  • GitHub Check: Run backend tests
  • GitHub Check: CodeQL (javascript-typescript)
🔇 Additional comments (46)
frontend/src/components/skeletons/UserCard.tsx (1)

13-15: Excellent accessibility improvements for loading states.

The addition of aria-busy="true" and aria-label="Loading" enhances the screen reader experience for users waiting for content to load. These attributes work well with the existing role="status" to provide clear feedback about the loading state.

Note: role="status" already has an implicit aria-live="polite", so the explicit aria-live attribute is technically redundant but harmless and can improve code clarity.

frontend/src/components/skeletons/Card.tsx (1)

19-25: Consistent accessibility enhancements across skeleton components.

The accessibility attributes here mirror those added to UserCardSkeleton, providing a consistent and accessible loading experience. The combination of role="status", aria-busy="true", and aria-label="Loading" ensures screen readers properly announce the loading state to users.

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

365-365: LGTM! Improved consistency with idiomatic JavaScript.

The change from 100.0 to 100 is functionally equivalent and aligns with JavaScript conventions and the majority of other test cases in this file that use integer notation for whole numbers.

Also applies to: 373-373

frontend/src/app/board/[year]/candidates/page.tsx (2)

91-97: Good refactor: Using Apollo's built-in loading state.

This change correctly leverages Apollo Client's loading flag instead of managing local state with useState. This approach is cleaner and avoids potential race conditions between the query lifecycle and manual state updates.


680-682: LGTM!

The loading check correctly uses Apollo's loading flag to display the spinner while the GraphQL query is in flight.

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

467-478: Good fix: Distinguishing GraphQL documents in mock implementation.

The updated mock correctly differentiates between GetProjectMetadataDocument and GetTopContributorsDocument when the key is 'nest'. This ensures accurate test behavior since both queries share the same key but expect different response structures.

This aligns with the beforeEach mock setup (lines 220-236) which uses the same pattern.

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

8-8: LGTM!

Import cleanup correctly removes useState since state is now derived from Apollo's query responses.


63-82: Clean Apollo query setup with proper loading state extraction.

The queries correctly extract loading, data, and error from both GetProjectMetadataDocument and GetTopContributorsDocument. Running these queries in parallel improves loading performance.


86-88: Good pattern: Deriving data directly from responses.

The explicit comment and direct derivation from response objects prevents race conditions that can occur when synchronizing Apollo query results with local state via useEffect. This is the recommended approach.


90-100: LGTM!

The error handling effects are correctly separated with minimal dependencies, ensuring handleAppError is called only when the respective error state changes.


102-106: Correct combined loading state.

The loading state properly combines all three query loading flags with logical OR, ensuring the skeleton is displayed until all required data is available.

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

77-84: LGTM! Semantic HTML improvement.

The update from div to fieldset/legend is a good accessibility enhancement. Using semantic HTML elements in test mocks better reflects accessible component patterns and aligns with the PR's broader accessibility improvements.

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

164-173: LGTM! Accessibility improvement with semantic button element.

The mock now correctly renders a native <button> element when clickable is true, rather than a <div> with a role attribute. This improves keyboard accessibility by providing native focus management and activation behavior.

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

371-377: LGTM! Improved error handling.

The error handling enhancement properly captures and logs the error with appropriate context. The instanceof Error check before accessing .message is the correct TypeScript pattern, and clearing the suggestions on error provides good UX for the autocomplete functionality.

CONTRIBUTING.md (2)

226-236: Concrete environment file setup instructions are clearer.

Replacing abstract guidance with specific cp commands makes the setup process straightforward and less error-prone for contributors.


262-262: API key guidance is now more actionable.

The updated note clearly states that the default write API key must have index write permissions (addObject permission) and provides guidance for non-default keys. This is a significant improvement over the previous caution approach, as it gives contributors a concrete requirement to verify rather than an instruction to ignore.

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/issues/[issueId]/page.tsx (1)

39-62: LGTM! Improved readability with explicit variable assignments.

The refactoring from inline conditionals to explicit if/else branches for statusText and color makes the logic much clearer and easier to maintain.

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

27-27: Good fix for the aria-hidden typo.

Correcting area-hidden to aria-hidden ensures the icon is properly hidden from screen readers, improving accessibility.


19-19: LGTM: Focus styling enhances keyboard accessibility.

The added focus outline and hover underline provide clear visual feedback for both keyboard and mouse users, improving the button's accessibility and usability.

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

61-61: LGTM: Focus styling enhances keyboard navigation.

The added focus outline provides clear visual feedback for keyboard users, improving accessibility and making it easier to navigate the repository cards.

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

46-54: LGTM: Using native dialog element improves test accuracy.

Replacing the div with role="dialog" with a native <dialog> element better reflects semantic HTML structure and provides a more accurate representation of modal behavior in tests. The open attribute properly controls visibility, and the native element includes built-in accessibility features.

frontend/src/components/MultiSearch.tsx (3)

196-206: Keyboard accessibility enhancement looks good.

The new handleSuggestionKeyDown handler properly enables Enter and Space key activation for individual suggestion items, complementing the existing arrow-key navigation. The use of stopPropagation() correctly prevents conflicts with the global keyboard handler.


269-269: Good use of optional chaining for null-safety.

The optional chaining ensures safe comparison when highlightedIndex is null, preventing potential runtime errors.


277-278: Accessibility improvements are well implemented.

The onKeyDown binding and enhanced focus styling (with visible outline) provide excellent keyboard accessibility and visual feedback for users navigating via keyboard.

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

25-37: Excellent keyboard accessibility enhancement.

The extracted navigation handlers provide both cleaner code organization and proper keyboard support. The validation check for org and repo before navigation is a good safeguard, and the keyboard handler correctly supports both Enter and Space keys.

Also applies to: 92-93

frontend/src/app/settings/api-keys/page.tsx (2)

23-77: Clean component extraction improves maintainability.

The refactored content state components (ErrorState, EmptyState, ApiKeysTable) provide better code organization and reusability. The ApiKeysTable is properly typed and follows React best practices.


79-89: Content-type-driven rendering is well designed.

The content-type approach with the getContentComponents mapper provides excellent maintainability and clear separation between loading, error, empty, and data states. The logic correctly distinguishes between initial loading (showing ApiKeysSkeleton) and subsequent refetches (showing LoadingSpinner).

Also applies to: 142-156, 289

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

25-25: Good update to use native dialog element.

Switching the Modal mock to render a native <dialog> element instead of a div with role="dialog" is more semantically correct and aligns with modern HTML standards. The test queries will continue to work correctly since <dialog> has the dialog role natively.

frontend/package.json (1)

76-76: No action required. Verification confirms that @swc/core 1.15.8, @typescript-eslint 8.51.0, and eslint-plugin-jest 29.12.0 are all compatible with React 19.2.3 and the Node.js ^24.0.0 engine requirement. No breaking changes or compatibility issues were identified in these versions.

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

16-26: LGTM! Clean simplification of the component structure.

The refactoring from a two-icon nested structure to a single circular container with conditional styling is well-executed. The use of clsx for conditional classes based on the compliant flag makes the component more maintainable, and the accessibility is preserved through the Tooltip wrapper.

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

37-61: LGTM! Tests properly updated to reflect component changes.

The test assertions have been correctly updated to match the simplified component structure:

  • Background and text color classes are verified for both compliant states
  • Icon count expectation changed from 2 to 1, matching the new single-icon rendering
frontend/src/components/Pagination.tsx (1)

74-79: LGTM! Proper accessibility improvement for decorative icon.

Adding aria-hidden="true" to the FaEllipsis icon is correct, as the container already provides the semantic meaning via aria-label="More pages". This prevents screen readers from announcing redundant information.

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

30-35: LGTM! Proper keyboard accessibility implementation.

The handleKeyDown function correctly handles both Enter and Space keys for toggling the "Show more/Show less" functionality, and the preventDefault() call properly prevents unwanted page scrolling when Space is pressed.


49-50: LGTM! Complete keyboard and focus accessibility.

The button now has both keyboard event handling and visible focus indicators, making it fully accessible for keyboard navigation. The focus styling with outline and offset provides clear visual feedback.

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

144-152: ActionButton correctly accepts the onKeyDown prop.

The ActionButton component interface properly defines onKeyDown?: (e: React.KeyboardEvent<HTMLAnchorElement | HTMLButtonElement>) => void and implements it in both the Link and Button branches (lines 34 and 44). The keyboard accessibility enhancement is correctly implemented.

frontend/src/components/SortBy.tsx (4)

3-3: LGTM: Type-only import for React.

The type-only import is the correct pattern for using React types without importing the runtime.


16-21: LGTM: Solid keyboard accessibility implementation.

The handler correctly supports Enter and Space keys (the standard keyboard activation keys) and prevents default Space scrolling behavior. This enhances accessibility for keyboard-only users.


34-34: LGTM: Enhanced focus visibility.

Adding focus:underline improves keyboard navigation feedback for the Select trigger.


73-73: LGTM: Keyboard handler correctly wired.

The onKeyDown handler is correctly attached to the sort order toggle button, completing the keyboard accessibility enhancement for this control.

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

9-9: LGTM: Correctly typed keyboard event handler.

The union type React.KeyboardEvent<HTMLAnchorElement | HTMLButtonElement> appropriately covers both the Link and Button variants of this component.


42-49: @heroui/button Button component supports the onKeyDown prop — implementation is correct.

The Button component from @heroui/button v2.2.29 explicitly supports the onKeyDown prop with signature onKeyDown: (e: KeyboardEvent) => void. The implementation in ActionButton.tsx is valid.

backend/apps/owasp/models/common.py (1)

241-245: LGTM! More idiomatic regex pattern.

The change from [\s\S]*? to .*? with re.DOTALL is functionally equivalent but more idiomatic. Both patterns match any character including newlines when the DOTALL flag is present, but using . with DOTALL is the standard Python approach.

backend/tests/apps/common/management/commands/add_project_custom_tags_test.py (1)

99-100: LGTM! Appropriate use of NOSONAR comment.

The inline comment correctly suppresses a code analysis warning for an intentionally unused parameter. In test mocks, it's common to match the signature of the real method (Django's save(update_fields=None)) without using all parameters.

frontend/src/app/api/auth/[...nextauth]/route.ts (2)

20-25: LGTM! Improved error handling with descriptive messages and error chaining.

The enhanced error handling includes:

  • Descriptive prefix indicating the failed operation
  • Original error message extraction with type checking
  • Error cause chaining for better stack trace preservation

This improves debugging capabilities and makes error logs more actionable.


37-42: LGTM! Consistent error handling pattern.

The error handling improvements mirror those in checkIfProjectLeader, maintaining consistency across both authentication check functions.

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

119-119: Consistent application across all endpoints.

All six Query parameter descriptions have been updated to use the new constant, ensuring uniformity across the API.

Also applies to: 165-165, 190-190, 217-217, 242-242, 267-267

Comment on lines +26 to +27
ORDERING_FIELD_DESCRIPTION = "Ordering field"

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 | 🟠 Major

Good DRY refactoring!

Extracting the repeated "Ordering field" description into a constant improves maintainability and ensures consistency across all endpoints.

🤖 Prompt for AI Agents
In backend/apps/api/rest/v0/snapshot.py around lines 26-27 you added
ORDERING_FIELD_DESCRIPTION = "Ordering field"; ensure this DRY refactor is
applied consistently by replacing any repeated literal "Ordering field"
occurrences in this file (and related modules if present) with the new constant,
and export or import the constant where other modules need it so all endpoints
reference ORDERING_FIELD_DESCRIPTION instead of hard-coded strings.

slack-sdk = "^3.37.0"
strawberry-graphql = { extras = [ "django" ], version = "^0.288.1" }
strawberry-graphql-django = "^0.71.0"
strawberry-graphql-django = "^0.72.0"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check latest version and recent versions of strawberry-graphql-django
echo "=== Checking strawberry-graphql-django versions ==="
curl -s https://pypi.org/pypi/strawberry-graphql-django/json | jq -r '.releases | keys[] | select(. >= "0.70.0" and . <= "0.73.0")' | sort -V

echo -e "\n=== Latest version info ==="
curl -s https://pypi.org/pypi/strawberry-graphql-django/json | jq '.info | {version, requires_dist: .requires_dist}'

echo -e "\n=== Release info for 0.72.0 ==="
curl -s https://pypi.org/pypi/strawberry-graphql-django/0.72.0/json | jq '.info | {version, requires_dist, summary}'

Repository: OWASP/Nest

Length of output: 731


🌐 Web query:

strawberry-graphql-django 0.72.0 release notes breaking changes

💡 Result:

Breaking changes in strawberry-graphql-django v0.72.0 (released August 18, 2021):

  • Added support for asynchronous permission classes.
  • Breaking for callers that instantiate StrawberryField / StrawberryArgument etc. directly if they used arguments such as is_optional or child.
  • @strawberry.field no longer accepts a type_ argument — it now expects a StrawberryAnnotation called type_annotation. [1]

Source: Strawberry changelog. [1]


🌐 Web query:

strawberry-graphql-django compatibility strawberry-graphql 0.288

💡 Result:

Yes — strawberry-graphql-django is compatible with recent Strawberry releases (the Django integration is supported by Strawberry core and the separate strawberry-graphql-django package). See the Django integration docs and the strawberry-graphql-django PyPI page. [1][2]

If you want a specific check, install matching latest minor releases (e.g. strawberry 0.288.x and the latest strawberry-graphql-django) and run your test suite; the docs note that importing strawberry_django mirrors strawberry.django when both are installed. [1][2]

Sources:

  • Strawberry Django integration docs. [1]
  • strawberry-graphql-django PyPI project page (package metadata, releases). [2]

Review the codebase for strawberry-graphql-django breaking changes in v0.72.0.

Version ^0.72.0 is compatible with strawberry-graphql ^0.288.1 (v0.72.0 requires strawberry-graphql>=0.288.0). However, v0.72.0 introduces breaking changes that require code review:

  • Direct instantiation of StrawberryField and StrawberryArgument with is_optional or child arguments no longer works
  • @strawberry.field no longer accepts the type_ argument; use type_annotation instead
  • Async permission classes are now supported

Verify the codebase does not rely on these deprecated patterns before upgrading.

🤖 Prompt for AI Agents
In backend/pyproject.toml around line 50, the pinned dependency
strawberry-graphql-django = "^0.72.0" may introduce breaking changes; search the
codebase for direct instantiation of StrawberryField or StrawberryArgument with
is_optional or child args and replace those patterns with the new supported
construction APIs (remove is_optional/child usage and use proper
typing/annotations or helper factories), find all uses of @strawberry.field(...,
type_=...) and change them to @strawberry.field(..., type_annotation=...) with
equivalent annotations, and audit permission classes for sync/async behavior
updating any permission implementations to be async-compatible where needed; run
tests and type checks after making these replacements.

Comment on lines +253 to +254
- An Algolia app is automatically created for you when you sign up.
- During the sign up process, you may be asked to import data. You can skip this step.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, find the CONTRIBUTING.md file
git ls-files | grep -i "contributing.md"

Repository: OWASP/Nest

Length of output: 90


🏁 Script executed:

# Read lines 253-254 from CONTRIBUTING.md
sed -n '250,260p' CONTRIBUTING.md | cat -n

Repository: OWASP/Nest

Length of output: 659


🌐 Web query:

hyphenation rules "sign up" vs "sign-up" adjective English grammar

💡 Result:

Short answer

  • Use sign up (two words) for the verb: "Please sign up for the class." [1][2]
  • Use sign-up (hyphen) or signup (one word, per some dictionaries) for the noun or an attributive adjective: "The sign-up sheet" / "the signup form." Style guides differ, so follow your house style. [1][2][3][4]

Sources

  • U.S. web style guide (HRSA): verb = "sign up"; noun/adjective = "sign‑up." [1]
  • Merriam‑Webster (dictionary): lists sign up (verb) and sign‑up (noun/adjective); also recognizes signup. [2]
  • GSA style guidance & Dictionary.com: similar notes on usage and forms. [3][4]

Fix hyphenation in Algolia setup narrative.

Line 254 contains a grammar issue: "sign up process" should be "sign-up process" when used as an adjective. Standard English conventions (Merriam-Webster, GSA style guide) require hyphenation for the attributive form, matching the style used in technical documentation.

🔎 Proposed grammar fix
- - During the sign up process, you may be asked to import data. You can skip this step.
+ - During the sign-up process, you may be asked to import data. You can skip this step.
📝 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
- An Algolia app is automatically created for you when you sign up.
- During the sign up process, you may be asked to import data. You can skip this step.
- An Algolia app is automatically created for you when you sign up.
- During the sign-up process, you may be asked to import data. You can skip this step.
🧰 Tools
🪛 LanguageTool

[grammar] ~254-~254: Use a hyphen to join words.
Context: ...u when you sign up. - During the sign up process, you may be asked to import d...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
In CONTRIBUTING.md around lines 253 to 254, the phrase "sign up process" is used
attributively and should be hyphenated; change "sign up process" to "sign-up
process" (both occurrences in those lines) to follow standard English
hyphenation for compound modifiers.

mkdocs-minify-plugin = "^0.8.0"
mkdocstrings = "^1.0.0"
pymdown-extensions = "^10.14.3"
pymdown-extensions = "^10.20.0"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, examine the docs/pyproject.toml file to understand the full context
cat docs/pyproject.toml

Repository: OWASP/Nest

Length of output: 504


🏁 Script executed:

#!/bin/bash
# Check pymdown-extensions on PyPI
echo "Fetching pymdown-extensions info from PyPI..."
curl -s https://pypi.org/pypi/pymdown-extensions/json | jq '{latest_version: .info.version, all_versions: .releases | keys | sort_by(split(".") | map(tonumber)) | reverse[0:10]}'

echo -e "\nChecking version 10.20.0 specifically..."
curl -s https://pypi.org/pypi/pymdown-extensions/json | jq '.releases | has("10.20.0")'

Repository: OWASP/Nest

Length of output: 263


🏁 Script executed:

#!/bin/bash
# Try direct access to PyPI with simpler approach
echo "Attempting to fetch pymdown-extensions release history..."
curl -s -I https://pypi.org/project/pymdown-extensions/10.20.0/ | head -1

# Also try fetching the simple API
echo -e "\nFetching from PyPI simple API..."
curl -s https://pypi.org/simple/pymdown-extensions/ | grep -o '10\.20\.0' | head -1

# Get all available versions
echo -e "\nFetching all versions (last 20)..."
curl -s https://pypi.org/simple/pymdown-extensions/ | grep -oP 'pymdown_extensions-\K[0-9.]+' | tail -20

Repository: OWASP/Nest

Length of output: 337


🏁 Script executed:

#!/bin/bash
# Use Python to parse versions more reliably
python3 << 'EOF'
import urllib.request
import re

try:
    url = "https://pypi.org/simple/pymdown-extensions/"
    with urllib.request.urlopen(url) as response:
        html = response.read().decode('utf-8')
    
    # Extract all versions from href attributes
    versions = re.findall(r'pymdown[_-]extensions[_-]([\d.]+)[^"]*\.whl', html)
    versions = sorted(set(versions), key=lambda v: tuple(map(int, v.split('.'))))
    
    print("Available versions (last 15):")
    for v in versions[-15:]:
        print(f"  {v}")
    
    if '10.20.0' in versions:
        print("\n✓ Version 10.20.0 EXISTS on PyPI")
    else:
        print("\n✗ Version 10.20.0 NOT FOUND")
        if '10.20' in str(versions):
            print("  But 10.20.x versions exist")
    
    print(f"\nLatest version: {versions[-1] if versions else 'Unknown'}")
        
except Exception as e:
    print(f"Error: {e}")
EOF

Repository: OWASP/Nest

Length of output: 140


🌐 Web query:

pymdown-extensions 10.20.0 PyPI release

💡 Result:

pymdown-extensions 10.20.0 was released on PyPI on December 31, 2025. [1][2]

Sources:

  • PyPI project page (pymdown-extensions — 10.20, Released Dec 31, 2025). [1]
  • PyMdown Extensions changelog/documentation. [2]

🌐 Web query:

pymdown-extensions 10.20.0 compatibility mkdocs mkdocs-material

💡 Result:

Short answer: pymdown-extensions 10.20.0 is available, but it can break some mkdocs / mkdocs-material uses that rely on the old snippets behavior. See details and fixes below.

  • pymdown-extensions 10.20 (10.20.0 on PyPI) is released. [1]
  • Starting with 10.0 the snippets extension changed behavior (snippets are restricted to the configured base_path by default via restrict_base_path). That change is the root cause of breakage people reported when using mkdocs / mkdocs-material. You can either set snippets.restrict_base_path: false in your pymdownx.snippets configuration or pin to a pre-10.x release if you need legacy behavior. [2][3]
  • If you use MkDocs Material, check the theme docs and any theme/plugin compatibility notes; many Material-based docs recommend specific pymdownx extensions and may include guidance for emoji/snippets configuration. If you hit "snippet not found" errors after upgrading, try the restrict_base_path setting above or downgrade to a 9.x release. [4][2]

References

  1. PyPI / pymdown-extensions (latest 10.20). [1]
  2. PyMdown changelog (notes about 10.0 snippet behavior and related fixes). [2]
  3. mkdocs-material GitHub issue reporting snippet-related breakage when pymdown-extensions moved to 10.x. [3]
  4. MkDocs Material docs on recommended pymdownx extensions and configuration. [4]

Would you like the exact mkdocs.yml snippet to set snippets.restrict_base_path: false?


Ensure pymdownx.snippets configuration is compatible with pymdown-extensions 10.20.0.

The version 10.20.0 exists and is valid, but note that pymdown-extensions 10.0+ changed the snippets extension behavior—restrict_base_path now defaults to true, which restricts snippet inclusion to the configured base path. This can cause "snippet not found" errors when using mkdocs-material. Verify that your mkdocs configuration either sets snippets.restrict_base_path: false in the pymdownx.snippets configuration or that all snippet paths are within the configured base directory.

🤖 Prompt for AI Agents
In docs/pyproject.toml around line 17, you added pymdown-extensions = "^10.20.0"
but pymdown-extensions 10.0+ changes pymdownx.snippets behavior so
restrict_base_path now defaults to true and can cause "snippet not found"
errors; either update your MkDocs configuration to explicitly set
pymdownx.snippets.restrict_base_path: false under the
markdown/extensions/pymdownx.snippets section, or ensure all snippet files live
inside the MkDocs configured docs/base directory so they are allowed by the
default restriction.

Comment on lines +89 to 93
const ellipsisContainers = document.querySelectorAll('div.flex.h-10.w-10')
const ellipses = Array.from(ellipsisContainers).filter((el) =>
el.querySelector('svg[aria-hidden="true"]')
)
expect(ellipses).toHaveLength(2)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Testing anti-pattern: querying by implementation details.

The test now queries by CSS classes ('div.flex.h-10.w-10') and DOM structure rather than by accessible attributes. This violates Testing Library best practices and makes the test brittle to styling changes.

The previous approach using screen.getAllByLabelText('More pages') was superior because it:

  • Tested from the user's perspective (how screen readers perceive the UI)
  • Was resilient to implementation changes
  • Enforced accessibility standards

Recommendation: Update the Pagination component to expose ellipsis indicators with proper ARIA attributes (e.g., aria-label="More pages" on the container), then revert this test to use screen.getAllByLabelText('More pages').

🔎 Recommended approach

In the Pagination component, ensure ellipsis containers have an accessible label:

<div aria-label="More pages" className="flex h-10 w-10 items-center justify-center">
  <FaEllipsis aria-hidden="true" />
</div>

Then in the test, revert to:

-    const ellipsisContainers = document.querySelectorAll('div.flex.h-10.w-10')
-    const ellipses = Array.from(ellipsisContainers).filter((el) =>
-      el.querySelector('svg[aria-hidden="true"]')
-    )
+    const ellipses = screen.getAllByLabelText('More pages')
     expect(ellipses).toHaveLength(2)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In frontend/__tests__/unit/components/Pagination.test.tsx around lines 89 to 93,
the test queries ellipsis elements by CSS classes and DOM structure which is
brittle; update the Pagination component to add an accessible label (e.g.,
aria-label="More pages") to the ellipsis container(s) and then change the test
to use screen.getAllByLabelText('More pages') to select them; ensure the
ellipsis icon remains aria-hidden so screen readers read the container label,
and remove the querySelector-based assertions in the test.

icon?: JSX.Element
label: string
onclick?: () => void
onkeydown?: (e: React.KeyboardEvent) => void
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use camelCase convention for React event handler props.

The property name onkeydown doesn't follow React's naming convention. React event handlers use camelCase (e.g., onClick, onKeyDown, onChange). This inconsistency can lead to confusion and potential integration issues.

🔎 Fix the property name
 export type Button = {
   icon?: JSX.Element
   label: string
   onclick?: () => void
-  onkeydown?: (e: React.KeyboardEvent) => void
+  onKeyDown?: (e: React.KeyboardEvent) => void
   url?: string
 }
📝 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
onkeydown?: (e: React.KeyboardEvent) => void
export type Button = {
icon?: JSX.Element
label: string
onclick?: () => void
onKeyDown?: (e: React.KeyboardEvent) => void
url?: string
}
🤖 Prompt for AI Agents
In frontend/src/types/button.ts around line 9, the prop name `onkeydown` uses
incorrect casing for a React event handler; rename it to `onKeyDown` to follow
React's camelCase convention, update any imports/usages, type references, and
related tests or components to use `onKeyDown`, and run type checks to ensure
there are no remaining references to the old name.

@arkid15r arkid15r disabled auto-merge January 2, 2026 18:36
@arkid15r arkid15r merged commit a6e6b12 into feature/e2e-backend Jan 2, 2026
70 of 72 checks passed
@arkid15r arkid15r deleted the e2e/merge-update-1 branch January 2, 2026 18:36
@coderabbitai coderabbitai bot mentioned this pull request Jan 6, 2026
3 tasks
This was referenced Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend backend-tests docs Improvements or additions to documentation frontend frontend-tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.