Skip to content
Snippets Groups Projects
Unverified Commit 76a19020 authored by Alexander Polyankin's avatar Alexander Polyankin Committed by GitHub
Browse files

Handle api errors in entity hooks (#30687)

parent 1d21c85a
No related branches found
No related tags found
No related merge requests found
import React from "react";
import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
import { createMockDatabase } from "metabase-types/api/mocks";
import { setupDatabasesEndpoints } from "__support__/server-mocks";
import {
PERMISSION_ERROR,
setupDatabasesEndpoints,
setupUnauthorizedDatabasesEndpoints,
} from "__support__/server-mocks";
import {
renderWithProviders,
screen,
......@@ -23,8 +27,17 @@ const TestComponent = () => {
return <div>{data.name}</div>;
};
const setup = () => {
setupDatabasesEndpoints([TEST_DATABASE]);
interface SetupOpts {
hasDataAccess?: boolean;
}
const setup = ({ hasDataAccess = true }: SetupOpts = {}) => {
if (hasDataAccess) {
setupDatabasesEndpoints([TEST_DATABASE]);
} else {
setupUnauthorizedDatabasesEndpoints([TEST_DATABASE]);
}
renderWithProviders(<TestComponent />);
};
......@@ -39,4 +52,10 @@ describe("useDatabaseQuery", () => {
await waitForElementToBeRemoved(() => screen.queryByText("Loading..."));
expect(screen.getByText(TEST_DATABASE.name)).toBeInTheDocument();
});
it("should show error from the response", async () => {
setup({ hasDataAccess: false });
await waitForElementToBeRemoved(() => screen.queryByText("Loading..."));
expect(screen.getByText(PERMISSION_ERROR)).toBeInTheDocument();
});
});
import { useEffect } from "react";
import { useDeepCompareEffect } from "react-use";
import type { Action } from "@reduxjs/toolkit";
import { useDispatch, useSelector } from "metabase/lib/redux";
import { State } from "metabase-types/store";
......@@ -52,9 +52,10 @@ export const useEntityListQuery = <TItem, TQuery>(
const error = useSelector(state => getError(state, options));
const dispatch = useDispatch();
useEffect(() => {
useDeepCompareEffect(() => {
if (enabled) {
dispatch(fetchList(entityQuery, { reload }));
const action = dispatch(fetchList(entityQuery, { reload }));
Promise.resolve(action).catch(() => undefined);
}
}, [dispatch, fetchList, entityQuery, reload, enabled]);
......
import { useEffect } from "react";
import { useDeepCompareEffect } from "react-use";
import type { Action } from "@reduxjs/toolkit";
import { useDispatch, useSelector } from "metabase/lib/redux";
import { State } from "metabase-types/store";
......@@ -61,10 +61,11 @@ export const useEntityQuery = <TId, TItem, TQuery>(
const error = useSelector(state => getError(state, options));
const dispatch = useDispatch();
useEffect(() => {
useDeepCompareEffect(() => {
if (entityId != null && enabled) {
const query = { ...entityQuery, id: entityId };
dispatch(fetch(query, { reload, requestType }));
const action = dispatch(fetch(query, { reload, requestType }));
Promise.resolve(action).catch(() => undefined);
}
}, [dispatch, fetch, entityId, entityQuery, enabled, reload, requestType]);
......
import React from "react";
import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper";
import { createMockDatabase, createMockTable } from "metabase-types/api/mocks";
import { setupDatabasesEndpoints } from "__support__/server-mocks";
import {
PERMISSION_ERROR,
setupDatabasesEndpoints,
setupUnauthorizedDatabasesEndpoints,
} from "__support__/server-mocks";
import {
renderWithProviders,
screen,
......@@ -37,8 +41,17 @@ const TestComponent = () => {
);
};
const setup = () => {
setupDatabasesEndpoints([TEST_DATABASE]);
interface SetupOpts {
hasDataAccess?: boolean;
}
const setup = ({ hasDataAccess = true }: SetupOpts = {}) => {
if (hasDataAccess) {
setupDatabasesEndpoints([TEST_DATABASE]);
} else {
setupUnauthorizedDatabasesEndpoints([TEST_DATABASE]);
}
renderWithProviders(<TestComponent />);
};
......@@ -53,4 +66,10 @@ describe("useSchemaListQuery", () => {
await waitForElementToBeRemoved(() => screen.queryByText("Loading..."));
expect(screen.getByText(TEST_TABLE.schema)).toBeInTheDocument();
});
it("should show error from the response", async () => {
setup({ hasDataAccess: false });
await waitForElementToBeRemoved(() => screen.queryByText("Loading..."));
expect(screen.getByText(PERMISSION_ERROR)).toBeInTheDocument();
});
});
......@@ -64,6 +64,8 @@ export function setupUnauthorizedDatabaseEndpoints(db: Database) {
status: 403,
body: PERMISSION_ERROR,
});
setupUnauthorizedSchemaEndpoints(db);
}
export function setupUnauthorizedDatabasesEndpoints(dbs: Database[]) {
......
......@@ -4,6 +4,7 @@ export * from "./alert";
export * from "./bookmark";
export * from "./card";
export * from "./collection";
export * from "./constants";
export * from "./dashboard";
export * from "./database";
export * from "./dataset";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment