Skip to content

Commit 4715361

Browse files
author
Seung Yeon Joo
committed
Add convert index to remote restore options
1 parent 3330fc4 commit 4715361

7 files changed

Lines changed: 222 additions & 95 deletions

File tree

cypress/fixtures/plugins/index-management-dashboards-plugin/sample_convert_index_to_remote_policy.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
"snapshot": "{{ctx.index}}",
3131
"include_aliases": true,
3232
"ignore_index_settings": "index.refresh_interval,index.number_of_replicas",
33-
"number_of_replicas": 0
33+
"number_of_replicas": 0,
34+
"delete_original_index": false,
35+
"rename_pattern": "$1_remote"
3436
}
3537
}
3638
],
@@ -39,4 +41,3 @@
3941
]
4042
}
4143
}
42-

models/interfaces.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ export interface ConvertIndexToRemoteAction extends Action {
435435
include_aliases?: boolean;
436436
ignore_index_settings?: string;
437437
number_of_replicas?: number;
438+
delete_original_index?: boolean;
439+
rename_pattern?: string;
438440
};
439441
}
440442

public/pages/VisualCreatePolicy/components/UIActions/ConvertIndexToRemoteUIAction.test.tsx

Lines changed: 91 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import React from "react";
77
import "@testing-library/jest-dom";
88
import { render, screen, cleanup, fireEvent } from "@testing-library/react";
9-
import userEventModule from "@testing-library/user-event";
109
import { DEFAULT_CONVERT_INDEX_TO_REMOTE } from "../../utils/constants";
1110
import { ConvertIndexToRemoteAction, UIAction } from "../../../../../models/interfaces";
1211
import { actionRepoSingleton } from "../../utils/helpers";
@@ -26,10 +25,8 @@ const mockOnChangeAction = (uiAction: UIAction<ConvertIndexToRemoteAction> = TES
2625
afterEach(() => cleanup());
2726

2827
describe("ConvertIndexToRemoteUIAction component", () => {
29-
const userEvent = userEventModule.setup();
30-
3128
it("renders with default values", () => {
32-
const { container } = render(actionRepoSingleton.getUIAction("convert_index_to_remote").render(TEST_PROPS, mockOnChangeAction));
29+
render(actionRepoSingleton.getUIAction("convert_index_to_remote").render(TEST_PROPS, mockOnChangeAction));
3330

3431
// Check that repository field exists with default value
3532
const repositoryInput = screen.getByTestId("action-render-convert-index-to-remote-repository");
@@ -46,6 +43,16 @@ describe("ConvertIndexToRemoteUIAction component", () => {
4643
expect(includeAliasesSwitch).toBeInTheDocument();
4744
expect(includeAliasesSwitch).not.toBeChecked();
4845

46+
// Check that delete_original_index switch exists
47+
const deleteOriginalIndexSwitch = screen.getByTestId("action-render-convert-index-to-remote-delete-original-index");
48+
expect(deleteOriginalIndexSwitch).toBeInTheDocument();
49+
expect(deleteOriginalIndexSwitch).not.toBeChecked();
50+
51+
// Check that rename_pattern field exists
52+
const renamePatternInput = screen.getByTestId("action-render-convert-index-to-remote-rename-pattern");
53+
expect(renamePatternInput).toBeInTheDocument();
54+
expect(renamePatternInput).toHaveValue("$1_remote");
55+
4956
// Check that ignore_index_settings field exists
5057
const ignoreIndexSettingsInput = screen.getByTestId("action-render-convert-index-to-remote-ignore-index-settings");
5158
expect(ignoreIndexSettingsInput).toBeInTheDocument();
@@ -54,29 +61,25 @@ describe("ConvertIndexToRemoteUIAction component", () => {
5461
// Check that number_of_replicas field exists
5562
const numberOfReplicasInput = screen.getByTestId("action-render-convert-index-to-remote-number-of-replicas");
5663
expect(numberOfReplicasInput).toBeInTheDocument();
57-
expect(numberOfReplicasInput).toHaveValue(0);
58-
59-
expect(container).toMatchSnapshot();
64+
expect(numberOfReplicasInput).toHaveValue(null);
6065
});
6166

6267
it("updates repository value on change", async () => {
6368
renderComponent();
6469

6570
const repositoryInput = screen.getByTestId("action-render-convert-index-to-remote-repository");
66-
await userEvent.clear(repositoryInput);
67-
await userEvent.type(repositoryInput, "my-remote-repo");
71+
fireEvent.change(repositoryInput, { target: { value: "my-remote-repo" } });
6872

69-
expect(repositoryInput).toHaveValue("my-remote-repo");
73+
expect(screen.getByTestId("action-render-convert-index-to-remote-repository")).toHaveValue("my-remote-repo");
7074
});
7175

7276
it("updates snapshot value on change", async () => {
7377
renderComponent();
7478

7579
const snapshotInput = screen.getByTestId("action-render-convert-index-to-remote-snapshot");
76-
await userEvent.clear(snapshotInput);
77-
await userEvent.type(snapshotInput, "{{ctx.index}}");
80+
fireEvent.change(snapshotInput, { target: { value: "{{ctx.index}}" } });
7881

79-
expect(snapshotInput).toHaveValue("{{ctx.index}}");
82+
expect(screen.getByTestId("action-render-convert-index-to-remote-snapshot")).toHaveValue("{{ctx.index}}");
8083
});
8184

8285
it("toggles include_aliases switch", async () => {
@@ -85,32 +88,52 @@ describe("ConvertIndexToRemoteUIAction component", () => {
8588
const includeAliasesSwitch = screen.getByTestId("action-render-convert-index-to-remote-include-aliases");
8689
expect(includeAliasesSwitch).not.toBeChecked();
8790

88-
await userEvent.click(includeAliasesSwitch);
89-
expect(includeAliasesSwitch).toBeChecked();
91+
fireEvent.click(includeAliasesSwitch);
92+
expect(screen.getByTestId("action-render-convert-index-to-remote-include-aliases")).toBeChecked();
93+
});
94+
95+
it("toggles delete_original_index switch", async () => {
96+
renderComponent();
97+
98+
const deleteOriginalIndexSwitch = screen.getByTestId("action-render-convert-index-to-remote-delete-original-index");
99+
expect(deleteOriginalIndexSwitch).not.toBeChecked();
100+
101+
fireEvent.click(deleteOriginalIndexSwitch);
102+
expect(screen.getByTestId("action-render-convert-index-to-remote-delete-original-index")).toBeChecked();
103+
});
104+
105+
it("updates rename_pattern value on change", async () => {
106+
renderComponent();
107+
108+
const renamePatternInput = screen.getByTestId("action-render-convert-index-to-remote-rename-pattern");
109+
fireEvent.change(renamePatternInput, { target: { value: "remote_$1" } });
110+
111+
expect(screen.getByTestId("action-render-convert-index-to-remote-rename-pattern")).toHaveValue("remote_$1");
90112
});
91113

92114
it("updates ignore_index_settings value on change", async () => {
93115
renderComponent();
94116

95117
const ignoreIndexSettingsInput = screen.getByTestId("action-render-convert-index-to-remote-ignore-index-settings");
96-
await userEvent.type(ignoreIndexSettingsInput, "index.refresh_interval,index.number_of_replicas");
118+
fireEvent.change(ignoreIndexSettingsInput, { target: { value: "index.refresh_interval,index.number_of_replicas" } });
97119

98-
expect(ignoreIndexSettingsInput).toHaveValue("index.refresh_interval,index.number_of_replicas");
120+
expect(screen.getByTestId("action-render-convert-index-to-remote-ignore-index-settings")).toHaveValue(
121+
"index.refresh_interval,index.number_of_replicas"
122+
);
99123
});
100124

101125
it("updates number_of_replicas value on change", async () => {
102126
renderComponent();
103127

104128
const numberOfReplicasInput = screen.getByTestId("action-render-convert-index-to-remote-number-of-replicas");
105-
await userEvent.clear(numberOfReplicasInput);
106-
await userEvent.type(numberOfReplicasInput, "2");
129+
fireEvent.change(numberOfReplicasInput, { target: { value: "2" } });
107130

108-
expect(numberOfReplicasInput).toHaveValue(2);
131+
expect(screen.getByTestId("action-render-convert-index-to-remote-number-of-replicas")).toHaveValue(2);
109132
});
110133

111134
it("validates required fields", () => {
112135
const uiAction = actionRepoSingleton.getUIAction("convert_index_to_remote");
113-
136+
114137
// Valid action
115138
expect(uiAction.isValid()).toBe(true);
116139

@@ -139,6 +162,32 @@ describe("ConvertIndexToRemoteUIAction component", () => {
139162
};
140163
const invalidUIAction2 = actionRepoSingleton.getUIActionFromData(invalidAction2.action);
141164
expect(invalidUIAction2.isValid()).toBe(false);
165+
166+
// Invalid action - rename pattern missing $1
167+
const invalidAction3 = {
168+
...TEST_PROPS,
169+
action: {
170+
convert_index_to_remote: {
171+
...DEFAULT_CONVERT_INDEX_TO_REMOTE.convert_index_to_remote,
172+
rename_pattern: "remote_index",
173+
},
174+
},
175+
};
176+
const invalidUIAction3 = actionRepoSingleton.getUIActionFromData(invalidAction3.action);
177+
expect(invalidUIAction3.isValid()).toBe(false);
178+
179+
// Invalid action - negative number_of_replicas
180+
const invalidAction4 = {
181+
...TEST_PROPS,
182+
action: {
183+
convert_index_to_remote: {
184+
...DEFAULT_CONVERT_INDEX_TO_REMOTE.convert_index_to_remote,
185+
number_of_replicas: -1,
186+
},
187+
},
188+
};
189+
const invalidUIAction4 = actionRepoSingleton.getUIActionFromData(invalidAction4.action);
190+
expect(invalidUIAction4.isValid()).toBe(false);
142191
});
143192

144193
it("renders with custom values", () => {
@@ -149,21 +198,21 @@ describe("ConvertIndexToRemoteUIAction component", () => {
149198
include_aliases: true,
150199
ignore_index_settings: "index.refresh_interval",
151200
number_of_replicas: 2,
201+
delete_original_index: true,
202+
rename_pattern: "remote_$1",
152203
},
153204
};
154205

155206
const customProps = { ...TEST_PROPS, action: customAction };
156-
const { container } = render(
157-
actionRepoSingleton.getUIAction("convert_index_to_remote").render(customProps, mockOnChangeAction)
158-
);
207+
render(actionRepoSingleton.getUIAction("convert_index_to_remote").render(customProps, mockOnChangeAction));
159208

160209
expect(screen.getByTestId("action-render-convert-index-to-remote-repository")).toHaveValue("s3-repo");
161210
expect(screen.getByTestId("action-render-convert-index-to-remote-snapshot")).toHaveValue("{{ctx.index}}-snapshot");
162211
expect(screen.getByTestId("action-render-convert-index-to-remote-include-aliases")).toBeChecked();
212+
expect(screen.getByTestId("action-render-convert-index-to-remote-delete-original-index")).toBeChecked();
213+
expect(screen.getByTestId("action-render-convert-index-to-remote-rename-pattern")).toHaveValue("remote_$1");
163214
expect(screen.getByTestId("action-render-convert-index-to-remote-ignore-index-settings")).toHaveValue("index.refresh_interval");
164215
expect(screen.getByTestId("action-render-convert-index-to-remote-number-of-replicas")).toHaveValue(2);
165-
166-
expect(container).toMatchSnapshot();
167216
});
168217

169218
it("returns correct content", () => {
@@ -174,13 +223,26 @@ describe("ConvertIndexToRemoteUIAction component", () => {
174223
it("converts to action correctly", () => {
175224
const uiAction = actionRepoSingleton.getUIAction("convert_index_to_remote");
176225
const action = uiAction.toAction();
177-
226+
178227
expect(action).toHaveProperty("convert_index_to_remote");
179228
expect(action.convert_index_to_remote).toHaveProperty("repository");
180229
expect(action.convert_index_to_remote).toHaveProperty("snapshot");
181230
expect(action.convert_index_to_remote).toHaveProperty("include_aliases");
182231
expect(action.convert_index_to_remote).toHaveProperty("ignore_index_settings");
183-
expect(action.convert_index_to_remote).toHaveProperty("number_of_replicas");
232+
expect(action.convert_index_to_remote).toHaveProperty("delete_original_index");
233+
expect(action.convert_index_to_remote).toHaveProperty("rename_pattern");
234+
expect(action.convert_index_to_remote).not.toHaveProperty("number_of_replicas");
184235
});
185-
});
186236

237+
it("keeps number_of_replicas when explicitly configured", () => {
238+
const uiAction = actionRepoSingleton.getUIActionFromData({
239+
convert_index_to_remote: {
240+
...DEFAULT_CONVERT_INDEX_TO_REMOTE.convert_index_to_remote,
241+
number_of_replicas: 2,
242+
},
243+
});
244+
245+
const action = uiAction.toAction() as ConvertIndexToRemoteAction;
246+
expect(action.convert_index_to_remote.number_of_replicas).toBe(2);
247+
});
248+
});

0 commit comments

Comments
 (0)