Skip to content

Commit

Permalink
Temp/alias management 2.5 (#524)
Browse files Browse the repository at this point in the history
* Feature/common 2.5 (#506)

* feat: split to common change

Signed-off-by: suzhou <[email protected]>

* feat: update

Signed-off-by: suzhou <[email protected]>

Signed-off-by: suzhou <[email protected]>

* feat: update

Signed-off-by: suzhou <[email protected]>

* feat: update

Signed-off-by: suzhou <[email protected]>

Signed-off-by: suzhou <[email protected]>
  • Loading branch information
SuZhou-Joe committed Jan 6, 2023
1 parent 6b1738d commit 918114a
Show file tree
Hide file tree
Showing 24 changed files with 2,451 additions and 1 deletion.
119 changes: 119 additions & 0 deletions cypress/integration/aliases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/
import { PLUGIN_NAME } from "../support/constants";

const SAMPLE_INDEX_PREFIX = "index-for-alias-test";
const SAMPLE_ALIAS_PREFIX = "alias-for-test";
const CREATE_ALIAS = "create-alias";
const EDIT_INDEX = "index-edit-index-for-alias-test";

describe("Aliases", () => {
before(() => {
// Set welcome screen tracking to false
localStorage.setItem("home:welcome:show", "false");
cy.deleteAllIndices();
for (let i = 0; i < 11; i++) {
cy.createIndex(`${SAMPLE_INDEX_PREFIX}-${i}`, null);
}
cy.createIndex(EDIT_INDEX, null);
for (let i = 0; i < 30; i++) {
cy.addAlias(`${SAMPLE_ALIAS_PREFIX}-${i}`, `${SAMPLE_INDEX_PREFIX}-${i % 11}`);
}
cy.removeAlias(`${SAMPLE_ALIAS_PREFIX}-0`);
cy.addAlias(`${SAMPLE_ALIAS_PREFIX}-0`, `${SAMPLE_INDEX_PREFIX}-*`);
});

beforeEach(() => {
// Visit ISM OSD
cy.visit(`${Cypress.env("opensearch_dashboards")}/app/${PLUGIN_NAME}#/aliases`);

// Common text to wait for to confirm page loaded, give up to 60 seconds for initial load
cy.contains("Rows per page", { timeout: 60000 });
});

describe("can be searched / sorted / paginated", () => {
it("successfully", () => {
cy.get('[data-test-subj="pagination-button-1"]').should("exist");
cy.get('[placeholder="Search..."]').type("alias-for-test-0{enter}");
cy.contains("alias-for-test-0");
cy.get(".euiTableRow").should("have.length", 1);
cy.get('[data-test-subj="comboBoxSearchInput"]').type("closed{enter}");

cy.contains("You have no aliases.");
});
});

describe("shows more flyout", () => {
it("successfully", () => {
cy.get('[placeholder="Search..."]').type("alias-for-test-0{enter}");
cy.contains("alias-for-test-0");
cy.get(".euiTableRow").should("have.length", 1);
cy.get('.euiTableRowCell [data-test-subj="8 more"]')
.click()
.get('[data-test-subj="indices-table"] .euiTableRow')
.should("have.length", 10);
});
});

describe("can create a alias with wildcard and specific name", () => {
it("successfully", () => {
cy.get('[data-test-subj="Create AliasButton"]').click();
cy.get('[data-test-subj="form-name-alias"]').type(CREATE_ALIAS);
cy.get('[data-test-subj="form-name-indexArray"] [data-test-subj="comboBoxSearchInput"]').type(
`${EDIT_INDEX}{enter}${SAMPLE_INDEX_PREFIX}-*{enter}`
);
cy.get(".euiFlyoutFooter .euiButton--fill").click().get('[data-test-subj="9 more"]').should("exist");
});
});

describe("can edit / delete a alias", () => {
it("successfully", () => {
cy.get('[placeholder="Search..."]').type(`${SAMPLE_ALIAS_PREFIX}-0{enter}`);
cy.contains(`${SAMPLE_ALIAS_PREFIX}-0`);
cy.get('[data-test-subj="moreAction"] button')
.click()
.get('[data-test-subj="editAction"]')
.should("be.disabled")
.get(`#_selection_column_${SAMPLE_ALIAS_PREFIX}-0-checkbox`)
.click()
.get('[data-test-subj="moreAction"] button')
.click()
.get('[data-test-subj="editAction"]')
.click()
.get('[data-test-subj="form-name-indexArray"] [data-test-subj="comboBoxInput"]')
.click()
.type(`${EDIT_INDEX}{enter}`)
.get(`[title="${SAMPLE_INDEX_PREFIX}-0"] button`)
.click()
.get(`[title="${SAMPLE_INDEX_PREFIX}-1"] button`)
.click()
.get(".euiFlyoutFooter .euiButton--fill")
.click()
.end();

cy.get('[data-test-subj="7 more"]').should("exist");

cy.get('[data-test-subj="moreAction"] button').click().get('[data-test-subj="deleteAction"]').click();
// The confirm button should be disabled
cy.get('[data-test-subj="deleteConfirmButton"]').should("be.disabled");
// type delete
cy.wait(500).get('[data-test-subj="deleteInput"]').type("delete");
cy.get('[data-test-subj="deleteConfirmButton"]').should("not.be.disabled");
// click to delete
cy.get('[data-test-subj="deleteConfirmButton"]').click();
// the alias should not exist
cy.wait(500);
cy.get(`#_selection_column_${SAMPLE_ALIAS_PREFIX}-0-checkbox`).should("not.exist");
});
});

after(() => {
cy.deleteAllIndices();
for (let i = 0; i < 30; i++) {
cy.removeAlias(`${SAMPLE_ALIAS_PREFIX}-${i}`);
}
cy.removeAlias(CREATE_ALIAS);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from "react";
import "@testing-library/jest-dom/extend-expect";
import { render, waitFor } from "@testing-library/react";
// @ts-ignore
import userEvent from "@testing-library/user-event";
import IndexControls from "./IndexControls";

describe("<IndexControls /> spec", () => {
it("renders the component", async () => {
const { container } = render(<IndexControls value={{ search: "testing", status: "1" }} onSearchChange={() => {}} />);

expect(container.firstChild).toMatchSnapshot();
});

it("onChange with right data", async () => {
const onSearchChangeMock = jest.fn();
const { getByTestId, getByPlaceholderText } = render(
<IndexControls value={{ search: "", status: "" }} onSearchChange={onSearchChangeMock} />
);

userEvent.type(getByTestId("comboBoxSearchInput"), "closed{enter}");
expect(onSearchChangeMock).toBeCalledTimes(1);
expect(onSearchChangeMock).toBeCalledWith({
search: "",
status: "closed",
});
userEvent.type(getByPlaceholderText("Search..."), "test");
await waitFor(() => {
expect(onSearchChangeMock).toBeCalledTimes(5);
expect(onSearchChangeMock).toBeCalledWith({
search: "test",
status: "closed",
});
});
});
});
52 changes: 52 additions & 0 deletions public/pages/Aliases/components/IndexControls/IndexControls.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React, { useEffect, useState } from "react";
import { EuiComboBox, EuiFieldSearch, EuiFlexGroup, EuiFlexItem } from "@elastic/eui";
import { ALIAS_STATUS_OPTIONS } from "../../../../utils/constants";

export interface SearchControlsProps {
value: {
search: string;
status: string;
};
onSearchChange: (args: SearchControlsProps["value"]) => void;
}

export default function SearchControls(props: SearchControlsProps) {
const [state, setState] = useState<SearchControlsProps["value"]>(props.value);
const onChange = <T extends keyof SearchControlsProps["value"]>(field: T, value: SearchControlsProps["value"][T]) => {
const payload = {
...state,
[field]: value,
};
setState(payload);
props.onSearchChange(payload);
};
useEffect(() => {
setState(props.value);
}, [props.value]);
return (
<EuiFlexGroup style={{ padding: "0px 5px" }} alignItems="center">
<EuiFlexItem>
<EuiFieldSearch fullWidth placeholder="Search..." value={state.search} onChange={(e) => onChange("search", e.target.value)} />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiComboBox
style={{
width: 150,
}}
singleSelection={{
asPlainText: true,
}}
placeholder="Status"
options={ALIAS_STATUS_OPTIONS}
selectedOptions={state.status ? [{ label: state.status }] : []}
onChange={(val) => onChange("status", val[0]?.label)}
/>
</EuiFlexItem>
</EuiFlexGroup>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<IndexControls /> spec renders the component 1`] = `
<div
class="euiFlexGroup euiFlexGroup--gutterLarge euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
style="padding: 0px 5px;"
>
<div
class="euiFlexItem"
>
<div
class="euiFormControlLayout euiFormControlLayout--fullWidth"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<input
class="euiFieldSearch euiFieldSearch--fullWidth euiFieldSearch-isClearable"
placeholder="Search..."
type="search"
value="testing"
/>
<div
class="euiFormControlLayoutIcons"
>
<span
class="euiFormControlLayoutCustomIcon"
>
EuiIconMock
</span>
</div>
<div
class="euiFormControlLayoutIcons euiFormControlLayoutIcons--right"
>
<button
aria-label="Clear input"
class="euiFormControlLayoutClearButton"
type="button"
>
EuiIconMock
</button>
</div>
</div>
</div>
</div>
<div
class="euiFlexItem euiFlexItem--flexGrowZero"
>
<div
aria-expanded="false"
aria-haspopup="listbox"
class="euiComboBox"
role="combobox"
style="width: 150px;"
>
<div
class="euiFormControlLayout"
>
<div
class="euiFormControlLayout__childrenWrapper"
>
<div
class="euiComboBox__inputWrap euiComboBox__inputWrap--noWrap euiComboBox__inputWrap-isClearable"
data-test-subj="comboBoxInput"
tabindex="-1"
>
<span
class="euiComboBoxPill euiComboBoxPill--plainText"
>
1
</span>
<div
class="euiComboBox__input"
style="font-size: 14px; display: inline-block;"
>
<input
aria-controls=""
data-test-subj="comboBoxSearchInput"
role="textbox"
style="box-sizing: content-box; width: 2px;"
value=""
/>
<div
style="position: absolute; top: 0px; left: 0px; visibility: hidden; height: 0px; overflow: scroll; white-space: pre; font-family: -webkit-small-control; letter-spacing: normal; text-transform: none;"
/>
</div>
</div>
<div
class="euiFormControlLayoutIcons euiFormControlLayoutIcons--right"
>
<button
aria-label="Clear input"
class="euiFormControlLayoutClearButton"
data-test-subj="comboBoxClearButton"
type="button"
>
EuiIconMock
</button>
<button
aria-label="Open list of options"
class="euiFormControlLayoutCustomIcon euiFormControlLayoutCustomIcon--clickable"
data-test-subj="comboBoxToggleListButton"
type="button"
>
EuiIconMock
</button>
</div>
</div>
</div>
</div>
</div>
</div>
`;
9 changes: 9 additions & 0 deletions public/pages/Aliases/components/IndexControls/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import IndexControls from "./IndexControls";

export * from "./IndexControls";
export default IndexControls;
Loading

0 comments on commit 918114a

Please sign in to comment.