diff --git a/coral/src/app/features/connectors/request/ConnectorRequest.test.tsx b/coral/src/app/features/connectors/request/ConnectorRequest.test.tsx
index c64b67c53c..9bd60df6c0 100644
--- a/coral/src/app/features/connectors/request/ConnectorRequest.test.tsx
+++ b/coral/src/app/features/connectors/request/ConnectorRequest.test.tsx
@@ -24,6 +24,12 @@ jest.mock("react-router-dom", () => ({
useNavigate: () => mockedUsedNavigate,
}));
+const mockedUseToast = jest.fn();
+jest.mock("@aivenio/aquarium", () => ({
+ ...jest.requireActual("@aivenio/aquarium"),
+ useToast: () => mockedUseToast,
+}));
+
describe("", () => {
const originalConsoleError = console.error;
let user: ReturnType;
@@ -45,7 +51,12 @@ describe("", () => {
createEnvironment({ id: "2", name: "TST" }),
createEnvironment({ id: "3", name: "PROD" }),
]);
- customRender(, { queryClient: true });
+ customRender(
+
+
+ ,
+ { queryClient: true }
+ );
});
afterEach(cleanup);
@@ -96,7 +107,12 @@ describe("", () => {
createEnvironment({ id: "2", name: "TST" }),
createEnvironment({ id: "3", name: "PROD" }),
]);
- customRender(, { queryClient: true });
+ customRender(
+
+
+ ,
+ { queryClient: true }
+ );
});
afterEach(cleanup);
@@ -405,7 +421,10 @@ describe("", () => {
});
});
- afterEach(() => cleanup());
+ afterEach(() => {
+ mockedUseToast.mockReset();
+ cleanup();
+ });
it("creates a new connector request when input was valid", async () => {
await user.click(
@@ -424,6 +443,7 @@ describe("", () => {
environment: "1",
remarks: "",
});
+ await waitFor(() => expect(mockedUseToast).toHaveBeenCalled());
});
it("errors and does not create a new connector request when input was invalid", async () => {
@@ -440,12 +460,13 @@ describe("", () => {
);
expect(createConnectorRequest).not.toHaveBeenCalled();
+ expect(mockedUseToast).not.toHaveBeenCalled();
expect(
screen.getByRole("button", { name: "Submit request" })
).toBeEnabled();
});
- it("shows a dialog informing user that request was successful", async () => {
+ it("shows a notification informing user that request was successful and redirects them", async () => {
await user.click(
screen.getByRole("button", { name: "Submit request" })
);
@@ -456,32 +477,13 @@ describe("", () => {
});
expect(createConnectorRequest).toHaveBeenCalledTimes(1);
-
- const successModal = await screen.findByRole("dialog");
-
- expect(successModal).toBeVisible();
- expect(successModal).toHaveTextContent("Connector request successful!");
- });
-
- it("user can continue to the next page without waiting for redirect in the dialog", async () => {
- await user.click(
- screen.getByRole("button", { name: "Submit request" })
+ await waitFor(() =>
+ expect(mockedUseToast).toHaveBeenCalledWith({
+ message: "Connector request successful!",
+ position: "bottom-left",
+ variant: "default",
+ })
);
-
- await waitFor(() => {
- const btn = screen.getByRole("button", { name: "Submit request" });
- expect(btn).toBeDisabled();
- });
-
- expect(createConnectorRequest).toHaveBeenCalledTimes(1);
-
- const successModal = await screen.findByRole("dialog");
- const button = within(successModal).getByRole("button", {
- name: "Continue",
- });
-
- await userEvent.click(button);
-
expect(mockedUsedNavigate).toHaveBeenCalledWith(
"/requests/connectors?status=CREATED"
);
diff --git a/coral/src/app/features/connectors/request/ConnectorRequest.tsx b/coral/src/app/features/connectors/request/ConnectorRequest.tsx
index afa62fdade..e8d687d6b4 100644
--- a/coral/src/app/features/connectors/request/ConnectorRequest.tsx
+++ b/coral/src/app/features/connectors/request/ConnectorRequest.tsx
@@ -6,6 +6,7 @@ import {
Grid,
Label,
Typography,
+ useToast,
} from "@aivenio/aquarium";
import MonacoEditor from "@monaco-editor/react";
import { useMutation, useQuery } from "@tanstack/react-query";
@@ -34,9 +35,10 @@ import { parseErrorMsg } from "src/services/mutation-utils";
function ConnectorRequest() {
const [cancelDialogVisible, setCancelDialogVisible] = useState(false);
- const [successModalOpen, setSuccessModalOpen] = useState(false);
const navigate = useNavigate();
+ const toast = useToast();
+
const form = useForm({
schema: connectorRequestFormSchema,
});
@@ -51,17 +53,15 @@ function ConnectorRequest() {
const connectorRequestMutation = useMutation(createConnectorRequest, {
onSuccess: () => {
- setSuccessModalOpen(true);
- setTimeout(() => {
- redirectToMyRequests();
- }, 5 * 1000);
+ navigate("/requests/connectors?status=CREATED");
+ toast({
+ message: "Connector request successful!",
+ position: "bottom-left",
+ variant: "default",
+ });
},
});
- function redirectToMyRequests() {
- navigate("/requests/connectors?status=CREATED");
- }
-
function onSubmitForm(userInput: ConnectorRequestFormSchema) {
connectorRequestMutation.mutate(userInput);
}
@@ -73,20 +73,6 @@ function ConnectorRequest() {
return (
<>
- {successModalOpen && (
-
- )}
-
{connectorRequestMutation.isError && (
diff --git a/coral/src/app/features/topics/acl-request/TopicAclRequest.test.tsx b/coral/src/app/features/topics/acl-request/TopicAclRequest.test.tsx
index 0d62819ef3..dd6c04502a 100644
--- a/coral/src/app/features/topics/acl-request/TopicAclRequest.test.tsx
+++ b/coral/src/app/features/topics/acl-request/TopicAclRequest.test.tsx
@@ -1,3 +1,4 @@
+import { Context as AquariumContext } from "@aivenio/aquarium";
import { cleanup, screen, waitFor, within } from "@testing-library/react";
import { waitForElementToBeRemoved } from "@testing-library/react/pure";
import userEvent from "@testing-library/user-event";
@@ -31,6 +32,12 @@ jest.mock("src/domain/acl/acl-api", () => ({
getAivenServiceAccounts: jest.fn().mockReturnValue(["account"]),
}));
+const mockedUseToast = jest.fn();
+jest.mock("@aivenio/aquarium", () => ({
+ ...jest.requireActual("@aivenio/aquarium"),
+ useToast: () => mockedUseToast,
+}));
+
const dataSetup = ({ isAivenCluster }: { isAivenCluster: boolean }) => {
mockgetAllEnvironmentsForTopicAndAcl({
mswInstance: server,
@@ -97,7 +104,11 @@ describe("", () => {
}
+ element={
+
+
+
+ }
/>
,
{
@@ -173,7 +184,11 @@ describe("", () => {
}
+ element={
+
+
+
+ }
/>
,
{
@@ -450,7 +465,11 @@ describe("", () => {
}
+ element={
+
+
+
+ }
/>
,
{
@@ -729,7 +748,11 @@ describe("", () => {
}
+ element={
+
+
+
+ }
/>
,
{
@@ -928,7 +951,7 @@ describe("", () => {
});
describe("enables user to create a new acl request", () => {
- beforeEach(async () => {
+ beforeEach(() => {
mockCreateAclRequest({
mswInstance: server,
response: {
@@ -940,6 +963,7 @@ describe("", () => {
afterEach(() => {
jest.clearAllMocks();
+ mockedUseToast.mockReset();
});
it("creates a new acl request when input was valid", async () => {
@@ -985,6 +1009,7 @@ describe("", () => {
requestOperationType: "CREATE",
teamId: 1,
});
+ await waitFor(() => expect(mockedUseToast).toHaveBeenCalled());
});
it("renders errors and does not submit when input was invalid", async () => {
@@ -1017,9 +1042,10 @@ describe("", () => {
expect(spyPost).not.toHaveBeenCalled();
expect(submitButton).toBeEnabled();
+ expect(mockedUseToast).not.toHaveBeenCalled();
});
- it("shows a dialog informing user that request was successful", async () => {
+ it("shows a notification informing user that request was successful and redirects them", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
const submitButton = screen.getByRole("button", {
@@ -1052,55 +1078,16 @@ describe("", () => {
expect(spyPost).toHaveBeenCalledTimes(1);
- const successModal = await screen.findByRole("dialog");
-
- expect(successModal).toBeVisible();
- expect(successModal).toHaveTextContent("Acl request successful!");
- });
-
- it("user can continue to the next page without waiting for redirect in the dialog", async () => {
- const spyPost = jest.spyOn(api, "post");
- await assertSkeleton();
- const submitButton = screen.getByRole("button", {
- name: "Submit request",
- });
-
- // Fill form with valid data
- await selectTestEnvironment();
- await userEvent.click(screen.getByRole("radio", { name: "Literal" }));
- await userEvent.click(
- screen.getByRole("radio", { name: "Service account" })
- );
-
- const principalsField = await screen.findByRole("combobox", {
- name: "Service accounts *",
- });
-
- expect(principalsField).toBeVisible();
- expect(principalsField).toBeEnabled();
-
- await userEvent.type(principalsField, "Alice");
- await userEvent.tab();
-
- await waitFor(() => expect(submitButton).toBeEnabled());
- await userEvent.click(submitButton);
-
await waitFor(() => {
- expect(submitButton).toBeDisabled();
+ expect(mockedNavigate).toHaveBeenLastCalledWith(
+ "/requests/acls?status=CREATED"
+ );
});
-
- expect(spyPost).toHaveBeenCalledTimes(1);
-
- const successModal = await screen.findByRole("dialog");
- const button = within(successModal).getByRole("button", {
- name: "Continue",
+ expect(mockedUseToast).toHaveBeenCalledWith({
+ message: "Acl request successful!",
+ position: "bottom-left",
+ variant: "default",
});
-
- await userEvent.click(button);
-
- expect(mockedNavigate).toHaveBeenLastCalledWith(
- "/requests/acls?status=CREATED"
- );
});
});
});
@@ -1113,7 +1100,11 @@ describe("", () => {
}
+ element={
+
+
+
+ }
/>
,
{
@@ -1337,6 +1328,10 @@ describe("", () => {
});
});
+ afterEach(() => {
+ mockedUseToast.mockReset();
+ });
+
it("creates a new acl request when input was valid", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
@@ -1398,6 +1393,7 @@ describe("", () => {
requestOperationType: "CREATE",
transactionalId: undefined,
});
+ await waitFor(() => expect(mockedUseToast).toHaveBeenCalled());
});
it("renders errors and does not submit when input was invalid", async () => {
@@ -1430,7 +1426,7 @@ describe("", () => {
expect(submitButton).toBeEnabled();
});
- it("shows a dialog informing user that request was successful", async () => {
+ it("shows a notification informing user that request was successful and redirects them", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
@@ -1478,70 +1474,16 @@ describe("", () => {
});
expect(spyPost).toHaveBeenCalledTimes(1);
- const successModal = await screen.findByRole("dialog");
-
- expect(successModal).toBeVisible();
- expect(successModal).toHaveTextContent("Acl request successful!");
- });
-
- it("user can continue to the next page without waiting for redirect in the dialog", async () => {
- const spyPost = jest.spyOn(api, "post");
- await assertSkeleton();
-
- const aclConsumerTypeInput = screen.getByRole("radio", {
- name: "Consumer",
- });
- await userEvent.click(aclConsumerTypeInput);
-
- const submitButton = screen.getByRole("button", {
- name: "Submit request",
- });
-
- // Fill form with valid data
- await selectTestEnvironment();
-
- expect(
- screen.getByRole("radio", { name: "Principal" })
- ).toBeInTheDocument();
-
- await userEvent.click(screen.getByRole("radio", { name: "Principal" }));
- expect(screen.getByRole("radio", { name: "Principal" })).toBeChecked();
-
- const principalsField = await screen.findByRole("textbox", {
- name: "SSL DN strings / Usernames *",
- });
-
- expect(principalsField).toBeVisible();
- expect(principalsField).toBeEnabled();
-
- await userEvent.type(principalsField, "Alice");
- await userEvent.tab();
-
- const consumerGroupField = await screen.findByRole("textbox", {
- name: "Consumer group *",
- });
-
- await userEvent.type(consumerGroupField, "group");
- await userEvent.tab();
-
- await waitFor(() => expect(submitButton).toBeEnabled());
- await userEvent.click(submitButton);
-
await waitFor(() => {
- expect(submitButton).toBeDisabled();
+ expect(mockedNavigate).toHaveBeenLastCalledWith(
+ "/requests/acls?status=CREATED"
+ );
});
-
- expect(spyPost).toHaveBeenCalledTimes(1);
- const successModal = await screen.findByRole("dialog");
- const button = within(successModal).getByRole("button", {
- name: "Continue",
+ expect(mockedUseToast).toHaveBeenCalledWith({
+ message: "Acl request successful!",
+ position: "bottom-left",
+ variant: "default",
});
-
- await userEvent.click(button);
-
- expect(mockedNavigate).toHaveBeenLastCalledWith(
- "/requests/acls?status=CREATED"
- );
});
});
});
@@ -1550,10 +1492,15 @@ describe("", () => {
beforeEach(() => {
dataSetup({ isAivenCluster: true });
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
});
afterEach(cleanup);
@@ -1634,10 +1581,15 @@ describe("", () => {
beforeEach(() => {
dataSetup({ isAivenCluster: false });
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
});
afterEach(() => {
@@ -1951,10 +1903,15 @@ describe("", () => {
beforeEach(() => {
dataSetup({ isAivenCluster: false });
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
});
afterEach(cleanup);
@@ -2239,10 +2196,15 @@ describe("", () => {
beforeEach(async () => {
dataSetup({ isAivenCluster: true });
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
});
afterEach(() => {
@@ -2443,6 +2405,10 @@ describe("", () => {
});
});
+ afterEach(() => {
+ mockedUseToast.mockReset();
+ });
+
it("creates a new acl request when input was valid", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
@@ -2486,6 +2452,7 @@ describe("", () => {
requestOperationType: "CREATE",
teamId: 1,
});
+ await waitFor(() => expect(mockedUseToast).toHaveBeenCalled());
});
it("renders errors and does not submit when input was invalid", async () => {
@@ -2520,7 +2487,7 @@ describe("", () => {
expect(submitButton).toBeEnabled();
});
- it("shows a dialog informing user that request was successful", async () => {
+ it("shows a notification informing user that request was successful and redirects them", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
const submitButton = screen.getByRole("button", {
@@ -2552,56 +2519,16 @@ describe("", () => {
});
expect(spyPost).toHaveBeenCalledTimes(1);
-
- const successModal = await screen.findByRole("dialog");
-
- expect(successModal).toBeVisible();
- expect(successModal).toHaveTextContent("Acl request successful!");
- });
-
- it("user can continue to the next page without waiting for redirect in the dialog", async () => {
- const spyPost = jest.spyOn(api, "post");
- await assertSkeleton();
- const submitButton = screen.getByRole("button", {
- name: "Submit request",
- });
-
- // Fill form with valid data
- await selectTestEnvironment();
- await userEvent.click(screen.getByRole("radio", { name: "Literal" }));
- await userEvent.click(
- screen.getByRole("radio", { name: "Service account" })
- );
-
- const principalsField = await screen.findByRole("combobox", {
- name: "Service accounts *",
- });
-
- expect(principalsField).toBeVisible();
- expect(principalsField).toBeEnabled();
-
- await userEvent.type(principalsField, "Alice");
- await userEvent.tab();
-
- await waitFor(() => expect(submitButton).toBeEnabled());
- await userEvent.click(submitButton);
-
await waitFor(() => {
- expect(submitButton).toBeDisabled();
+ expect(mockedNavigate).toHaveBeenLastCalledWith(
+ "/requests/acls?status=CREATED"
+ );
});
-
- expect(spyPost).toHaveBeenCalledTimes(1);
-
- const successModal = await screen.findByRole("dialog");
- const button = within(successModal).getByRole("button", {
- name: "Continue",
+ expect(mockedUseToast).toHaveBeenCalledWith({
+ message: "Acl request successful!",
+ position: "bottom-left",
+ variant: "default",
});
-
- await userEvent.click(button);
-
- expect(mockedNavigate).toHaveBeenLastCalledWith(
- "/requests/acls?status=CREATED"
- );
});
});
});
@@ -2610,10 +2537,15 @@ describe("", () => {
beforeEach(async () => {
dataSetup({ isAivenCluster: false });
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
});
afterEach(() => {
@@ -2838,6 +2770,10 @@ describe("", () => {
});
});
+ afterEach(() => {
+ mockedUseToast.mockReset();
+ });
+
it("creates a new acl request when input was valid", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
@@ -2910,6 +2846,7 @@ describe("", () => {
requestOperationType: "CREATE",
transactionalId: undefined,
});
+ await waitFor(() => expect(mockedUseToast).toHaveBeenCalled());
});
it("renders errors and does not submit when input was invalid", async () => {
@@ -2942,7 +2879,7 @@ describe("", () => {
expect(submitButton).toBeEnabled();
});
- it("shows a dialog informing user that request was successful", async () => {
+ it("shows a notification informing user that request was successful and redirects them", async () => {
const spyPost = jest.spyOn(api, "post");
await assertSkeleton();
@@ -3001,81 +2938,16 @@ describe("", () => {
});
expect(spyPost).toHaveBeenCalledTimes(1);
- const successModal = await screen.findByRole("dialog");
-
- expect(successModal).toBeVisible();
- expect(successModal).toHaveTextContent("Acl request successful!");
- });
-
- it("user can continue to the next page without waiting for redirect in the dialog", async () => {
- const spyPost = jest.spyOn(api, "post");
- await assertSkeleton();
-
- const aclConsumerTypeInput = screen.getByRole("radio", {
- name: "Consumer",
- });
- await userEvent.click(aclConsumerTypeInput);
-
- const submitButton = screen.getByRole("button", {
- name: "Submit request",
- });
-
- // Fill form with valid data
- await selectTestEnvironment();
-
- const visibleTopicNameField = await screen.findByRole("combobox", {
- name: "Topic name *",
- });
-
- await userEvent.selectOptions(
- visibleTopicNameField,
- mockedResponseTopicNames[0]
- );
-
- expect(visibleTopicNameField).toHaveValue(mockedResponseTopicNames[0]);
-
- expect(
- screen.getByRole("radio", { name: "Principal" })
- ).toBeInTheDocument();
-
- await userEvent.click(screen.getByRole("radio", { name: "Principal" }));
- expect(screen.getByRole("radio", { name: "Principal" })).toBeChecked();
-
- const principalsField = await screen.findByRole("textbox", {
- name: "SSL DN strings / Usernames *",
- });
-
- expect(principalsField).toBeVisible();
- expect(principalsField).toBeEnabled();
-
- await userEvent.type(principalsField, "Alice");
- await userEvent.tab();
-
- const consumerGroupField = await screen.findByRole("textbox", {
- name: "Consumer group *",
- });
-
- await userEvent.type(consumerGroupField, "group");
- await userEvent.tab();
-
- await waitFor(() => expect(submitButton).toBeEnabled());
- await userEvent.click(submitButton);
-
await waitFor(() => {
- expect(submitButton).toBeDisabled();
+ expect(mockedNavigate).toHaveBeenLastCalledWith(
+ "/requests/acls?status=CREATED"
+ );
});
-
- expect(spyPost).toHaveBeenCalledTimes(1);
- const successModal = await screen.findByRole("dialog");
- const button = within(successModal).getByRole("button", {
- name: "Continue",
+ expect(mockedUseToast).toHaveBeenCalledWith({
+ message: "Acl request successful!",
+ position: "bottom-left",
+ variant: "default",
});
-
- await userEvent.click(button);
-
- expect(mockedNavigate).toHaveBeenLastCalledWith(
- "/requests/acls?status=CREATED"
- );
});
});
});
diff --git a/coral/src/app/features/topics/acl-request/forms/TopicConsumerForm.tsx b/coral/src/app/features/topics/acl-request/forms/TopicConsumerForm.tsx
index 5dfe734e30..6abfdbf59e 100644
--- a/coral/src/app/features/topics/acl-request/forms/TopicConsumerForm.tsx
+++ b/coral/src/app/features/topics/acl-request/forms/TopicConsumerForm.tsx
@@ -6,6 +6,7 @@ import {
GridItem,
Input,
SecondaryButton,
+ useToast,
} from "@aivenio/aquarium";
import { useMutation } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react";
@@ -47,9 +48,10 @@ const TopicConsumerForm = ({
isSubscription,
}: TopicConsumerFormProps) => {
const [cancelDialogVisible, setCancelDialogVisible] = useState(false);
- const [successModalOpen, setSuccessModalOpen] = useState(false);
const navigate = useNavigate();
+ const toast = useToast();
+
const { aclIpPrincipleType, environment, topicname } =
topicConsumerForm.getValues();
const { current: initialAclIpPrincipleType } = useRef(aclIpPrincipleType);
@@ -70,17 +72,15 @@ const TopicConsumerForm = ({
const { mutate, isLoading, isError, error } = useMutation({
mutationFn: createAclRequest,
onSuccess: () => {
- setSuccessModalOpen(true);
- setTimeout(() => {
- redirectToMyRequests();
- }, 5 * 1000);
+ navigate("/requests/acls?status=CREATED");
+ toast({
+ message: "Acl request successful!",
+ position: "bottom-left",
+ variant: "default",
+ });
},
});
- function redirectToMyRequests() {
- navigate("/requests/acls?status=CREATED");
- }
-
const onSubmitTopicConsumer: SubmitHandler = (
formData
) => {
@@ -119,19 +119,6 @@ const TopicConsumerForm = ({
{parseErrorMsg(error)}
)}
- {successModalOpen && (
-
- )}
", () => {
})
);
customRender(
- ,
+
+
+ ,
{ queryClient: true, memoryRouter: true }
);
});
@@ -207,10 +213,12 @@ describe("", () => {
);
customRender(
- ,
+
+
+ ,
{ queryClient: true, memoryRouter: true }
);
});
@@ -336,10 +344,12 @@ describe("", () => {
})
);
customRender(
- ,
+
+
+ ,
{ queryClient: true, memoryRouter: true }
);
});
@@ -484,10 +494,12 @@ describe("", () => {
})
);
customRender(
- ,
+
+
+ ,
{ queryClient: true, memoryRouter: true }
);
});
@@ -619,10 +631,12 @@ describe("", () => {
);
customRender(
- ,
+
+
+ ,
{ queryClient: true, memoryRouter: true }
);
});
@@ -750,10 +764,12 @@ describe("", () => {
})
);
customRender(
- ,
+
+
+ ,
{ queryClient: true, memoryRouter: true }
);
});
diff --git a/coral/src/app/features/topics/acl-request/forms/TopicProducerForm.tsx b/coral/src/app/features/topics/acl-request/forms/TopicProducerForm.tsx
index da083579c1..4d01b5ec0a 100644
--- a/coral/src/app/features/topics/acl-request/forms/TopicProducerForm.tsx
+++ b/coral/src/app/features/topics/acl-request/forms/TopicProducerForm.tsx
@@ -6,6 +6,7 @@ import {
GridItem,
RadioButton as BaseRadioButton,
SecondaryButton,
+ useToast,
} from "@aivenio/aquarium";
import { useMutation } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react";
@@ -48,9 +49,10 @@ const TopicProducerForm = ({
isSubscription,
}: TopicProducerFormProps) => {
const [cancelDialogVisible, setCancelDialogVisible] = useState(false);
- const [successModalOpen, setSuccessModalOpen] = useState(false);
const navigate = useNavigate();
+ const toast = useToast();
+
const { aclIpPrincipleType, aclPatternType, topicname, environment } =
topicProducerForm.getValues();
const { current: initialAclIpPrincipleType } = useRef(aclIpPrincipleType);
@@ -85,17 +87,15 @@ const TopicProducerForm = ({
const { mutate, isLoading, isError, error } = useMutation({
mutationFn: createAclRequest,
onSuccess: () => {
- setSuccessModalOpen(true);
- setTimeout(() => {
- redirectToMyRequests();
- }, 5 * 1000);
+ navigate("/requests/acls?status=CREATED");
+ toast({
+ message: "Acl request successful!",
+ position: "bottom-left",
+ variant: "default",
+ });
},
});
- function redirectToMyRequests() {
- navigate("/requests/acls?status=CREATED");
- }
-
const onSubmitTopicProducer: SubmitHandler = (
formData
) => {
@@ -117,19 +117,6 @@ const TopicProducerForm = ({
{parseErrorMsg(error)}
)}
- {successModalOpen && (
-
- )}
- {cancelDialogVisible && (
-
- )}
>
);
diff --git a/coral/src/app/features/topics/schema-request/TopicSchemaRequest.test.tsx b/coral/src/app/features/topics/schema-request/TopicSchemaRequest.test.tsx
index 8ca534d761..e7d38d25e8 100644
--- a/coral/src/app/features/topics/schema-request/TopicSchemaRequest.test.tsx
+++ b/coral/src/app/features/topics/schema-request/TopicSchemaRequest.test.tsx
@@ -1,3 +1,4 @@
+import { Context as AquariumContext } from "@aivenio/aquarium";
import * as ReactQuery from "@tanstack/react-query";
import { waitFor, within } from "@testing-library/react";
import {
@@ -35,6 +36,12 @@ jest.mock("react-router-dom", () => ({
useNavigate: () => mockedUsedNavigate,
}));
+const mockedUseToast = jest.fn();
+jest.mock("@aivenio/aquarium", () => ({
+ ...jest.requireActual("@aivenio/aquarium"),
+ useToast: () => mockedUseToast,
+}));
+
const useQuerySpy = jest.spyOn(ReactQuery, "useQuery");
const testTopicName = "my-awesome-topic";
@@ -86,10 +93,15 @@ describe("TopicSchemaRequest", () => {
testTopicName,
]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
const form = getForm();
expect(form).toBeVisible();
@@ -105,10 +117,15 @@ describe("TopicSchemaRequest", () => {
it("redirects user if topicName prop does not exist in list of topicNames", async () => {
mockGetTopicNames.mockResolvedValue(["topic-1", "topic-2"]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
await waitFor(() => {
expect(mockedUsedNavigate).toHaveBeenCalledWith(-1);
@@ -132,11 +149,16 @@ describe("TopicSchemaRequest", () => {
...mockedGetSchemaRegistryEnvironments,
]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- customRoutePath: "/topic/testtopic/request-schema?env=1",
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ customRoutePath: "/topic/testtopic/request-schema?env=1",
+ }
+ );
const form = getForm();
expect(form).toBeVisible();
@@ -166,11 +188,16 @@ describe("TopicSchemaRequest", () => {
...mockedGetSchemaRegistryEnvironments,
]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- customRoutePath: "/topic/testtopic/request-schema?env=INFRA",
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ customRoutePath: "/topic/testtopic/request-schema?env=INFRA",
+ }
+ );
const form = getForm();
expect(form).toBeVisible();
@@ -200,11 +227,16 @@ describe("TopicSchemaRequest", () => {
...mockedGetSchemaRegistryEnvironments,
]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- customRoutePath: "/topic/testtopic/request-schema?env=999",
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ customRoutePath: "/topic/testtopic/request-schema?env=999",
+ }
+ );
await waitFor(() => {
expect(mockedUsedNavigate).toHaveBeenCalledWith(-1);
@@ -216,11 +248,16 @@ describe("TopicSchemaRequest", () => {
...mockedGetSchemaRegistryEnvironments,
]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- customRoutePath: "/topic/testtopic/request-schema?env=HELLO",
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ customRoutePath: "/topic/testtopic/request-schema?env=HELLO",
+ }
+ );
await waitFor(() => {
expect(mockedUsedNavigate).toHaveBeenCalledWith(-1);
@@ -237,10 +274,15 @@ describe("TopicSchemaRequest", () => {
mockCreateSchemaRequest.mockImplementation(jest.fn());
mockGetTopicNames.mockResolvedValue([testTopicName]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
});
afterAll(() => {
@@ -272,10 +314,15 @@ describe("TopicSchemaRequest", () => {
mockCreateSchemaRequest.mockImplementation(jest.fn());
mockGetTopicNames.mockResolvedValue([testTopicName]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
await waitForElementToBeRemoved(
screen.getByTestId("environments-select-loading")
);
@@ -396,10 +443,15 @@ describe("TopicSchemaRequest", () => {
mockCreateSchemaRequest.mockImplementation(jest.fn());
mockGetTopicNames.mockResolvedValue([testTopicName]);
- customRender(, {
- queryClient: true,
- memoryRouter: true,
- });
+ customRender(
+
+
+ ,
+ {
+ queryClient: true,
+ memoryRouter: true,
+ }
+ );
await waitForElementToBeRemoved(
screen.getByTestId("environments-select-loading")
);
@@ -709,6 +761,7 @@ describe("TopicSchemaRequest", () => {
});
afterEach(() => {
+ mockedUseToast.mockReset();
cleanup();
});
@@ -804,6 +857,7 @@ describe("TopicSchemaRequest", () => {
schemafull: "{}",
topicname: "my-awesome-topic",
});
+ await waitFor(() => expect(mockedUseToast).toHaveBeenCalled());
});
it("does not submit on button click if user did not fill all required inputs", async () => {
@@ -824,9 +878,10 @@ describe("TopicSchemaRequest", () => {
await userEvent.tab();
expect(mockCreateSchemaRequest).not.toHaveBeenCalled();
+ expect(mockedUseToast).not.toHaveBeenCalled();
});
- it("shows a dialog informing user that schema request was successful", async () => {
+ it("shows a notification informing user that schema request was successful and redirects them", async () => {
const form = getForm();
const select = within(form).getByRole("combobox", {
@@ -849,43 +904,13 @@ describe("TopicSchemaRequest", () => {
await userEvent.click(button);
expect(mockCreateSchemaRequest).toHaveBeenCalled();
-
- const successModal = await screen.findByRole("dialog");
- expect(successModal).toBeVisible();
- expect(successModal).toHaveTextContent("Schema request successful!");
- });
-
- it("user can continue to the next page without waiting for redirect in the dialog", async () => {
- const form = getForm();
-
- const select = within(form).getByRole("combobox", {
- name: /Environment/i,
- });
- const option = within(select).getByRole("option", {
- name: mockedEnvironments[0].name,
- });
- const fileInput =
- within(form).getByLabelText(/Upload AVRO Schema/i);
-
- const submitButton = within(form).getByRole("button", {
- name: "Submit request",
- });
- expect(submitButton).toBeEnabled();
-
- await userEvent.selectOptions(select, option);
- await userEvent.tab();
- await userEvent.upload(fileInput, testFile);
- await userEvent.click(submitButton);
-
- expect(mockCreateSchemaRequest).toHaveBeenCalled();
-
- const successModal = await screen.findByRole("dialog");
- const button = within(successModal).getByRole("button", {
- name: "Continue",
- });
-
- await userEvent.click(button);
-
+ await waitFor(() =>
+ expect(mockedUseToast).toHaveBeenCalledWith({
+ message: "Schema request successful!",
+ position: "bottom-left",
+ variant: "default",
+ })
+ );
expect(mockedUsedNavigate).toHaveBeenCalledWith(
"/requests/schemas?status=CREATED"
);
diff --git a/coral/src/app/features/topics/schema-request/TopicSchemaRequest.tsx b/coral/src/app/features/topics/schema-request/TopicSchemaRequest.tsx
index 6f3b33051a..0cf2d64656 100644
--- a/coral/src/app/features/topics/schema-request/TopicSchemaRequest.tsx
+++ b/coral/src/app/features/topics/schema-request/TopicSchemaRequest.tsx
@@ -1,4 +1,4 @@
-import { Alert, Box, Button } from "@aivenio/aquarium";
+import { Alert, Box, Button, useToast } from "@aivenio/aquarium";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
@@ -42,9 +42,10 @@ function TopicSchemaRequest(props: TopicSchemaRequestProps) {
const presetEnvironment = searchParams.get("env");
const [cancelDialogVisible, setCancelDialogVisible] = useState(false);
- const [successModalOpen, setSuccessModalOpen] = useState(false);
const navigate = useNavigate();
+ const toast = useToast();
+
const form = useForm({
schema: topicRequestFormSchema,
defaultValues: {
@@ -103,17 +104,15 @@ function TopicSchemaRequest(props: TopicSchemaRequestProps) {
const schemaRequestMutation = useMutation(createSchemaRequest, {
onSuccess: () => {
- setSuccessModalOpen(true);
- setTimeout(() => {
- redirectToMyRequests();
- }, 5 * 1000);
+ navigate("/requests/schemas?status=CREATED");
+ toast({
+ message: "Schema request successful!",
+ position: "bottom-left",
+ variant: "default",
+ });
},
});
- function redirectToMyRequests() {
- navigate("/requests/schemas?status=CREATED");
- }
-
function onSubmitForm(userInput: TopicRequestFormSchema) {
schemaRequestMutation.mutate(userInput);
}
@@ -136,19 +135,6 @@ function TopicSchemaRequest(props: TopicSchemaRequestProps) {
Could not fetch environments.
)}
- {successModalOpen && (
-
- )}
{schemaRequestMutation.isError && (
diff --git a/coral/src/app/pages/topics/schema-request.test.tsx b/coral/src/app/pages/topics/schema-request.test.tsx
index 2ff6464158..dd4786a380 100644
--- a/coral/src/app/pages/topics/schema-request.test.tsx
+++ b/coral/src/app/pages/topics/schema-request.test.tsx
@@ -1,3 +1,4 @@
+import { Context as AquariumContext } from "@aivenio/aquarium";
import { cleanup, screen } from "@testing-library/react/pure";
import SchemaRequest from "src/app/pages/topics/schema-request";
import { getQueryClientForTests } from "src/services/test-utils/query-client-tests";
@@ -40,7 +41,11 @@ describe("SchemaRequest", () => {
}
+ element={
+
+
+
+ }
/>