mirror of
https://github.com/wassname/talk.git
synced 2026-08-04 13:23:35 +08:00
[next] Fix warnings and errors that appear during test (#2348)
* fix: handle react act errors * fix: fixed deprecated reporter option
This commit is contained in:
@@ -2,6 +2,7 @@ import sinon from "sinon";
|
||||
|
||||
import { GQLResolver } from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createAccessToken,
|
||||
CreateTestRendererParams,
|
||||
replaceHistoryLocation,
|
||||
@@ -52,11 +53,13 @@ it("renders form", async () => {
|
||||
})
|
||||
.once();
|
||||
|
||||
await waitForElement(() =>
|
||||
within(root).getByText("Reset your password", {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
await act(async () => {
|
||||
await waitForElement(() =>
|
||||
within(root).getByText("Reset your password", {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
expect(within(root).toJSON()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
});
|
||||
@@ -91,11 +94,13 @@ it("renders error from server", async () => {
|
||||
})
|
||||
);
|
||||
|
||||
await waitForElement(() =>
|
||||
within(root).getByText(code, {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
await act(async () => {
|
||||
await waitForElement(() =>
|
||||
within(root).getByText(code, {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
restMock.verify();
|
||||
}
|
||||
});
|
||||
@@ -126,36 +131,42 @@ it("submits form", async () => {
|
||||
})
|
||||
.once();
|
||||
|
||||
await waitForElement(() =>
|
||||
within(root).getByText("Reset your password", {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await waitForElement(() =>
|
||||
within(root).getByText("Reset your password", {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
const form = within(root).getByType("form");
|
||||
const textField = within(root).getByLabelText("Password");
|
||||
|
||||
// Submit an empty form.
|
||||
form.props.onSubmit();
|
||||
act(() => {
|
||||
form.props.onSubmit();
|
||||
});
|
||||
within(root).getByText("field is required", {
|
||||
exact: false,
|
||||
});
|
||||
|
||||
// Password too short.
|
||||
textField.props.onChange("test");
|
||||
act(() => {
|
||||
textField.props.onChange("test");
|
||||
});
|
||||
within(root).getByText("Password must contain at least 8 characters", {
|
||||
exact: false,
|
||||
});
|
||||
|
||||
// Submit valid form.
|
||||
textField.props.onChange("testtest");
|
||||
form.props.onSubmit();
|
||||
|
||||
await waitForElement(() =>
|
||||
within(root).getByText("successfully", {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
await act(async () => {
|
||||
textField.props.onChange("testtest");
|
||||
form.props.onSubmit();
|
||||
await waitForElement(() =>
|
||||
within(root).getByText("successfully", {
|
||||
exact: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
restMock.verify();
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { pureMerge } from "coral-common/utils";
|
||||
import { GQLResolver } from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createAccessToken,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
@@ -117,11 +118,13 @@ it("do not render createPassword view when local auth is disabled", async () =>
|
||||
}),
|
||||
});
|
||||
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/reported"
|
||||
)
|
||||
);
|
||||
await act(async () => {
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/reported"
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("complete account", async () => {
|
||||
@@ -137,9 +140,11 @@ it("complete account", async () => {
|
||||
},
|
||||
}),
|
||||
});
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/reported"
|
||||
)
|
||||
);
|
||||
await act(async () => {
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/reported"
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
QueryToModerationQueuesResolver,
|
||||
} from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createAccessToken,
|
||||
createQueryResolverStub,
|
||||
createResolversStub,
|
||||
@@ -55,11 +56,13 @@ async function createTestRenderer(
|
||||
|
||||
it("redirect when already logged in", async () => {
|
||||
await createTestRenderer();
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/reported"
|
||||
)
|
||||
);
|
||||
await act(async () => {
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/reported"
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("redirect to redirectPath when already logged in", async () => {
|
||||
@@ -68,9 +71,11 @@ it("redirect to redirectPath when already logged in", async () => {
|
||||
localRecord.setValue("/admin/moderate/pending", "redirectPath");
|
||||
},
|
||||
});
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/pending"
|
||||
)
|
||||
);
|
||||
await act(async () => {
|
||||
await wait(() =>
|
||||
expect(window.location.toString()).toBe(
|
||||
"http://localhost/admin/moderate/pending"
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
QueryToModerationQueuesResolver,
|
||||
} from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createQueryResolverStub,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
@@ -50,10 +51,12 @@ async function createTestRenderer(
|
||||
|
||||
it("redirect when not logged in", async () => {
|
||||
const { context } = await createTestRenderer();
|
||||
await wait(() => {
|
||||
expect(lookup(context.relayEnvironment, LOCAL_ID)!.redirectPath).toBe(
|
||||
"/admin/moderate/reported"
|
||||
);
|
||||
expect(window.location.toString()).toBe("http://localhost/admin/login");
|
||||
await act(async () => {
|
||||
await wait(() => {
|
||||
expect(lookup(context.relayEnvironment, LOCAL_ID)!.redirectPath).toBe(
|
||||
"/admin/moderate/reported"
|
||||
);
|
||||
expect(window.location.toString()).toBe("http://localhost/admin/login");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,6 +3,7 @@ import sinon from "sinon";
|
||||
import { pureMerge } from "coral-common/utils";
|
||||
import { GQLResolver } from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createAccessToken,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
@@ -12,6 +13,7 @@ import {
|
||||
within,
|
||||
} from "coral-framework/testHelpers";
|
||||
|
||||
import { ReactTestInstance } from "react-test-renderer";
|
||||
import create from "../create";
|
||||
import {
|
||||
emptyModerationQueues,
|
||||
@@ -47,10 +49,14 @@ async function createTestRenderer(
|
||||
},
|
||||
});
|
||||
|
||||
const form = await waitForElement(() =>
|
||||
within(testRenderer.root).getByType("form")
|
||||
);
|
||||
return { testRenderer, form, context };
|
||||
let form: ReactTestInstance;
|
||||
|
||||
await act(async () => {
|
||||
form = await waitForElement(() =>
|
||||
within(testRenderer.root).getByType("form")
|
||||
);
|
||||
});
|
||||
return { testRenderer, form: form!, context };
|
||||
}
|
||||
|
||||
it("renders sign in form", async () => {
|
||||
@@ -150,12 +156,16 @@ it("submits form successfully", async () => {
|
||||
|
||||
const historyMock = sinon.mock(window.history);
|
||||
|
||||
form.props.onSubmit();
|
||||
act(() => {
|
||||
form.props.onSubmit();
|
||||
});
|
||||
const submitButton = within(form).getByText("Sign in with Email", {
|
||||
selector: "button",
|
||||
});
|
||||
expect(submitButton.props.disabled).toBe(true);
|
||||
await wait(() => expect(submitButton.props.disabled).toBe(false));
|
||||
await act(async () => {
|
||||
await wait(() => expect(submitButton.props.disabled).toBe(false));
|
||||
});
|
||||
expect(location.toString()).toMatchSnapshot();
|
||||
restMock.verify();
|
||||
historyMock.verify();
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
QueryToUsersResolver,
|
||||
} from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createQueryResolverStub,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
@@ -101,17 +102,14 @@ it("filter by role", async () => {
|
||||
const selectField = within(container).getByLabelText("Search by role");
|
||||
const commentersOption = within(selectField).getByText("Commenters");
|
||||
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
selectField.props.onChange({
|
||||
target: { value: commentersOption.props.value.toString() },
|
||||
});
|
||||
// TODO: Fix act warnings until await Promise.resolve();
|
||||
// or whatever comes out at https://github.com/facebook/react/issues/14769
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("We could not find anyone", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("We could not find anyone", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
it("can't change viewer role", async () => {
|
||||
@@ -149,7 +147,7 @@ it("change user role", async () => {
|
||||
selector: "tr",
|
||||
});
|
||||
|
||||
TestRenderer.act(() => {
|
||||
act(() => {
|
||||
within(userRow)
|
||||
.getByLabelText("Change role")
|
||||
.props.onClick();
|
||||
@@ -159,7 +157,7 @@ it("change user role", async () => {
|
||||
"A dropdown to change the user role"
|
||||
);
|
||||
|
||||
TestRenderer.act(() => {
|
||||
act(() => {
|
||||
within(popup)
|
||||
.getByText("Staff", { selector: "button" })
|
||||
.props.onClick();
|
||||
@@ -223,13 +221,11 @@ it("load more", async () => {
|
||||
}),
|
||||
});
|
||||
const loadMore = within(container).getByText("Load More");
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
loadMore.props.onClick();
|
||||
// Wait for load more to disappear.
|
||||
await waitUntilThrow(() => within(container).getByText("Load More"));
|
||||
});
|
||||
|
||||
// Wait for load more to disappear.
|
||||
await waitUntilThrow(() => within(container).getByText("Load More"));
|
||||
|
||||
// Make sure third user was added.
|
||||
within(container).getByText(users.commenters[1].username!);
|
||||
});
|
||||
@@ -256,16 +252,15 @@ it("filter by search", async () => {
|
||||
});
|
||||
const form = findParentWithType(searchField, "form")!;
|
||||
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
searchField.props.onChange({
|
||||
target: { value: "search" },
|
||||
});
|
||||
form.props.onSubmit();
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("could not find anyone", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("could not find anyone", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
it("filter by status", async () => {
|
||||
@@ -293,17 +288,14 @@ it("filter by status", async () => {
|
||||
);
|
||||
const bannedOption = within(statusField).getByText("Banned");
|
||||
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
statusField.props.onChange({
|
||||
target: { value: bannedOption.props.value.toString() },
|
||||
});
|
||||
// TODO: Fix act warnings until await Promise.resolve();
|
||||
// or whatever comes out at https://github.com/facebook/react/issues/14769
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("We could not find anyone", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("We could not find anyone", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
it("can't change staff, moderator and admin status", async () => {
|
||||
@@ -373,9 +365,11 @@ it("ban user", async () => {
|
||||
|
||||
expect(within(modal).toJSON()).toMatchSnapshot();
|
||||
|
||||
within(modal)
|
||||
.getByText("Ban User")
|
||||
.props.onClick();
|
||||
TestRenderer.act(() => {
|
||||
within(modal)
|
||||
.getByText("Ban User")
|
||||
.props.onClick();
|
||||
});
|
||||
within(userRow).getByText("Banned");
|
||||
expect(resolvers.Mutation!.banUser!.called).toBe(true);
|
||||
});
|
||||
|
||||
@@ -1196,27 +1196,6 @@ exports[`reported queue rejects comment in reported queue: dangling 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`reported queue renders empty reported queue 1`] = `
|
||||
<div
|
||||
className="MainLayout-root"
|
||||
data-testid="moderate-main-container"
|
||||
>
|
||||
<main
|
||||
className="Moderate-main"
|
||||
>
|
||||
<div
|
||||
className="HorizontalGutter-root Queue-root HorizontalGutter-double"
|
||||
>
|
||||
<div
|
||||
className="Card-root EmptyMessage-root"
|
||||
>
|
||||
Nicely done! There are no more reported comments to moderate.
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`reported queue renders reported queue with comments 1`] = `
|
||||
<div
|
||||
className="MainLayout-root"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
import { noop } from "lodash";
|
||||
import TestRenderer from "react-test-renderer";
|
||||
|
||||
import { pureMerge } from "coral-common/utils";
|
||||
import {
|
||||
act,
|
||||
createMutationResolverStub,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
@@ -92,10 +92,11 @@ it("goes to moderation when clicking on title", async () => {
|
||||
transitionControl.allowTransition = false;
|
||||
|
||||
const story = storyConnection.edges[0].node;
|
||||
within(container)
|
||||
.getByText(story.metadata!.title!)
|
||||
.props.onClick({ button: 0, preventDefault: noop });
|
||||
|
||||
act(() => {
|
||||
within(container)
|
||||
.getByText(story.metadata!.title!)
|
||||
.props.onClick({ button: 0, preventDefault: noop });
|
||||
});
|
||||
// Expect a routing request was made to the right url.
|
||||
expect(transitionControl.history[0].pathname).toBe(
|
||||
`/admin/moderate/${story.id}`
|
||||
@@ -122,17 +123,14 @@ it("filter by status", async () => {
|
||||
const selectField = within(container).getByLabelText("Search by status");
|
||||
const closedOption = within(selectField).getByText("Closed Stories");
|
||||
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
selectField.props.onChange({
|
||||
target: { value: closedOption.props.value.toString() },
|
||||
});
|
||||
// TODO: Fix act warnings until await Promise.resolve();
|
||||
// or whatever comes out at https://github.com/facebook/react/issues/14769
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("could not find any", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("could not find any", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
it("change story status", async () => {
|
||||
@@ -185,11 +183,11 @@ it("change story status", async () => {
|
||||
);
|
||||
|
||||
/** CLOSE STORY */
|
||||
TestRenderer.act(() => {
|
||||
act(() => {
|
||||
changeStatusButton.props.onClick();
|
||||
});
|
||||
|
||||
TestRenderer.act(() => {
|
||||
act(() => {
|
||||
within(popup)
|
||||
.getByText("Closed", { selector: "button" })
|
||||
.props.onClick();
|
||||
@@ -199,11 +197,11 @@ it("change story status", async () => {
|
||||
expect(closeStory.called).toBe(true);
|
||||
|
||||
/** OPEN STORY */
|
||||
TestRenderer.act(() => {
|
||||
act(() => {
|
||||
changeStatusButton.props.onClick();
|
||||
});
|
||||
|
||||
TestRenderer.act(() => {
|
||||
act(() => {
|
||||
within(popup)
|
||||
.getByText("Open", { selector: "button" })
|
||||
.props.onClick();
|
||||
@@ -244,13 +242,12 @@ it("load more", async () => {
|
||||
}),
|
||||
});
|
||||
const loadMore = within(container).getByText("Load More");
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
loadMore.props.onClick();
|
||||
// Wait for load more to disappear.
|
||||
await waitUntilThrow(() => within(container).getByText("Load More"));
|
||||
});
|
||||
|
||||
// Wait for load more to disappear.
|
||||
await waitUntilThrow(() => within(container).getByText("Load More"));
|
||||
|
||||
// Make sure third user was added.
|
||||
within(container).getByText(stories[2].metadata!.title!);
|
||||
});
|
||||
@@ -278,16 +275,15 @@ it("filter by search", async () => {
|
||||
);
|
||||
const form = findParentWithType(searchField, "form")!;
|
||||
|
||||
TestRenderer.act(() => {
|
||||
await act(async () => {
|
||||
searchField.props.onChange({
|
||||
target: { value: "search" },
|
||||
});
|
||||
form.props.onSubmit();
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("could not find any", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
await waitForElement(() =>
|
||||
within(container).getByText("could not find any", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
it("use searchFilter from url", async () => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { act } from "react-test-renderer";
|
||||
import sinon from "sinon";
|
||||
|
||||
import { pureMerge } from "coral-common/utils";
|
||||
import { GQLResolver } from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
wait,
|
||||
@@ -134,14 +134,14 @@ it("submits form successfully", async () => {
|
||||
})
|
||||
.once();
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
emailField.props.onChange("hans@test.com");
|
||||
form!.props.onSubmit();
|
||||
await waitForElement(() =>
|
||||
within(testRenderer.root).getByText("Check Your Email", { exact: false })
|
||||
);
|
||||
});
|
||||
|
||||
await waitForElement(() =>
|
||||
within(testRenderer.root).getByText("Check Your Email", { exact: false })
|
||||
);
|
||||
within(testRenderer.root)
|
||||
.getByText("Close")
|
||||
.props.onClick();
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import TestRenderer from "react-test-renderer";
|
||||
|
||||
export default function act(
|
||||
callback: () => Promise<void> | void | undefined
|
||||
): Promise<void> | void {
|
||||
return TestRenderer.act(callback as any) as any;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ export {
|
||||
} from "./removeFragmentRefs";
|
||||
export { default as createUUIDGenerator } from "./createUUIDGenerator";
|
||||
export * from "./denormalize";
|
||||
export { default as act } from "./act";
|
||||
export { default as limitSnapshotTo } from "./limitSnapshotTo";
|
||||
export { default as within } from "./within";
|
||||
export { default as wait } from "./wait";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { pureMerge } from "coral-common/utils";
|
||||
import { GQLResolver } from "coral-framework/schema";
|
||||
import {
|
||||
act,
|
||||
createResolversStub,
|
||||
CreateTestRendererParams,
|
||||
waitForElement,
|
||||
@@ -69,23 +70,29 @@ it("ignore user", async () => {
|
||||
const username = within(comment).getByText(firstCommentAuthor.username!, {
|
||||
selector: "button",
|
||||
});
|
||||
username.props.onClick();
|
||||
act(() => {
|
||||
username.props.onClick();
|
||||
});
|
||||
const ignoreButton = within(comment).getByText("Ignore", {
|
||||
selector: "button",
|
||||
});
|
||||
ignoreButton.props.onClick();
|
||||
act(() => {
|
||||
ignoreButton.props.onClick();
|
||||
});
|
||||
within(comment).getByText("Cancel", {
|
||||
selector: "button",
|
||||
});
|
||||
within(comment)
|
||||
.getByText("Ignore", {
|
||||
selector: "button",
|
||||
})
|
||||
.props.onClick();
|
||||
// Check for a tombstone
|
||||
await waitForElement(() =>
|
||||
within(tabPane).getByText("This comment is hidden", { exact: false })
|
||||
);
|
||||
await act(async () => {
|
||||
within(comment)
|
||||
.getByText("Ignore", {
|
||||
selector: "button",
|
||||
})
|
||||
.props.onClick();
|
||||
// Check for a tombstone
|
||||
await waitForElement(() =>
|
||||
within(tabPane).getByText("This comment is hidden", { exact: false })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("render stream with ignored user", async () => {
|
||||
|
||||
@@ -1,38 +1,35 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`map new speech prop to older aural prop 1`] = `
|
||||
<MediaQuery
|
||||
<MediaQueryContextConsumer
|
||||
aural={true}
|
||||
values={Object {}}
|
||||
>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
</MediaQuery>
|
||||
</MediaQueryContextConsumer>
|
||||
`;
|
||||
|
||||
exports[`renders correctly 1`] = `
|
||||
<MediaQuery
|
||||
<MediaQueryContextConsumer
|
||||
component="div"
|
||||
maxWidth={320}
|
||||
minWidth={640}
|
||||
screen={true}
|
||||
values={Object {}}
|
||||
>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
</MediaQuery>
|
||||
</MediaQueryContextConsumer>
|
||||
`;
|
||||
|
||||
exports[`renders less than and great than correctly 1`] = `
|
||||
<MediaQuery
|
||||
<MediaQueryContextConsumer
|
||||
maxWidth={319}
|
||||
minWidth={641}
|
||||
values={Object {}}
|
||||
>
|
||||
<div>
|
||||
Hello World
|
||||
</div>
|
||||
</MediaQuery>
|
||||
</MediaQueryContextConsumer>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user