Skip to content

Add unit test infrastructure and inline snapshot tests#245

Merged
keithchong merged 2 commits into
redhat-developer:mainfrom
AdamSaleh:add-unit-test-coverage
Jun 17, 2026
Merged

Add unit test infrastructure and inline snapshot tests#245
keithchong merged 2 commits into
redhat-developer:mainfrom
AdamSaleh:add-unit-test-coverage

Conversation

@AdamSaleh

Copy link
Copy Markdown
Member

Summary

  • Set up Jest with ts-jest, jsdom, and module mocks for PatternFly, OpenShift Console SDK, react-i18next, and CSS/SCSS imports
  • Add 24 test suites (144 tests, 203 inline snapshots) covering utility functions, service layer, and React components
  • Add GitHub Actions workflow to run tests on push/PR and upload coverage to Codecov with unit-tests flag

All tests use toMatchInlineSnapshot() — expected values live in the source file and auto-update with jest -u. No external fixture files, no manual snapshot maintenance.

What's tested

Area Files What's covered
Utilities utils, gitops, urls, stringHelpers, project-utils URL building, GVK parsing, git provider detection, HTML encoding
Services ArgoCD sync, terminate, refresh K8s operations
Components SyncStatus, HealthStatus, OperationState, Revision, MetadataLabels, ExternalLink, ActionDropDown, toggles, etc. Rendering with various props
Topology graph/utils, creators Node status mapping, abbreviations, action creators
Rollouts rollout-utils, ReplicaSetInfo Deploy detection, replica set info extraction, canary/stable identification
Pod status pod-utils Pod status from container states
Plugin icons, TechPreviewBadge, enableGitOpsDynamicFlag Status icons, badges, feature flags

Mock infrastructure

9 mock files in __mocks__/ stub external dependencies for Jest:

  • dynamic-plugin-sdk.tsx — OpenShift Console SDK types, icons, and K8s helpers
  • patternfly-react-core.tsx — Button, Popover, Dropdown, Tooltip, Label, etc.
  • patternfly-react-icons.tsx, patternfly-react-table.tsx, patternfly-react-topology.ts, patternfly-react-tokens.ts
  • react-i18next.ts, json-schema.ts, style-mock.ts

Note: Adding a new PatternFly or SDK import to source code may require updating the corresponding mock file.

Why renderToStaticMarkup instead of @testing-library/react

The project uses React 17.0.2. @testing-library/react@14+ requires React 18's react-dom/client. renderToStaticMarkup works with React 17 and produces deterministic HTML suitable for inline snapshots.

Test plan

  • yarn test — 24 suites, 144 tests, 203 snapshots pass
  • yarn test:coverage — generates coverage report
  • jest -u — all snapshots auto-update
  • Verify GitHub Actions workflow runs on this PR
  • Verify Codecov receives the coverage upload

🤖 Generated with Claude Code

@openshift-ci openshift-ci Bot requested review from keithchong and wtam2018 June 11, 2026 18:16
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 039f4e55-d12a-4a01-bf43-19bf4551d81e

📥 Commits

Reviewing files that changed from the base of the PR and between fd94b45 and 24e85d8.

📒 Files selected for processing (1)
  • README.md
✅ Files skipped from review due to trivial changes (1)
  • README.md

📝 Walkthrough

Summary by CodeRabbit

  • Tests
    • Added extensive Jest unit/snapshot coverage across UI components, status displays, URL/util helpers, and rollout/topology logic.
  • Chores
    • Introduced a unit test CI workflow with coverage reporting.
    • Added/updated Jest test tooling (scripts, configuration, and lightweight test mocks).
    • Updated project ignore rules to exclude coverage artifacts.
    • Documented how to run tests, update snapshots, and generate coverage in the README.

Walkthrough

Adds Jest configuration, dev tooling, test scripts, a GitHub Actions workflow for coverage reporting, nine Jest mock modules for external dependencies, and a comprehensive suite of snapshot and unit tests covering UI components, utilities, services, pod/container logic, graph helpers, and rollout state analysis.

Changes

Jest Testing Infrastructure & Test Coverage

Layer / File(s) Summary
Jest Configuration & Environment
jest.config.ts, package.json, .gitignore, .github/workflows/unit-tests.yml, README.md
Jest config for TypeScript via ts-jest and jsdom environment; extensive moduleNameMapper entries to route src/, @gitops/*, and external packages to local mocks; test scripts (test, test:update, test:coverage) and devDependencies upgraded to Jest 29; CI workflow that installs dependencies, runs coverage tests, and uploads to Codecov; .gitignore updated to exclude coverage/; README updated with testing documentation.
Jest Mock Modules for External Dependencies
__mocks__/dynamic-plugin-sdk.tsx, __mocks__/json-schema.ts, __mocks__/patternfly-react-core.tsx, __mocks__/patternfly-react-icons.tsx, __mocks__/patternfly-react-table.tsx, __mocks__/patternfly-react-tokens.ts, __mocks__/patternfly-react-topology.ts, __mocks__/react-i18next.ts, __mocks__/style-mock.ts
Nine mock modules providing lightweight Jest fn() stubs, React component stand-ins, and type aliases for dynamic-plugin-sdk, PatternFly core/icons/table/tokens/topology, json-schema, react-i18next, and stylesheet imports to enable isolated test execution without external dependencies.
Status & Revision Component Tests
src/gitops/Revision/Revision.test.tsx, src/gitops/Statuses/HealthStatus.test.tsx, src/gitops/Statuses/SyncStatus.test.tsx, src/gitops/Statuses/OperationState.test.tsx
Snapshot tests verifying revision rendering (SHA 7-char truncation, sha256: prefix handling, branch names, Helm mode without links, empty revision as (None), revisionExtra suffixes), health status icons and popovers with messages, sync status indicators for Synced/OutOfSync/Unknown states, and operation state phase-specific output with quiet mode suppression of Succeeded.
UI Component & Icon Tests
src/gitops/utils/components/ActionDropDown/ActionDropDown.test.tsx, src/gitops/utils/components/ActionDropDownItem/ActionDropDownItem.test.tsx, src/gitops/utils/components/ExternalLink/ExternalLink.test.tsx, src/gitops/utils/components/OwnerReferences/OwnerReferences.test.tsx, src/gitops/utils/components/toggles/toggles.test.tsx, src/gitops/components/shared/MetadataLabels/MetadataLabels.test.tsx, src/plugin/import/badges/TechPreviewBadge.test.tsx, src/plugin/status/icons.test.tsx
Snapshot tests for action dropdown toggles (default and kebab variants), dropdown item rendering (basic, described, disabled, icon-bearing), external links with target="_blank" and rel attributes, owner references with Application/ApplicationSet/unknown kind fallbacks, dropdown/kebab/select toggle components, metadata label display (no labels, single/multiple labels, empty values), tech preview badge with optional tooltip, and plugin status icons (GrayUnknownIcon, BlueSyncIcon, RedResourcesFullIcon, etc.).
GitOps Utility & Helper Function Tests
src/gitops/utils/gitops.test.ts, src/gitops/utils/urls.test.ts, src/gitops/utils/stringHelpers.test.ts, src/gitops/utils/project-utils.test.ts, src/gitops/utils/utils.test.ts
Unit tests for revision URL normalization and commit link generation, repository URL extraction across GitHub/GitLab/Bitbucket, SHA vs branch detection, cluster name mapping (in-cluster Kubernetes recognition), operation duration calculation from ISO timestamps, refresh annotation detection (argocd.argoproj.io/refresh), operation type inference (Sync/Delete/Unknown), ApplicationSet status from condition type/status, project deny-rule detection and display value normalization, Git URL regex validation, HTML entity encoding, resource array wrapping, GVK parsing, resource URL construction with namespace/all-namespaces handling, and resource path building for CRD and cluster-scoped models.
Service, Pod, Graph, and Rollout Tests
src/gitops/services/ArgoCD.test.ts, src/gitops/components/shared/pod-utils.test.ts, src/gitops/components/graph/utils.test.ts, src/gitops/components/rollout/revisions/ReplicaSetInfo.test.ts, src/gitops/components/rollout/utils/rollout-utils.test.ts, src/gitops/topology/actions/creators.test.ts, src/plugin/utils/flags/enableGitOpsDynamicFlag.test.ts
Tests for ArgoCD Kubernetes mutation helpers (syncAppK8s with operation fields and optional sync policy details, syncResourcek8s with resource mapping, terminateOpK8s with JSON patch replacement, refreshAppk8s with annotation soft/hard modes); pod status detection (Terminating on deletionTimestamp, CrashLoopBackOff via waiting state, Warning on non-zero exitCode, Not Ready phases, Running/Pending/Succeeded from pod phase); container looping filter for CrashLoopBackOff identification; graph node status mapping from HealthStatus with default fallback, spacer node creation with configurable padding, and sync status mapping; replica set analysis with selector construction from hash labels, stable vs canary classification, zero-replica ScaledDown status, pod-to-replica-set assignment, and container image extraction; rollout deployment-state checks for Progressing/Paused/Healthy phases; topology action creator output shapes including encoded cta.href; and feature-flag enablement helper verification.

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: establishing unit test infrastructure with inline snapshot tests for the project.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing the Jest setup, mock infrastructure, test coverage areas, and implementation rationale.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

@codecov-commenter

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

Thanks for integrating Codecov - We've got you covered ☂️

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
.github/workflows/unit-tests.yml (1)

13-13: 💤 Low value

Consider pinning actions to commit SHAs and setting persist-credentials: false.

For enhanced supply chain security:

  1. Pin actions to specific commit SHAs instead of version tags (e.g., actions/checkout@<commit-sha> instead of @v4)
  2. Add persist-credentials: false to the checkout step to prevent credentials from persisting in .git/config

These are defense-in-depth measures against potential action tag manipulation and credential leakage through artifacts.

🔒 Example of hardened checkout step
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+        with:
+          persist-credentials: false
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/unit-tests.yml at line 13, Replace the loose
actions/checkout@v4 reference with a pinned commit SHA (use the specific commit
hash for actions/checkout you want) and add the checkout input
persist-credentials: false; specifically update the checkout step that currently
uses "actions/checkout@v4" to use "actions/checkout@<commit-sha>" and include
the key persist-credentials: false so credentials are not persisted to
.git/config.

Source: Linters/SAST tools

__mocks__/patternfly-react-tokens.ts (1)

1-5: 💤 Low value

Simplify redundant CommonJS exports.

Lines 4–5 export the same token object via module.exports after the ES6 default export (line 3). Jest handles both import styles correctly with just the ES6 export; the CommonJS assignments are redundant and can be removed.

Optional: Simplify to ES6-only export
 const token = { name: 'mock-token', value: '`#000000`', var: 'var(--mock-token)' };
 
 export default token;
-module.exports = token;
-module.exports.default = token;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@__mocks__/patternfly-react-tokens.ts` around lines 1 - 5, The mock exports
duplicate the ES module default by also assigning module.exports and
module.exports.default; remove the redundant CommonJS lines so only the ES6
export remains (keep the const token = { ... } and the export default token),
ensuring the symbol token and the export default token line are preserved and
delete the module.exports = token and module.exports.default = token
assignments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@__mocks__/patternfly-react-tokens.ts`:
- Around line 1-5: The mock exports duplicate the ES module default by also
assigning module.exports and module.exports.default; remove the redundant
CommonJS lines so only the ES6 export remains (keep the const token = { ... }
and the export default token), ensuring the symbol token and the export default
token line are preserved and delete the module.exports = token and
module.exports.default = token assignments.

In @.github/workflows/unit-tests.yml:
- Line 13: Replace the loose actions/checkout@v4 reference with a pinned commit
SHA (use the specific commit hash for actions/checkout you want) and add the
checkout input persist-credentials: false; specifically update the checkout step
that currently uses "actions/checkout@v4" to use "actions/checkout@<commit-sha>"
and include the key persist-credentials: false so credentials are not persisted
to .git/config.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 5e16eca8-e1c2-466a-a862-2c820c6e8e25

📥 Commits

Reviewing files that changed from the base of the PR and between 05c5379 and 0e7f2a3.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (37)
  • .github/workflows/unit-tests.yml
  • .gitignore
  • __mocks__/dynamic-plugin-sdk.tsx
  • __mocks__/json-schema.ts
  • __mocks__/patternfly-react-core.tsx
  • __mocks__/patternfly-react-icons.tsx
  • __mocks__/patternfly-react-table.tsx
  • __mocks__/patternfly-react-tokens.ts
  • __mocks__/patternfly-react-topology.ts
  • __mocks__/react-i18next.ts
  • __mocks__/style-mock.ts
  • jest.config.ts
  • package.json
  • src/gitops/Revision/Revision.test.tsx
  • src/gitops/Statuses/HealthStatus.test.tsx
  • src/gitops/Statuses/OperationState.test.tsx
  • src/gitops/Statuses/SyncStatus.test.tsx
  • src/gitops/components/graph/utils.test.ts
  • src/gitops/components/rollout/revisions/ReplicaSetInfo.test.ts
  • src/gitops/components/rollout/utils/rollout-utils.test.ts
  • src/gitops/components/shared/MetadataLabels/MetadataLabels.test.tsx
  • src/gitops/components/shared/pod-utils.test.ts
  • src/gitops/services/ArgoCD.test.ts
  • src/gitops/topology/actions/creators.test.ts
  • src/gitops/utils/components/ActionDropDown/ActionDropDown.test.tsx
  • src/gitops/utils/components/ActionDropDownItem/ActionDropDownItem.test.tsx
  • src/gitops/utils/components/ExternalLink/ExternalLink.test.tsx
  • src/gitops/utils/components/OwnerReferences/OwnerReferences.test.tsx
  • src/gitops/utils/components/toggles/toggles.test.tsx
  • src/gitops/utils/gitops.test.ts
  • src/gitops/utils/project-utils.test.ts
  • src/gitops/utils/stringHelpers.test.ts
  • src/gitops/utils/urls.test.ts
  • src/gitops/utils/utils.test.ts
  • src/plugin/import/badges/TechPreviewBadge.test.tsx
  • src/plugin/status/icons.test.tsx
  • src/plugin/utils/flags/enableGitOpsDynamicFlag.test.ts

Set up Jest with ts-jest, jsdom, and module mocks for PatternFly,
OpenShift Console SDK, and react-i18next. All tests use
toMatchInlineSnapshot() for zero-friction maintenance (jest -u).

24 test suites, 144 tests, 203 inline snapshots covering utility
functions, service layer, and React components.

Adds a GitHub Actions workflow to run tests and upload coverage
to Codecov with the unit-tests flag.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Adam Saleh <adam@asaleh.net>
@AdamSaleh AdamSaleh force-pushed the add-unit-test-coverage branch from 0e7f2a3 to fd94b45 Compare June 12, 2026 06:15

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/gitops/utils/components/ActionDropDown/ActionDropDown.test.tsx (1)

5-39: ⚡ Quick win

Snapshot scope is too brittle and misses the dropdown’s core behavior contract.

These tests currently lock mock serialization details (e.g., popperProps="[object Object]") and only validate the closed render path, but they don’t verify the first-open onLazyClick contract from ActionDropDown.tsx. Prefer semantic assertions for stable DOM signals and add one behavior-focused test for onLazyClick firing on first open.

As per coding guidelines, “Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/gitops/utils/components/ActionDropDown/ActionDropDown.test.tsx` around
lines 5 - 39, The tests in ActionDropDown.test.tsx use fragile full HTML
snapshots (including popperProps) and miss the behavioral contract for the
first-open lazy-loading; update the tests to use semantic assertions instead of
inline snapshots for ActionsDropdown (check presence/attributes of the toggle
button and absence/presence of menu items) and add a behavior test that mounts
ActionsDropdown with a jest.fn() onLazyClick, simulates a user click on the
toggle (using fireEvent or userEvent) to open the dropdown, and asserts that the
onLazyClick handler (referenced as onLazyClick in
ActionDropDown/ActionsDropdown) is called exactly once on the first open; remove
or avoid asserting serialized popperProps and focus on stable DOM signals like
data-testid="dropdown" and visible menu items.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/unit-tests.yml:
- Line 13: Replace mutable action tags with pinned commit SHAs for every `uses:`
entry that currently references a floating tag (e.g., `actions/checkout@v4`,
`actions/setup-node@v5`, and the other `uses:` entry at line 24) by looking up
the corresponding official action repository and substituting the full immutable
commit SHA (e.g., `actions/checkout@<full-sha>`). Update each `uses:` reference
in the workflow to the exact commit SHA while preserving the existing inputs and
behavior so CI execution is stable and supply-chain hardened.
- Line 13: Update the actions/checkout step (actions/checkout@v4) to disable
credential persistence by adding persist-credentials: false and restrict the
workflow job permissions to the minimal scopes needed for npm/yarn (e.g., remove
write or repo-level tokens and grant only contents: read and packages: read if
necessary) so that running dependency-managed scripts like yarn install and yarn
test:coverage cannot persist or exfiltrate the checkout token.

---

Nitpick comments:
In `@src/gitops/utils/components/ActionDropDown/ActionDropDown.test.tsx`:
- Around line 5-39: The tests in ActionDropDown.test.tsx use fragile full HTML
snapshots (including popperProps) and miss the behavioral contract for the
first-open lazy-loading; update the tests to use semantic assertions instead of
inline snapshots for ActionsDropdown (check presence/attributes of the toggle
button and absence/presence of menu items) and add a behavior test that mounts
ActionsDropdown with a jest.fn() onLazyClick, simulates a user click on the
toggle (using fireEvent or userEvent) to open the dropdown, and asserts that the
onLazyClick handler (referenced as onLazyClick in
ActionDropDown/ActionsDropdown) is called exactly once on the first open; remove
or avoid asserting serialized popperProps and focus on stable DOM signals like
data-testid="dropdown" and visible menu items.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: d91bc223-224d-47b3-b3c5-b16349c2fe97

📥 Commits

Reviewing files that changed from the base of the PR and between 0e7f2a3 and fd94b45.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (37)
  • .github/workflows/unit-tests.yml
  • .gitignore
  • __mocks__/dynamic-plugin-sdk.tsx
  • __mocks__/json-schema.ts
  • __mocks__/patternfly-react-core.tsx
  • __mocks__/patternfly-react-icons.tsx
  • __mocks__/patternfly-react-table.tsx
  • __mocks__/patternfly-react-tokens.ts
  • __mocks__/patternfly-react-topology.ts
  • __mocks__/react-i18next.ts
  • __mocks__/style-mock.ts
  • jest.config.ts
  • package.json
  • src/gitops/Revision/Revision.test.tsx
  • src/gitops/Statuses/HealthStatus.test.tsx
  • src/gitops/Statuses/OperationState.test.tsx
  • src/gitops/Statuses/SyncStatus.test.tsx
  • src/gitops/components/graph/utils.test.ts
  • src/gitops/components/rollout/revisions/ReplicaSetInfo.test.ts
  • src/gitops/components/rollout/utils/rollout-utils.test.ts
  • src/gitops/components/shared/MetadataLabels/MetadataLabels.test.tsx
  • src/gitops/components/shared/pod-utils.test.ts
  • src/gitops/services/ArgoCD.test.ts
  • src/gitops/topology/actions/creators.test.ts
  • src/gitops/utils/components/ActionDropDown/ActionDropDown.test.tsx
  • src/gitops/utils/components/ActionDropDownItem/ActionDropDownItem.test.tsx
  • src/gitops/utils/components/ExternalLink/ExternalLink.test.tsx
  • src/gitops/utils/components/OwnerReferences/OwnerReferences.test.tsx
  • src/gitops/utils/components/toggles/toggles.test.tsx
  • src/gitops/utils/gitops.test.ts
  • src/gitops/utils/project-utils.test.ts
  • src/gitops/utils/stringHelpers.test.ts
  • src/gitops/utils/urls.test.ts
  • src/gitops/utils/utils.test.ts
  • src/plugin/import/badges/TechPreviewBadge.test.tsx
  • src/plugin/status/icons.test.tsx
  • src/plugin/utils/flags/enableGitOpsDynamicFlag.test.ts
✅ Files skipped from review due to trivial changes (3)
  • .gitignore
  • mocks/patternfly-react-core.tsx
  • mocks/patternfly-react-table.tsx
🚧 Files skipped from review as they are similar to previous changes (30)
  • mocks/style-mock.ts
  • src/plugin/utils/flags/enableGitOpsDynamicFlag.test.ts
  • src/gitops/utils/components/OwnerReferences/OwnerReferences.test.tsx
  • src/gitops/topology/actions/creators.test.ts
  • src/gitops/utils/stringHelpers.test.ts
  • src/gitops/components/shared/pod-utils.test.ts
  • src/gitops/components/rollout/utils/rollout-utils.test.ts
  • mocks/patternfly-react-topology.ts
  • src/gitops/utils/urls.test.ts
  • src/gitops/utils/components/toggles/toggles.test.tsx
  • src/gitops/components/shared/MetadataLabels/MetadataLabels.test.tsx
  • mocks/react-i18next.ts
  • mocks/json-schema.ts
  • src/gitops/components/rollout/revisions/ReplicaSetInfo.test.ts
  • src/gitops/Statuses/OperationState.test.tsx
  • src/plugin/status/icons.test.tsx
  • src/gitops/Revision/Revision.test.tsx
  • mocks/patternfly-react-tokens.ts
  • src/gitops/utils/project-utils.test.ts
  • jest.config.ts
  • src/gitops/components/graph/utils.test.ts
  • src/gitops/utils/gitops.test.ts
  • src/gitops/Statuses/SyncStatus.test.tsx
  • src/gitops/utils/components/ExternalLink/ExternalLink.test.tsx
  • src/plugin/import/badges/TechPreviewBadge.test.tsx
  • mocks/patternfly-react-icons.tsx
  • src/gitops/utils/utils.test.ts
  • src/gitops/services/ArgoCD.test.ts
  • package.json
  • mocks/dynamic-plugin-sdk.tsx

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pin all GitHub Actions to immutable commit SHAs.

Line 13, Line 15, and Line 24 use mutable tags (@v4, @v5). That leaves CI behavior vulnerable to upstream tag movement or supply-chain compromise. Pin each uses: reference to a full commit SHA.

Suggested hardening patch
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<full-commit-sha>

-      - uses: actions/setup-node@v4
+      - uses: actions/setup-node@<full-commit-sha>

-      - uses: codecov/codecov-action@v5
+      - uses: codecov/codecov-action@<full-commit-sha>

Also applies to: 15-15, 24-24

🧰 Tools
🪛 zizmor (1.25.2)

[warning] 13-13: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 13-13: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/unit-tests.yml at line 13, Replace mutable action tags
with pinned commit SHAs for every `uses:` entry that currently references a
floating tag (e.g., `actions/checkout@v4`, `actions/setup-node@v5`, and the
other `uses:` entry at line 24) by looking up the corresponding official action
repository and substituting the full immutable commit SHA (e.g.,
`actions/checkout@<full-sha>`). Update each `uses:` reference in the workflow to
the exact commit SHA while preserving the existing inputs and behavior so CI
execution is stable and supply-chain hardened.

Source: Linters/SAST tools


⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Disable checkout credential persistence before running dependency-controlled scripts.

On Line 13, actions/checkout defaults to persisting the token in local git config. Since Line 20/22 execute package-managed scripts (yarn install, yarn test:coverage), this unnecessarily enlarges token exfiltration risk. Set persist-credentials: false and scope job permissions minimally.

Suggested hardening patch
+permissions:
+  contents: read
+
 jobs:
   test:
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@<full-commit-sha>
+        with:
+          persist-credentials: false
🧰 Tools
🪛 zizmor (1.25.2)

[warning] 13-13: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 13-13: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/unit-tests.yml at line 13, Update the actions/checkout
step (actions/checkout@v4) to disable credential persistence by adding
persist-credentials: false and restrict the workflow job permissions to the
minimal scopes needed for npm/yarn (e.g., remove write or repo-level tokens and
grant only contents: read and packages: read if necessary) so that running
dependency-managed scripts like yarn install and yarn test:coverage cannot
persist or exfiltrate the checkout token.

Source: Linters/SAST tools

getResourceNodeSyncStatus,
} from './utils';

describe('kindToAbbr', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This looks like a good test of this particular function

});
});

describe('getTopologyNodeStatus', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is a good test possibly to prevent changes in what it returns in the future. eg. changing the return value inadvertantly will signify a 'breaking' change from what was the original expected value

});
});

describe('createSpacerNode', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Seems reasonable

@@ -0,0 +1,23 @@
import { isDeploying } from './rollout-utils';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Seems lik a good unit test for isDeploying

@@ -0,0 +1,73 @@
import { renderToStaticMarkup } from 'react-dom/server';
import Revision from './Revision';

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The test is missing the return of None, but this seems like a good start for provide a unit test.

I like the test for sha256 versusn non-sha256 revisions.

@@ -0,0 +1,28 @@
name: Unit Tests

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for doing this Adam. Similar to Argo CD, it uses jest as well.

I think we should keep what you have.

https://github.com/argoproj/argo-cd/blob/cc3165f4189243d7b9a627b07b60138ed80ca795/.github/workflows/ci-build.yaml#L353

@aali309

aali309 commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

LGTM. I think this is a good foundation to build on. Non-blocking but would help to have README testing section.
Thanks @AdamSaleh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Adam Saleh <adam@asaleh.net>
@AdamSaleh

Copy link
Copy Markdown
Member Author

@aali309 added that readme :)

@keithchong keithchong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@keithchong keithchong merged commit cdadfac into redhat-developer:main Jun 17, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants