Skip to content

Conversation

@sg00dwin
Copy link
Member

No description provided.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Nov 10, 2025
@openshift-ci-robot
Copy link
Contributor

openshift-ci-robot commented Nov 10, 2025

@sg00dwin: This pull request references CONSOLE-4605 which is a valid jira issue.

In response to this:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci bot requested review from cajieh and rhamilto November 10, 2025 18:47
@openshift-ci openshift-ci bot added the component/olm Related to OLM label Nov 10, 2025
@sg00dwin sg00dwin assigned sg00dwin and cajieh and unassigned sg00dwin Nov 10, 2025
@sg00dwin
Copy link
Member Author

QA Approver:
/assign @yapei

@sg00dwin
Copy link
Member Author

/test okd-scos-e2e-aws-ovn

@yapei
Copy link
Contributor

yapei commented Nov 12, 2025

went through the changes and all tests are passing in CI
/verified by frontend,yapei

@openshift-ci-robot openshift-ci-robot added the verified Signifies that the PR passed pre-merge verification criteria label Nov 12, 2025
@openshift-ci-robot
Copy link
Contributor

@yapei: This PR has been marked as verified by e2e-gcp-console,yapei.

In response to this:

/verified by e2e-gcp-console,yapei

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

Copy link
Contributor

@cajieh cajieh left a comment

Choose a reason for hiding this comment

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

@sg00dwin It looks good, except for a few comments I've added.
The test files should be moved to the tests subdirectory of the target directory. This will ensure consistency with other migrated tests and aligns with Console best practices.

Also, it appears that the following three tests are missing from the migration:

  1. packages/operator-lifecycle-manager/src/components/install-plan.spec.tsx
  2. packages/operator-lifecycle-manager/src/components/modals/uninstall-operator-modal.spec.tsx
  3. packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx

We can either include them in this PR or scope them into a new, small story for 'missing tests.' What do you think?"

jest.clearAllMocks();

installPlanApprovalModalProps = {
obj: _.cloneDeep(testSubscription),
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Could be simplified to a shallow copy using object spread: obj = { ...testCatalogSource }. Although not new.


expect(createYAML.find(ErrorBoundary).exists()).toBe(true);
expect(createYAML.find(ErrorBoundary).childAt(0).dive().find(CreateYAML).exists()).toBe(true);
expect(screen.getByText(new RegExp(testPackageManifest.metadata.name))).toBeInTheDocument();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
expect(screen.getByText(new RegExp(testPackageManifest.metadata.name))).toBeInTheDocument();
expect(screen.getByText(new RegExp(testPackageManifest.metadata.name))).toBeVisible();


expect(wrapper.find(DetailsPage).props().resources).toEqual([
expect(detailsPageProps.pages).toHaveLength(3);
Copy link
Contributor

Choose a reason for hiding this comment

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

This tests implementation details (how DetailsPage is called), not user behavior. I would make it a follow-up in the story to extend RTL tests.

Copy link
Member Author

Choose a reason for hiding this comment

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

wrapper = shallow(<CatalogSourceDetailsPage />);
mockDetailsPage.mockClear();
});

Copy link
Contributor

@cajieh cajieh Nov 12, 2025

Choose a reason for hiding this comment

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

Missing afterEach(jest.restoreAllMocks()) after using jest.spyOn()

Suggested change
afterEach(() => {
jest.restoreAllMocks();
});

@TheRealJon
Copy link
Member

/label px-approved
/label docs-approved

These are transparent test migrations with no px or docs impact.

@openshift-ci openshift-ci bot added px-approved Signifies that Product Support has signed off on this PR docs-approved Signifies that Docs has signed off on this PR labels Nov 13, 2025
@sg00dwin sg00dwin force-pushed the CONSOLE-4605-migration-to-RTL branch from 4c7cbda to 09e107d Compare November 17, 2025 16:01
@openshift-ci-robot openshift-ci-robot removed the verified Signifies that the PR passed pre-merge verification criteria label Nov 17, 2025
@sg00dwin sg00dwin force-pushed the CONSOLE-4605-migration-to-RTL branch from 09e107d to e40cc2e Compare November 18, 2025 17:20
@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

Walkthrough

Added many new test suites and refactored tests in operator-lifecycle-manager; simultaneously removed several legacy spec files. Changes are test-only (additions, deletions, and RTL migration of OperatorGroup tests); no production code or public API signatures were modified.

Changes

Cohort / File(s) Summary
New component tests (operator-lifecycle-manager)
frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/__tests__/operator-group.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/__tests__/package-manifest.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/__tests__/subscription.spec.tsx
Added comprehensive tests covering rendering, table rows, details pages, YAML flows, statuses, and resource wiring with extensive mocks for CatalogSource, CSVs, InstallPlans, OperatorGroup, PackageManifest, and Subscription components.
Deleted legacy component specs
frontend/packages/operator-lifecycle-manager/src/components/catalog-source.spec.tsx, .../clusterserviceversion.spec.tsx, .../install-plan.spec.tsx, .../package-manifest.spec.tsx, .../subscription.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/operand/create-operand.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx
Removed older/co-located test files that appear replaced by the new __tests__ variants.
New modal tests
frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/installplan-approval-modal.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/subscription-channel-modal.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/uninstall-operator-modal.spec.tsx
Added modal test suites validating UI rendering, form controls, channel/approval selection, and k8sUpdate/k8sDelete interactions and callbacks.
Deleted legacy modal specs
frontend/packages/operator-lifecycle-manager/src/components/modals/installplan-approval-modal.spec.tsx, .../subscription-channel-modal.spec.tsx, .../uninstall-operator-modal.spec.tsx
Removed older modal spec files replaced by the new __tests__ versions.
New operand tests
frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/create-operand.spec.tsx, frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/index.spec.tsx
Added tests for CreateOperand, OperandYAML, OperandTableRow, OperandStatus, OperandDetailsPage, ProvidedAPIsPage, and ProvidedAPIPage with mocks for models, watches, editors, and routing.
Removed old operand tests
frontend/packages/operator-lifecycle-manager/src/components/operand/create-operand.spec.tsx (deleted), frontend/packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx (deleted)
Deleted previous operand test suites (replaced by new __tests__ files).
OperatorGroup testing approach change
frontend/packages/operator-lifecycle-manager/src/components/__tests__/operator-group.spec.tsx
Migrated OperatorGroup tests from Enzyme shallow rendering to React Testing Library (renderWithProviders + screen queries); assertions updated from wrapper existence checks to DOM visibility/text assertions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

  • Focus areas:
    • Validate import/require path updates and that removed files are not referenced elsewhere.
    • Confirm React Testing Library assertions correctly replace previous Enzyme semantics (OperatorGroup).
    • Inspect modal tests for correct mocks and expected k8s payload shapes and sequencing.
    • Spot-check that deleted tests are fully replaced by new tests and no production files were accidentally removed.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link

@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: 4

🧹 Nitpick comments (7)
frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/uninstall-operator-modal.spec.tsx (1)

66-113: Test structure for k8sKill calls is clear but could verify call ordering.

Tests 2 and 3 both render the component, submit the form, wait for exactly 2 calls to k8sKill, and then validate details of one call each. This is a reasonable pattern for testing independent aspects of behavior.

However, if call ordering matters (subscription deleted before CSV), consider consolidating into a single test that validates the sequence, or explicitly verify call order using toHaveNthReturnedWith / mock.calls inspection.

frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/subscription-channel-modal.spec.tsx (1)

83-106: Async update & close behavior well covered; minor duplication only

The pattern of selecting the nightly radio, submitting the form, and using waitFor around k8sUpdate and close expectations properly exercises the async flow and payload shape. The expectations against SubscriptionModel and spec.channel: 'nightly' are precise and valuable.

There is a bit of repeated “select nightly + submit form” boilerplate across the two tests; if this pattern grows elsewhere, consider extracting a tiny helper (e.g., selectChannelAndSubmit('nightly')) to keep things DRY, but it’s not required for this PR.

Also applies to: 108-122

frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/installplan-approval-modal.spec.tsx (1)

93-96: Consider a more robust form selection pattern.

Using .closest('form') combined with an optional check can mask test failures. If the form isn't found, the test silently skips the submission and may produce a false positive.

Consider one of these alternatives:

  1. Add a data-testid to the form element and query it directly:
-    const form = screen.getByRole('radio', { name: /manual/i }).closest('form');
-    if (form) {
-      fireEvent.submit(form);
-    }
+    const form = screen.getByTestId('install-plan-approval-form');
+    fireEvent.submit(form);
  1. Assert the form exists before submission:
     const form = screen.getByRole('radio', { name: /manual/i }).closest('form');
-    if (form) {
-      fireEvent.submit(form);
-    }
+    expect(form).toBeInTheDocument();
+    fireEvent.submit(form!);

Also applies to: 123-126, 145-148

frontend/packages/operator-lifecycle-manager/src/components/__tests__/subscription.spec.tsx (2)

156-353: Consider adding consistent cleanup to all describe blocks.

Some describe blocks have beforeEach/afterEach cleanup (lines 70-76, 261-263, 308-315), while others don't (SubscriptionStatus, SubscriptionsList, SubscriptionsPage). For test isolation and to prevent mock state pollution between tests, consider adding consistent cleanup:

 describe('SubscriptionStatus', () => {
+  beforeEach(() => {
+    jest.clearAllMocks();
+  });
+
+  afterEach(() => {
+    jest.restoreAllMocks();
+  });
+
   it('renders "Upgrade available" when update is available', () => {

Apply similar cleanup to SubscriptionsList and SubscriptionsPage describe blocks.


205-205: Consider avoiding .WrappedComponent if possible.

Accessing .WrappedComponent exposes internal implementation details and makes the test fragile to changes in how the component is wrapped (e.g., HOC changes). If the component can be tested without accessing the wrapped version, that would be more maintainable. However, this is acceptable for test migrations where compatibility with existing patterns is needed.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/package-manifest.spec.tsx (1)

55-158: Tests are comprehensive and working correctly.

The test suite provides good coverage of the PackageManifestTableRow component with proper mock lifecycle management. All assertions are meaningful and the tests are passing in CI.

Optional: Consider reducing repetition.

The table wrapper structure is repeated across all four tests (lines 68-80, 96-108, 117-129, 140-152). Extracting this to a helper function could improve maintainability:

const renderPackageManifestRow = (obj, customData, columns = []) => {
  return renderWithProviders(
    <table>
      <tbody>
        <tr>
          <PackageManifestTableRow
            obj={obj}
            customData={customData}
            columns={columns}
          />
        </tr>
      </tbody>
    </table>,
  );
};

Optional: Clarify test description.

The test at line 136 could have a clearer description. It's testing fallback behavior when catalogSource is not provided in customData, not when the catalog source doesn't exist. Consider: "renders column for catalog source using package manifest name when catalogSource is not in customData".

frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/index.spec.tsx (1)

1-73: Well-structured mock setup for RTL migration.

The mocking strategy is comprehensive and appropriate for testing these operand components. The typed mock reference for DetailsPage (line 72) is particularly good practice for inspecting mock calls later.

Consider adding an afterEach block to restore mocks for consistency with the create-operand.spec.tsx file:

+afterEach(() => {
+  jest.restoreAllMocks();
+});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between f0cb82b and e40cc2e.

📒 Files selected for processing (21)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/operator-group.spec.tsx (8 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/package-manifest.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/subscription.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/catalog-source.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/clusterserviceversion.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/install-plan.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/installplan-approval-modal.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/subscription-channel-modal.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/uninstall-operator-modal.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/modals/installplan-approval-modal.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/modals/subscription-channel-modal.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/modals/uninstall-operator-modal.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/create-operand.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/index.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/operand/create-operand.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/package-manifest.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/subscription.spec.tsx (0 hunks)
💤 Files with no reviewable changes (10)
  • frontend/packages/operator-lifecycle-manager/src/components/subscription.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/modals/uninstall-operator-modal.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/catalog-source.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/install-plan.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/operand/create-operand.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/modals/installplan-approval-modal.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/package-manifest.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/modals/subscription-channel-modal.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/clusterserviceversion.spec.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/index.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/installplan-approval-modal.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/subscription-channel-modal.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/uninstall-operator-modal.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/subscription.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/package-manifest.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/operator-group.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/create-operand.spec.tsx
🔇 Additional comments (30)
frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/uninstall-operator-modal.spec.tsx (2)

1-34: Well-structured RTL test suite with sound mock strategy.

The test migration follows React Testing Library best practices effectively: proper use of renderWithProviders, semantic queries (getByRole, getByText), and correct async handling with waitFor. Mock configuration is isolated in beforeEach and resets between tests.

One minor maintainability note: the k8sGetResource mock (line 32–34) appears unused in the test suite. Consider removing it if the component doesn't invoke this utility, or verify it's being called indirectly through the component under test.


128-137: Modal close callback test is clean; verify no edge-case handling needed.

The test correctly verifies that the close callback is invoked exactly once after form submission. Ensure the component has no error-handling flow where close should not be called (e.g., validation errors or k8sKill failures). If error paths exist, consider a companion test for those scenarios.

frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/subscription-channel-modal.spec.tsx (4)

20-65: Solid, isolated test setup

Cloning the subscription and package fixtures plus resetting mocks in beforeEach gives each test a clean, independent state and avoids cross‑test mutation. This setup looks good and maintainable.


67-72: Good basic render smoke test

Checking the modal title and primary Save button via accessible queries is a good, low‑cost smoke test that will catch obvious regressions in the modal wiring.


74-81: Accessible channel options coverage

Verifying that a radio exists per channel and asserting by accessible name (stable, nightly) exercises both data‑driven rendering and a11y labels, which is exactly what you want here.


124-141: Submit button state tests are effective

The tests that ensure Save is initially disabled and becomes enabled only after changing the channel give good confidence that users can’t submit a no‑op change and that the UI reacts correctly to selection changes.

frontend/packages/operator-lifecycle-manager/src/components/modals/__tests__/installplan-approval-modal.spec.tsx (1)

1-154: Well-structured RTL migration with comprehensive coverage.

The test suite successfully migrates from Enzyme to React Testing Library with good practices:

  • Proper use of renderWithProviders and RTL queries
  • Comprehensive coverage of modal rendering, radio selection, and form submission
  • Correct mocking strategy for dependencies
  • Tests both Subscription and InstallPlan update scenarios
  • Proper cleanup with beforeEach/afterEach
frontend/packages/operator-lifecycle-manager/src/components/__tests__/subscription.spec.tsx (1)

1-353: Test migration looks good overall.

The migration from Enzyme to React Testing Library is well-executed. The tests appropriately verify component behavior by checking both mock interactions and rendered output. The comprehensive mocking strategy ensures tests remain fast and focused on the subscription components.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/package-manifest.spec.tsx (2)

1-29: LGTM! Clean mock setup and imports.

The mocking strategy is well-structured, with proper isolation of component dependencies. The ResourceLink mock correctly preserves the actual implementation while allowing override, and typed mock references improve type safety.


31-53: LGTM! Header tests are clear and focused.

The tests effectively verify the table header configuration with appropriate assertions.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx (3)

172-205: Well-structured logo component tests.

These tests effectively verify the image rendering logic, fallback behavior, and text content display with strong, specific assertions.


237-316: Well-structured subscription tests with comprehensive scenario coverage.

The tests effectively cover the empty state, subscription details rendering, and complex PackageManifest matching logic with strong assertions.


207-209: Good practice: documenting test removal rationale.

The comments explaining why certain tests were removed (complexity, AsyncComponent mocking requirements, integration test coverage) demonstrate thoughtful decision-making about appropriate test boundaries.

Also applies to: 228-230, 232-236, 318-321

frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/index.spec.tsx (4)

74-103: LGTM! Clean RTL assertions for table row rendering.

The tests properly verify that the OperandTableRow component renders the expected operand metadata, and the table wrapper structure is appropriate for testing a table row component.


105-195: Excellent coverage of OperandStatus display logic.

The test suite thoroughly covers the status field priority hierarchy (status → phase → state → condition → dash) and verifies both labels and values. The use of getByTestId for status text assertions is appropriate.


197-231: LGTM! Effective verification of DetailsPage configuration.

The tests properly mock routing dependencies and verify the DetailsPage receives the correct tab configuration. The pattern of inspecting mock calls to verify component props is appropriate for this scenario.


233-282: LGTM! Clean tests for CRD-based UI rendering.

The tests appropriately verify that the UI adapts based on the number of CRDs in the CSV. Good use of cloneDeep (line 248) to avoid mutating the shared test fixture.

frontend/packages/operator-lifecycle-manager/src/components/operand/__tests__/create-operand.spec.tsx (3)

1-43: LGTM! Comprehensive mock setup for operand creation tests.

The mock configuration properly isolates the components under test. The type assertions on lines 41-42 using as unknown as jest.Mock are acceptable for test mocks where the actual implementation types don't match the mock interface.


44-150: Excellent test coverage of CreateOperand configuration.

The test suite thoroughly verifies that SyncedEditor receives the correct configuration based on different inputs. The test for alm-examples annotation parsing (lines 90-131) is particularly comprehensive, ensuring sample data is correctly extracted and passed to the editor.


152-216: LGTM! Thorough verification of OperandYAML prop handling.

The test suite comprehensively covers the OperandYAML component's behavior, including conditional prop passing (resourceObjPath based on the next prop) and default values. The tests effectively verify that the component correctly forwards props to CreateYAML.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/operator-group.spec.tsx (2)

19-50: Excellent RTL migration!

The HOC tests properly verify component behavior using RTL queries and assertions. Good use of both positive (getByText, toBeVisible) and negative (queryByText, not.toBeInTheDocument) checks.


52-264: LGTM!

The utility function tests remain focused on logic verification with appropriate test coverage for edge cases and various operator group configurations.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx (5)

42-136: Well-structured table row tests.

Good coverage of rendering scenarios with proper table markup wrapping and RTL queries to verify visible content.


138-220: Tests verify component configuration.

These tests confirm the correct setup of list and page components. While they test implementation details, this approach is reasonable for migration work.


265-342: Solid approval flow testing.

Good coverage of the approval workflow including empty states, button visibility, and API interaction verification with proper async handling.


354-403: Appropriate conditional rendering tests.

Tests correctly verify that the preview link appears only when manual approval is required.


405-427: Page configuration verified.

The test confirms the details page is set up with the expected navigation tabs.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx (3)

92-107: Clean rendering test.

The test verifies that key catalog source information is visible to users.


109-157: Details page tests with proper cleanup.

The afterEach block correctly restores mocks. The TODO comment at line 126 appropriately acknowledges the implementation-detail testing approach for potential future refactoring.


159-219: Excellent YAML creation tests.

Good coverage of both loading and loaded states, with verification of YAML content including package name, channel, source, and CSV information.

Comment on lines 129 to 158
it('renders managed namespace', () => {
renderWithProviders(<ClusterServiceVersionTableRow {...clusterServiceVersionTableRowProps} />);

// The component should render without errors
expect(screen.getByText(testClusterServiceVersion.spec.displayName)).toBeVisible();
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Strengthen test assertion to actually verify namespace rendering.

The test claims to verify namespace rendering but only asserts that the display name is visible. This doesn't confirm the namespace is actually rendered.

Consider asserting the presence of the namespace text:

  it('renders managed namespace', () => {
    renderWithProviders(<ClusterServiceVersionTableRow {...clusterServiceVersionTableRowProps} />);

-    // The component should render without errors
-    expect(screen.getByText(testClusterServiceVersion.spec.displayName)).toBeVisible();
+    expect(screen.getByText(testClusterServiceVersion.metadata.namespace)).toBeVisible();
  });
📝 Committable suggestion

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

Suggested change
it('renders managed namespace', () => {
renderWithProviders(<ClusterServiceVersionTableRow {...clusterServiceVersionTableRowProps} />);
// The component should render without errors
expect(screen.getByText(testClusterServiceVersion.spec.displayName)).toBeVisible();
});
it('renders managed namespace', () => {
renderWithProviders(<ClusterServiceVersionTableRow {...clusterServiceVersionTableRowProps} />);
expect(screen.getByText(testClusterServiceVersion.metadata.namespace)).toBeVisible();
});
🤖 Prompt for AI Agents
In
frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx
around lines 129 to 134, the test labeled "renders managed namespace" only
asserts the displayName is visible and doesn't verify the namespace; update the
test to assert that the expected namespace string from the test data is rendered
(e.g., use screen.getByText or getByRole with the namespace value) so the test
fails if the namespace is missing, ensuring the component actually renders the
namespace.

@sg00dwin
Copy link
Member Author

sg00dwin commented Nov 18, 2025

@sg00dwin It looks good, except for a few comments I've added. The test files should be moved to the tests subdirectory of the target directory. This will ensure consistency with other migrated tests and aligns with Console best practices.

Also, it appears that the following three tests are missing from the migration:

  1. packages/operator-lifecycle-manager/src/components/install-plan.spec.tsx
  2. packages/operator-lifecycle-manager/src/components/modals/uninstall-operator-modal.spec.tsx
  3. packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx

We can either include them in this PR or scope them into a new, small story for 'missing tests.' What do you think?"

@cajieh I have added these 3 test files to the commit. And addressed your latest feedback changes.

@cajieh
Copy link
Contributor

cajieh commented Nov 18, 2025

@sg00dwin It looks good, except for a few comments I've added. The test files should be moved to the tests subdirectory of the target directory. This will ensure consistency with other migrated tests and aligns with Console best practices.
Also, it appears that the following three tests are missing from the migration:

  1. packages/operator-lifecycle-manager/src/components/install-plan.spec.tsx
  2. packages/operator-lifecycle-manager/src/components/modals/uninstall-operator-modal.spec.tsx
  3. packages/operator-lifecycle-manager/src/components/operand/index.spec.tsx

We can either include them in this PR or scope them into a new, small story for 'missing tests.' What do you think?"

@cajieh I have added these 3 test files to the commit. And addressed your latest feedback changes.

@sg00dwin Added a few more comments.
I will opened the story created for the missing tests since they are addressed in this PR.
Thank you.

});

// ClusterServiceVersionList tests removed - complex component requiring extensive mocking
// Original Enzyme tests verified table header configuration which are implementation details
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove the comment since it is capture in the Extend RTL test story ticket.

// ClusterServiceVersionDetails tests removed - hybrid component uses AsyncComponent
// for MarkdownView and multiple complex child components requiring extensive mocking.
// Original Enzyme tests heavily tested implementation details (finding specific DOM nodes,
// checking props passed to children). User-facing behavior is tested via integration tests.
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove the comments.

// ClusterServiceVersionDetailsPage tests removed - container component with complex
// hook dependencies (useClusterServiceVersion, useK8sWatchResource, useAccessReview).
// Original Enzyme tests verified DetailsPage props configuration which are implementation
// details. Page-level behavior is tested via Cypress integration tests.
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's remove the comments.

const radios = screen.getAllByRole('radio');
expect(radios).toHaveLength(2);
expect(screen.getByRole('radio', { name: /automatic \(default\)/i })).toBeVisible();
expect(screen.getByRole('radio', { name: /manual/i })).toBeVisible();
Copy link
Contributor

Choose a reason for hiding this comment

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

Better to use exact text matches, which makes the tests more precise and performant

Suggested change
expect(screen.getByRole('radio', { name: /manual/i })).toBeVisible();
expect(screen.getByRole('radio', { name: 'Automatic (default)' })).toBeVisible();
expect(screen.getByRole('radio', { name: 'Manual' })).toBeVisible();

Comment on lines 63 to 67
const automaticRadio = screen.getByRole('radio', { name: /automatic \(default\)/i });
const manualRadio = screen.getByRole('radio', { name: /manual/i });

expect(automaticRadio).toBeChecked();
expect(manualRadio).not.toBeChecked();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const automaticRadio = screen.getByRole('radio', { name: /automatic \(default\)/i });
const manualRadio = screen.getByRole('radio', { name: /manual/i });
expect(automaticRadio).toBeChecked();
expect(manualRadio).not.toBeChecked();
expect(screen.getByRole('radio', { name: 'Automatic (default)' })).toBeChecked();
expect(screen.getByRole('radio', { name: 'Manual' })).toBeChecked();

Comment on lines 69 to 70
const form = screen.getByRole('form');
fireEvent.submit(form);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const form = screen.getByRole('form');
fireEvent.submit(form);
fireEvent.submit(screen.getByRole('form'));

Comment on lines 91 to 92
const form = screen.getByRole('form');
fireEvent.submit(form);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const form = screen.getByRole('form');
fireEvent.submit(form);
fireEvent.submit(screen.getByRole('form'));

Comment on lines 120 to 121
const form = screen.getByRole('form');
fireEvent.submit(form);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const form = screen.getByRole('form');
fireEvent.submit(form);
fireEvent.submit(screen.getByRole('form'));

it('renders create button with correct text for single CRD', () => {
renderWithProviders(<ProvidedAPIPage kind="TestResource" csv={testClusterServiceVersion} />);

expect(screen.getByText('Create Test Resource')).toBeInTheDocument();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
expect(screen.getByText('Create Test Resource')).toBeInTheDocument();
expect(screen.getByText('Create Test Resource')).toBeVisible()

Comment on lines 62 to 63
expect(screen.getByText('Uninstall Operator?')).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Uninstall' })).toBeInTheDocument();
Copy link
Contributor

Choose a reason for hiding this comment

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

Prefer .toBeVisible() for any element a user is expected to see or interact with, and the .toBeInTheDocument() to verify structural elements or to check that a component has rendered or been removed conditionally.

Suggested change
expect(screen.getByText('Uninstall Operator?')).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Uninstall' })).toBeInTheDocument();
expect(screen.getByText('Uninstall Operator?')).toBeVisible()
expect(screen.getByRole('button', { name: 'Uninstall' })).toBeVisible()

The change is required across several files.


renderWithProviders(<InstallPlanPreview obj={manualPlan} />);

expect(screen.getByRole('button', { name: /approve/i })).toBeVisible();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
expect(screen.getByRole('button', { name: /approve/i })).toBeVisible();
expect(screen.getByRole('button', { name: 'Approve' })).toBeVisible();


renderWithProviders(<InstallPlanPreview obj={manualPlan} />);

expect(screen.getByRole('button', { name: /deny/i })).toBeVisible();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
expect(screen.getByRole('button', { name: /deny/i })).toBeVisible();
expect(screen.getByRole('button', { name: 'Deny' })).toBeVisible();

renderWithProviders(<InstallPlanPreview obj={installPlan} />);

// Check that preview functionality is available for components with status 'Unknown'
const previewButtons = screen.queryAllByRole('button', { name: /preview/i });
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
const previewButtons = screen.queryAllByRole('button', { name: /preview/i });
const previewButtons = screen.queryAllByRole('button', { name: 'Preview' });


renderWithProviders(<InstallPlanDetails obj={automaticPlan} />);

expect(screen.queryByRole('button', { name: /preview installplan/i })).not.toBeInTheDocument();
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
expect(screen.queryByRole('button', { name: /preview installplan/i })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Preview Installplan' })).not.toBeInTheDocument();

@sg00dwin sg00dwin force-pushed the CONSOLE-4605-migration-to-RTL branch from e40cc2e to 1987dc6 Compare November 20, 2025 17:44
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 20, 2025
Convert 8 test files from Enzyme to RTL with improved accessibility testing and behavioral assertions.

Add new tests to replace previous disabled tests

Assisted-by Claude
@sg00dwin sg00dwin force-pushed the CONSOLE-4605-migration-to-RTL branch from 1987dc6 to e19a479 Compare November 20, 2025 19:34
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Nov 20, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx (1)

126-126: Remove TODO comment as requested in previous review.

Per cajieh's previous feedback, this TODO comment should be removed since the work is tracked in the follow-up story (ODC-7820).

Apply this diff:

-  // TODO: Refactor to test user behavior instead of implementation details
🧹 Nitpick comments (3)
frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx (2)

101-224: Consider extracting the repetitive table wrapper into a render helper.

All eight tests in this suite repeat the same table structure wrapper. Extracting this to a helper function would improve maintainability and reduce duplication.

Consider adding a helper function before the tests:

const renderTableRow = (props: ClusterServiceVersionTableRowProps) => {
  return renderWithProviders(
    <table>
      <tbody>
        <tr>
          <ClusterServiceVersionTableRow {...props} />
        </tr>
      </tbody>
    </table>,
  );
};

Then simplify each test:

  it('renders component wrapped in ErrorBoundary', () => {
-    renderWithProviders(
-      <table>
-        <tbody>
-          <tr>
-            <ClusterServiceVersionTableRow {...clusterServiceVersionTableRowProps} />
-          </tr>
-        </tbody>
-      </table>,
-    );
+    renderTableRow(clusterServiceVersionTableRowProps);

    expect(screen.getByText(testClusterServiceVersion.spec.displayName)).toBeVisible();
  });

274-278: Consider adding a test for the positive case (canCreate=true).

The test suite only verifies that the create link is absent when canCreate is false, but doesn't verify it appears when canCreate is true. Adding a positive test case would improve coverage.

Example test to add:

it('renders create link when canCreate is true', () => {
  renderWithProviders(<CRDCard {...crdCardProps} canCreate={true} />);

  expect(screen.getByRole('link', { name: /Create/i })).toBeInTheDocument();
});
frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx (1)

67-72: Consider using more direct query patterns.

The current approach of using getAllByText followed by array filtering works but is indirect. Consider using within() scoping or more specific role-based queries for better test clarity.

Example refactor:

-    const installPlanLinks = screen.getAllByText(installPlan.metadata.name);
-    const installPlanLink = installPlanLinks.find((link) =>
-      link.getAttribute('href')?.includes('InstallPlan'),
-    );
-    expect(installPlanLink).toBeVisible();
+    const installPlanLink = screen.getByRole('link', { name: installPlan.metadata.name });
+    expect(installPlanLink).toHaveAttribute('href', expect.stringContaining('InstallPlan'));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 1987dc6 and e19a479.

📒 Files selected for processing (8)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/operator-group.spec.tsx (8 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/package-manifest.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/subscription.spec.tsx (1 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/catalog-source.spec.tsx (0 hunks)
  • frontend/packages/operator-lifecycle-manager/src/components/clusterserviceversion.spec.tsx (0 hunks)
💤 Files with no reviewable changes (2)
  • frontend/packages/operator-lifecycle-manager/src/components/clusterserviceversion.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/catalog-source.spec.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • frontend/packages/operator-lifecycle-manager/src/components/tests/operator-group.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/tests/subscription.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/tests/package-manifest.spec.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

-Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.

Files:

  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/clusterserviceversion.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx
  • frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx
🔇 Additional comments (10)
frontend/packages/operator-lifecycle-manager/src/components/__tests__/catalog-source.spec.tsx (3)

1-90: LGTM on imports and mock setup.

The imports and extensive mock configuration are appropriate for RTL-based testing. The mocks properly isolate the components under test.


92-107: Good RTL pattern testing user-visible behavior.

This test suite properly focuses on what the user sees (display name and publisher) rather than implementation details.


159-219: LGTM on CreateSubscriptionYAML tests.

These tests appropriately verify user-visible behavior including loading states and YAML content display. The mock override pattern is functional for this migration.

frontend/packages/operator-lifecycle-manager/src/components/__tests__/install-plan.spec.tsx (7)

1-42: LGTM: Test setup is well-structured.

The imports and mock configuration are appropriate for RTL-based testing with proper mocking of external dependencies.


139-176: LGTM: Table configuration tests are appropriate.

Using mock inspection to verify Table props is a reasonable approach for this component structure.


178-221: LGTM: Page configuration tests are comprehensive.

The tests appropriately verify MultiListPage setup and resource fetching configuration.


289-318: LGTM: Integration test for approval flow is well-structured.

The test properly verifies the k8sPatch call with correct parameters when the Approve button is clicked.


353-402: LGTM: Conditional rendering tests are well-covered.

The tests appropriately verify that the preview link appears only for manual approval plans and use proper negative assertions.


404-426: LGTM: Navigation structure test is appropriate.

The test verifies all three expected navigation tabs are configured correctly.


345-350: The current test implementation is correct and should not be changed.

The button label in the InstallPlanPreview component is {step.resource.name}, not "Preview". The test correctly verifies the button's visibility by matching against the actual resource name. The original review comment's suggestion to use { name: 'Preview' } contradicts the actual UI implementation and would cause the test to fail.

Likely an incorrect or invalid review comment.

@cajieh
Copy link
Contributor

cajieh commented Nov 20, 2025

/lgtm

@openshift-ci openshift-ci bot added lgtm Indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Nov 20, 2025
@cajieh
Copy link
Contributor

cajieh commented Nov 20, 2025

/verified later @yapei

@openshift-ci-robot openshift-ci-robot added verified-later verified Signifies that the PR passed pre-merge verification criteria labels Nov 20, 2025
@openshift-ci-robot
Copy link
Contributor

@cajieh: This PR has been marked to be verified later by @yapei.

In response to this:

/verified later @yapei
/approve

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 20, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cajieh, sg00dwin

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Nov 21, 2025

@sg00dwin: all tests passed!

Full PR test history. Your PR dashboard.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot openshift-merge-bot bot merged commit 057ffde into openshift:main Nov 21, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. component/olm Related to OLM docs-approved Signifies that Docs has signed off on this PR jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. px-approved Signifies that Product Support has signed off on this PR verified Signifies that the PR passed pre-merge verification criteria verified-later

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants