Skip to content

Commit

Permalink
Merge pull request #1589 from GowthamShanmugam/RHSTOR-6347
Browse files Browse the repository at this point in the history
RHSTOR-6347: Enable recipe-based DR enrollment for discovered applications
  • Loading branch information
openshift-merge-bot[bot] authored Oct 24, 2024
2 parents 637f39f + 1fe79bd commit 4bae5b0
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 69 deletions.
3 changes: 2 additions & 1 deletion locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
"You have selected {{count}} namespaces, to view or change your selection go back to the previous step._other": "You have selected {{count}} namespaces, to view or change your selection go back to the previous step.",
"Secure selected namespace by defining resource label expressions.": "Secure selected namespace by defining resource label expressions.",
"Resource label": "Resource label",
"Secure namespaces as per Recipe definition.": "Secure namespaces as per Recipe definition.",
"Recipe": "Recipe",
"Recipe list": "Recipe list",
"Only recipes of the selected namespaces will appear in the list.": "Only recipes of the selected namespaces will appear in the list.",
"Select a recipe": "Select a recipe",
Expand Down Expand Up @@ -130,7 +132,6 @@
"Name:": "Name:",
"Configuration": "Configuration",
"Type:": "Type:",
"Recipe": "Recipe",
"Recipe name:": "Recipe name:",
"Recipe namespace:": "Recipe namespace:",
"Label expressions:": "Label expressions:",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import * as React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import {
render,
screen,
waitFor,
fireEvent,
act,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { DRPlacementControlModel, DRPolicyModel } from '../../models';
import {
DRPlacementControlKind,
Expand Down Expand Up @@ -267,45 +274,45 @@ jest.mock('@patternfly/react-core', () => ({
}));

const moveToStep = async (step: number) => {
const user = userEvent.setup();
if (step > 1) {
// Select cluster
fireEvent.click(screen.getByText('Select cluster'));
fireEvent.click(screen.getByText('east-1'));
await user.click(screen.getByText('Select cluster'));
await user.click(screen.getByText('east-1'));

// Select namespaces
fireEvent.click(screen.getByLabelText('Select row 0'));
fireEvent.click(screen.getByLabelText('Select row 1'));
await user.click(screen.getByLabelText('Select row 0'));
await user.click(screen.getByLabelText('Select row 1'));

// Name input
fireEvent.change(screen.getByLabelText('Name input'), {
target: { value: 'my-name' },
});
await user.type(screen.getByLabelText('Name input'), 'my-name');
await waitFor(() => {
expect(screen.getByDisplayValue('my-name')).toBeInTheDocument();
});

// Next wizard step
fireEvent.click(screen.getByText('Next'));
await act(async () => {
// Next wizard step
await user.click(screen.getByText('Next'));
});
}

// Commented out recipe-based steps
if (step > 2) {
// Select recipe
// fireEvent.click(screen.getByText('Recipe'));
// fireEvent.click(screen.getByText('Select a recipe'));
// fireEvent.click(screen.getByText('mock-recipe-1'));
await user.click(screen.getByText('Recipe'));
await user.click(screen.getByText('Select a recipe'));
await user.click(screen.getByText('mock-recipe-1'));

// Next wizard step
fireEvent.click(screen.getByText('Next'));
await user.click(screen.getByText('Next'));
}

if (step > 3) {
// Select policy
fireEvent.click(screen.getByText('Select a policy'));
fireEvent.click(screen.getByText('mock-policy-1'));
await user.click(screen.getByText('Select a policy'));
await user.click(screen.getByText('mock-policy-1'));

// Next wizard step
fireEvent.click(screen.getByText('Next'));
await user.click(screen.getByText('Next'));
}
};

Expand All @@ -315,6 +322,7 @@ describe('Test namespace step', () => {
});
test('Namespace selection form test', async () => {
testCase = 1;
const user = userEvent.setup();
// Step1 title
expect(screen.getByText('Namespace selection')).toBeInTheDocument();
// Step1 title description
Expand Down Expand Up @@ -363,7 +371,7 @@ describe('Test namespace step', () => {
expect(screen.getByText('Cancel')).toBeInTheDocument();

// Validation message
fireEvent.click(screen.getByText('Next'));
await user.click(screen.getByText('Next'));
expect(
screen.getByText('Select a DRCluster to choose your namespace.')
).toBeInTheDocument();
Expand All @@ -377,9 +385,10 @@ describe('Test namespace step', () => {

test('No namespace found test', async () => {
testCase = 2;
const user = userEvent.setup();
// Cluster selection
fireEvent.click(screen.getByText('Select cluster'));
fireEvent.click(screen.getByText('east-1'));
await user.click(screen.getByText('Select cluster'));
await user.click(screen.getByText('east-1'));
// Ensure east-1 selection
expect(screen.getByText('east-1')).toBeInTheDocument();

Expand All @@ -394,9 +403,10 @@ describe('Test namespace step', () => {

test('Namespace selection test', async () => {
testCase = 3;
const user = userEvent.setup();
// Cluster east-1 selection
fireEvent.click(screen.getByText('Select cluster'));
fireEvent.click(screen.getByText('east-1'));
await user.click(screen.getByText('Select cluster'));
await user.click(screen.getByText('east-1'));
// Ensure east-1 selection
expect(screen.getByText('east-1')).toBeInTheDocument();

Expand All @@ -416,8 +426,8 @@ describe('Test namespace step', () => {
);

// Cluster west-1 selection
fireEvent.click(screen.getByText('east-1'));
fireEvent.click(screen.getByText('west-1'));
await user.click(screen.getByText('east-1'));
await user.click(screen.getByText('west-1'));
// Ensure west-1 selection
expect(screen.getByText('west-1')).toBeInTheDocument();

Expand All @@ -432,25 +442,21 @@ describe('Test namespace step', () => {
'Unable to find an element'
);
// Name input
fireEvent.change(screen.getByLabelText('Name input'), {
target: { value: 'my-name' },
});
user.type(screen.getByLabelText('Name input'), 'my-name');
await waitFor(() => {
expect(screen.getByDisplayValue('my-name')).toBeInTheDocument();
});
});
});

// The Recipe-bsaed dr protection is in Dev Preview for ODF 4.16.
// All Recipe-based test cases are skipped.
// https://bugzilla.redhat.com/show_bug.cgi?id=2291301
describe.skip('Test configure step', () => {
describe('Test configure step', () => {
beforeEach(() => {
render(<EnrollDiscoveredApplication />);
});

test('Configure form test', async () => {
testCase = 4;
const user = userEvent.setup();
await moveToStep(2);
// Step2 title
expect(screen.getByText('Configure definition')).toBeInTheDocument();
Expand All @@ -475,7 +481,7 @@ describe.skip('Test configure step', () => {
).toBeInTheDocument();

// Recipe selection
fireEvent.click(screen.getByText('Recipe'));
await user.click(screen.getByText('Recipe'));
expect(screen.getByText('Recipe list')).toBeInTheDocument();
expect(
screen.getByText(
Expand All @@ -490,7 +496,7 @@ describe.skip('Test configure step', () => {
expect(screen.getByText('Cancel')).toBeInTheDocument();

// Validation message
fireEvent.click(screen.getByText('Next'));
await user.click(screen.getByText('Next'));
expect(screen.getByText('Required')).toBeInTheDocument();
expect(
screen.getByText(
Expand All @@ -499,24 +505,25 @@ describe.skip('Test configure step', () => {
).toBeInTheDocument();

// Select recipe
fireEvent.click(screen.getByText('Select a recipe'));
await user.click(screen.getByText('Select a recipe'));
expect(screen.getByText('mock-recipe-1')).toBeInTheDocument();
expect(screen.getByText('namespace-1')).toBeInTheDocument();
expect(screen.getByText('mock-recipe-2')).toBeInTheDocument();
expect(screen.getByText('namespace-2')).toBeInTheDocument();
fireEvent.click(screen.getByText('mock-recipe-1'));
await user.click(screen.getByText('mock-recipe-1'));
// Ensure recipe selection
expect(screen.getByText('mock-recipe-1')).toBeInTheDocument();
});
});

describe.skip('Test replication step', () => {
describe('Test replication step', () => {
beforeEach(() => {
render(<EnrollDiscoveredApplication />);
});
test('Replication form test', async () => {
testCase = 5;
await moveToStep(3);
const user = userEvent.setup();
await await moveToStep(3);
// Step3 title
expect(
screen.getByText('Volume and Kubernetes object replication')
Expand All @@ -529,7 +536,7 @@ describe.skip('Test replication step', () => {
).toBeInTheDocument();
// Policy dropdown
expect(screen.getByText('Disaster recovery policy')).toBeInTheDocument();
fireEvent.click(screen.getByText('Select a policy'));
await user.click(screen.getByText('Select a policy'));
expect(screen.getByText('mock-policy-1')).toBeInTheDocument();
expect(
screen.getByText(
Expand All @@ -546,7 +553,7 @@ describe.skip('Test replication step', () => {
).toBeInTheDocument();
// Default interval
expect(screen.getByDisplayValue(5)).toBeInTheDocument();
fireEvent.click(screen.getByText('minutes'));
await user.click(screen.getByText('minutes'));
expect(screen.getByText('hours')).toBeInTheDocument();
expect(screen.getByText('days')).toBeInTheDocument();

Expand All @@ -556,32 +563,34 @@ describe.skip('Test replication step', () => {
expect(screen.getByText('Cancel')).toBeInTheDocument();

// Validation message
fireEvent.click(screen.getByText('Next'));
await user.click(screen.getByText('Next'));
expect(screen.getByText('Required')).toBeInTheDocument();

// Select policy
fireEvent.click(screen.getByText('Select a policy'));
fireEvent.click(screen.getByText('mock-policy-1'));
await user.click(screen.getByText('Select a policy'));
await user.click(screen.getByText('mock-policy-1'));
// Ensure policy selection
expect(screen.getByText('mock-policy-1')).toBeInTheDocument();

// kubernetes object replication interval selection
fireEvent.change(screen.getByDisplayValue(5), { target: { value: 10 } });
// user-even is not supporting number input: https://github.com/testing-library/user-event/issues/411
fireEvent.input(screen.getByDisplayValue(5), { target: { value: 10 } });
// Ensure interval selection
expect(screen.getByDisplayValue(10)).toBeInTheDocument();
// unit selection
fireEvent.click(screen.getByText('minutes'));
fireEvent.click(screen.getByText('days'));
await user.click(screen.getByText('minutes'));
await user.click(screen.getByText('days'));
// Ensure unit selection
expect(screen.getByText('days')).toBeInTheDocument();
});
});
describe.skip('Test review step', () => {
describe('Test review step', () => {
beforeEach(() => {
render(<EnrollDiscoveredApplication />);
});
test('Review form test', async () => {
testCase = 6;
const user = userEvent.setup();
await moveToStep(4);
// Namespace selection test
expect(screen.getAllByText('Namespace').length === 2).toBeTruthy();
Expand Down Expand Up @@ -620,7 +629,7 @@ describe.skip('Test review step', () => {
expect(screen.getByText('Cancel')).toBeInTheDocument();

// Click save
fireEvent.click(screen.getByText('Save'));
await user.click(screen.getByText('Save'));
await waitFor(async () => {
expect(
JSON.stringify(drpcObj) ===
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,11 @@ export const Configuration: React.FC<ConfigurationProps> = ({
onChange={(event, _unUsed) =>
setProtectionMethod(_unUsed, event)
}
checked={
isChecked={
protectionMethod === ProtectionMethodType.RESOURCE_LABEL
}
/>
</GridItem>
{/* The Recipe-bsaed dr protection is in Dev Preview for ODF 4.16.
https://bugzilla.redhat.com/show_bug.cgi?id=2291301
<GridItem
span={6}
className="mco-configuration-step__radio pf-v5-u-p-lg"
Expand All @@ -97,9 +94,9 @@ export const Configuration: React.FC<ConfigurationProps> = ({
onChange={(event, _unUsed) =>
setProtectionMethod(_unUsed, event)
}
checked={protectionMethod === ProtectionMethodType.RECIPE}
isChecked={protectionMethod === ProtectionMethodType.RECIPE}
/>
</GridItem> */}
</GridItem>
</Grid>
</FormGroup>
{protectionMethod === ProtectionMethodType.RECIPE && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
Button,
Form,
FormGroup,
Text,
Grid,
GridItem,
Popover,
Expand Down Expand Up @@ -295,23 +294,23 @@ export const PVCDetailsWizardContent: React.FC<PVCDetailsWizardContentProps> =
return (
<Form>
<FormGroup>
<Text>
<span>
{t(
'Use PVC label selectors to effortlessly specify the application resources that need protection. You can also create a custom PVC label selector if one doesn’t exists. For more information, '
)}
<Popover
</span>
<Popover
aria-label={t('Help')}
bodyContent={getLabelValidationMessage(t)}
>
<Button
aria-label={t('Help')}
bodyContent={getLabelValidationMessage(t)}
variant={ButtonVariant.link}
isInline
>
<Button
aria-label={t('Help')}
variant={ButtonVariant.link}
isInline
>
{t('see PVC label selector requirements.')}
</Button>
</Popover>
</Text>
{t('see PVC label selector requirements.')}
</Button>
</Popover>
</FormGroup>
{loaded && !error ? (
<LazyNameValueEditor
Expand Down
2 changes: 1 addition & 1 deletion packages/shared/src/table/selectable-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export const SelectableTable: SelectableTableProps = <
onSelect: onSelect,
isSelected: isRowSelected(getUID(row), selectedRows),
isDisabled:
!isRowSelectable?.(row) ||
(!!isRowSelectable && !isRowSelectable(row)) ||
!hasNoDeletionTimestamp(row),
props: {
id: getUID(row),
Expand Down

0 comments on commit 4bae5b0

Please sign in to comment.