Skip to content

Commit

Permalink
Add AnnouncementBanner tests; Fix defaultState redundancy (#3311)
Browse files Browse the repository at this point in the history
  • Loading branch information
imnasnainaec authored Aug 22, 2024
1 parent f90b698 commit 0812f13
Show file tree
Hide file tree
Showing 25 changed files with 131 additions and 110 deletions.
3 changes: 2 additions & 1 deletion public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@
"banners": {
"title": "Banners",
"loginBanner": "Login Banner",
"announcementBanner": "Announcement Banner"
"announcementBanner": "Announcement Banner",
"bannerCloseButton": "Close banner"
}
},
"userSettings": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useEffect,
useState,
} from "react";
import { useTranslation } from "react-i18next";

import { BannerType } from "api/models";
import { getBannerText } from "backend";
Expand All @@ -18,10 +19,20 @@ import { type StoreState } from "rootRedux/types";
import { Path } from "types/path";
import theme, { themeColors } from "types/theme";

enum AnnouncementBannerId {
ButtonClose = "announcement-banner-close-button",
}

export enum AnnouncementBannerTextId {
ButtonClose = "siteSettings.banners.bannerCloseButton",
}

export default function AnnouncementBanner(): ReactElement {
const [banner, setBanner] = useState<string>("");
const [margins, setMargins] = useState<CSSProperties>({});

const { t } = useTranslation();

// Adjust the margins depending on whether there is an AppBar.
const loc = useAppSelector(
(state: StoreState) => state.analyticsState.currentPage
Expand All @@ -48,7 +59,12 @@ export default function AnnouncementBanner(): ReactElement {

return banner ? (
<Toolbar style={{ ...margins, backgroundColor: themeColors.warning }}>
<IconButton onClick={closeBanner} size="large">
<IconButton
aria-label={t(AnnouncementBannerTextId.ButtonClose)}
id={AnnouncementBannerId.ButtonClose}
onClick={closeBanner}
size="large"
>
<Cancel />
</IconButton>
<Box sx={{ width: theme.spacing(2) }} />
Expand Down
73 changes: 73 additions & 0 deletions src/components/AnnouncementBanner/tests/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { act } from "react";
import { Provider } from "react-redux";
import createMockStore from "redux-mock-store";

import AnnouncementBanner, {
AnnouncementBannerTextId,
} from "components/AnnouncementBanner";
import { defaultState } from "rootRedux/types";

jest.mock("backend", () => ({
getBannerText: () => mockGetBannerText(),
}));

const mockBannerText = "I'm a banner!";
const mockGetBannerText = jest.fn();
const mockStore = createMockStore()(defaultState);

const renderAnnouncementBanner = async (bannerText?: string): Promise<void> => {
mockGetBannerText.mockResolvedValue(bannerText ?? "");
await act(async () => {
render(
<Provider store={mockStore}>
<AnnouncementBanner />
</Provider>
);
});
};

beforeEach(() => {
jest.clearAllMocks();
});

describe("AnnouncementBanner", () => {
it("doesn't load if no banner text", async () => {
await renderAnnouncementBanner();

// Confirm no banner by the absence of its close button
expect(
screen.queryByLabelText(AnnouncementBannerTextId.ButtonClose)
).toBeNull();
});

it("loads banner with text", async () => {
await renderAnnouncementBanner(mockBannerText);

// Confirm open banner by the presence of its close button and text
expect(
screen.queryByLabelText(AnnouncementBannerTextId.ButtonClose)
).not.toBeNull();
expect(screen.queryByText(mockBannerText)).not.toBeNull();
});

it("closes when button is clicked", async () => {
// Setup
const agent = userEvent.setup();
await renderAnnouncementBanner(mockBannerText);
expect(screen.queryByText(mockBannerText)).not.toBeNull();

// Click close button
const closeButton = screen.getByLabelText(
AnnouncementBannerTextId.ButtonClose
);
await agent.click(closeButton);

// Confirm closed
expect(
screen.queryByLabelText(AnnouncementBannerTextId.ButtonClose)
).toBeNull();
expect(screen.queryByText(mockBannerText)).toBeNull();
});
});
34 changes: 0 additions & 34 deletions src/components/App/DefaultState.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ReactElement, Suspense } from "react";
import { RouterProvider } from "react-router-dom";

import AnnouncementBanner from "components/AnnouncementBanner/AnnouncementBanner";
import AnnouncementBanner from "components/AnnouncementBanner";
import UpperRightToastContainer from "components/Toast/UpperRightToastContainer";
import router from "router/browserRouter";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { render } from "@testing-library/react";
import "jest-canvas-mock";
import { act } from "react";
import { Provider } from "react-redux";
import { act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";
import thunk from "redux-thunk";

import { defaultState } from "components/App/DefaultState";
import App from "components/App/component";
import App from "components/App";
import { defaultState } from "rootRedux/types";

jest.mock("react-router-dom");

jest.mock("components/AnnouncementBanner/AnnouncementBanner", () => "div");

const createMockStore = configureMockStore([thunk]);
const mockStore = createMockStore(defaultState);

Expand All @@ -22,7 +21,7 @@ global.analytics = { track: jest.fn() } as any;
describe("App", () => {
it("renders without crashing", async () => {
await act(async () => {
create(
render(
<Provider store={mockStore}>
<App />
</Provider>
Expand Down
2 changes: 1 addition & 1 deletion src/components/AppBar/tests/AppBarComponent.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { MemoryRouter } from "react-router-dom";
import { act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import { defaultState } from "components/App/DefaultState";
import AppBar from "components/AppBar/AppBarComponent";
import { defaultState } from "rootRedux/types";

jest.mock("backend", () => ({
isSiteAdmin: () => mockIsSiteAdmin(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
import configureMockStore from "redux-mock-store";

import { Word } from "api/models";
import { defaultState } from "components/App/DefaultState";
import { NoteButton } from "components/Buttons";
import {
DeleteEntry,
Expand All @@ -21,6 +20,7 @@ import { EditTextDialog } from "components/Dialogs";
import AudioPlayer from "components/Pronunciations/AudioPlayer";
import AudioRecorder from "components/Pronunciations/AudioRecorder";
import PronunciationsBackend from "components/Pronunciations/PronunciationsBackend";
import { defaultState } from "rootRedux/types";
import theme from "types/theme";
import { newPronunciation, simpleWord } from "types/word";
import { newWritingSystem } from "types/writingSystem";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
import configureMockStore from "redux-mock-store";

import { Gloss, SemanticDomain, Sense, Word } from "api/models";
import { defaultState } from "components/App/DefaultState";
import DataEntryTable, {
WordAccess,
addSemanticDomainToSense,
Expand All @@ -20,6 +19,7 @@ import DataEntryTable, {
updateEntryGloss,
} from "components/DataEntry/DataEntryTable";
import NewEntry from "components/DataEntry/DataEntryTable/NewEntry";
import { defaultState } from "rootRedux/types";
import { newProject } from "types/project";
import {
newSemanticDomain,
Expand Down
12 changes: 2 additions & 10 deletions src/components/Project/tests/ProjectActions.test.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { type PreloadedState } from "redux";

import { type Project, type Speaker } from "api/models";
import { defaultState } from "components/App/DefaultState";
import {
asyncRefreshProjectUsers,
asyncSetNewCurrentProject,
asyncUpdateCurrentProject,
clearCurrentProject,
} from "components/Project/ProjectActions";
import { defaultState as currentProjectState } from "components/Project/ProjectReduxTypes";
import { type RootState, setupStore } from "rootRedux/store";
import { setupStore } from "rootRedux/store";
import { persistedDefaultState } from "rootRedux/testTypes";
import { newProject } from "types/project";
import { newUser } from "types/user";

Expand All @@ -26,12 +24,6 @@ const mockGetAllSemDomNames = jest.fn();
const mockUpdateProject = jest.fn();
const mockProjId = "project-id";

// Preloaded values for store when testing
const persistedDefaultState: PreloadedState<RootState> = {
...defaultState,
_persist: { version: 1, rehydrated: false },
};

beforeEach(() => {
jest.resetAllMocks();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { PreloadedState } from "redux";

import { defaultState } from "components/App/DefaultState";
import {
asyncDownloadExport,
asyncExportProject,
asyncResetExport,
} from "components/ProjectExport/Redux/ExportProjectActions";
import { ExportStatus } from "components/ProjectExport/Redux/ExportProjectReduxTypes";
import { RootState, setupStore } from "rootRedux/store";
import { setupStore } from "rootRedux/store";
import { persistedDefaultState } from "rootRedux/testTypes";

jest.mock("backend", () => ({
deleteLift: jest.fn,
Expand All @@ -20,12 +18,6 @@ const mockDownloadList = jest.fn();
const mockExportLift = jest.fn();
const mockProjId = "project-id";

// Preloaded values for store when testing
const persistedDefaultState: PreloadedState<RootState> = {
...defaultState,
_persist: { version: 1, rehydrated: false },
};

describe("ExportProjectActions", () => {
describe("asyncDownloadExport", () => {
it("correctly affects state on success", async () => {
Expand Down
3 changes: 1 addition & 2 deletions src/components/Pronunciations/tests/AudioPlayer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ import { Provider } from "react-redux";
import { type ReactTestRenderer, act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import { defaultState } from "components/App/DefaultState";
import AudioPlayer, {
longPressDelay,
playButtonId,
playMenuId,
} from "components/Pronunciations/AudioPlayer";
import { PronunciationsStatus } from "components/Pronunciations/Redux/PronunciationsReduxTypes";
import { type StoreState } from "rootRedux/types";
import { type StoreState, defaultState } from "rootRedux/types";
import { newPronunciation } from "types/word";

// Mock out Menu to avoid issues with setting its anchor.
Expand Down
3 changes: 1 addition & 2 deletions src/components/Pronunciations/tests/AudioRecorder.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ import { Provider } from "react-redux";
import { ReactTestRenderer, act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import { defaultState } from "components/App/DefaultState";
import AudioRecorder from "components/Pronunciations/AudioRecorder";
import { recordIconId } from "components/Pronunciations/RecorderIcon";
import { PronunciationsStatus } from "components/Pronunciations/Redux/PronunciationsReduxTypes";
import { type StoreState } from "rootRedux/types";
import { type StoreState, defaultState } from "rootRedux/types";
import theme, { themeColors } from "types/theme";

let testRenderer: ReactTestRenderer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Provider } from "react-redux";
import { ReactTestRenderer, act, create } from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import { defaultState } from "components/App/DefaultState";
import AudioPlayer from "components/Pronunciations/AudioPlayer";
import AudioRecorder from "components/Pronunciations/AudioRecorder";
import PronunciationsBackend from "components/Pronunciations/PronunciationsBackend";
import { defaultState } from "rootRedux/types";
import theme from "types/theme";
import { newPronunciation } from "types/word";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Provider } from "react-redux";
import renderer from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import { defaultState } from "components/App/DefaultState";
import AudioPlayer from "components/Pronunciations/AudioPlayer";
import AudioRecorder from "components/Pronunciations/AudioRecorder";
import PronunciationsFrontend from "components/Pronunciations/PronunciationsFrontend";
import { defaultState } from "rootRedux/types";
import theme from "types/theme";
import { newPronunciation } from "types/word";

Expand Down
3 changes: 1 addition & 2 deletions src/components/Pronunciations/tests/RecorderIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import {
} from "react-test-renderer";
import configureMockStore from "redux-mock-store";

import { defaultState } from "components/App/DefaultState";
import RecorderIcon, {
recordButtonId,
} from "components/Pronunciations/RecorderIcon";
import { PronunciationsStatus } from "components/Pronunciations/Redux/PronunciationsReduxTypes";
import { type StoreState } from "rootRedux/types";
import { type StoreState, defaultState } from "rootRedux/types";
import theme from "types/theme";

let testRenderer: ReactTestRenderer;
Expand Down
12 changes: 2 additions & 10 deletions src/components/TreeView/Redux/tests/TreeViewActions.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { PreloadedState } from "redux";

import { defaultState } from "components/App/DefaultState";
import {
initTreeDomain,
setDomainLanguage,
traverseTree,
} from "components/TreeView/Redux/TreeViewActions";
import { RootState, setupStore } from "rootRedux/store";
import { setupStore } from "rootRedux/store";
import { persistedDefaultState } from "rootRedux/testTypes";
import {
newSemanticDomain,
newSemanticDomainTreeNode,
Expand All @@ -27,12 +25,6 @@ global.analytics = { identify: jest.fn(), track: jest.fn() } as any;
const mockId = "1.2.3";
const mockLang = "lang";

// Preloaded values for store when testing
const persistedDefaultState: PreloadedState<RootState> = {
...defaultState,
_persist: { version: 1, rehydrated: false },
};

describe("TreeViewActions", () => {
describe("setDomainLanguage", () => {
it("correctly affects state", async () => {
Expand Down
Loading

0 comments on commit 0812f13

Please sign in to comment.