diff --git a/frontend/src/App/app.test.tsx b/frontend/src/App/app.test.tsx index b5aea7e63..f6236cdc9 100644 --- a/frontend/src/App/app.test.tsx +++ b/frontend/src/App/app.test.tsx @@ -1,14 +1,9 @@ import { render } from "@/tests"; -import { StrictMode } from "react"; import { describe, it } from "vitest"; import App from "."; describe("App", () => { it("should render without crash", () => { - render( - - - - ); + render(); }); }); diff --git a/frontend/src/App/index.tsx b/frontend/src/App/index.tsx index e5c974240..374505be1 100644 --- a/frontend/src/App/index.tsx +++ b/frontend/src/App/index.tsx @@ -4,7 +4,7 @@ import { Layout } from "@/constants"; import NavbarProvider from "@/contexts/Navbar"; import OnlineProvider from "@/contexts/Online"; import { notification } from "@/modules/task"; -import CriticalError from "@/pages/CriticalError"; +import CriticalError from "@/pages/errors/CriticalError"; import { RouterNames } from "@/Router/RouterNames"; import { Environment } from "@/utilities"; import { AppShell } from "@mantine/core"; diff --git a/frontend/src/Router/index.tsx b/frontend/src/Router/index.tsx index 3c3ab8a4a..5e90290c8 100644 --- a/frontend/src/Router/index.tsx +++ b/frontend/src/Router/index.tsx @@ -6,12 +6,12 @@ import Authentication from "@/pages/Authentication"; import BlacklistMoviesView from "@/pages/Blacklist/Movies"; import BlacklistSeriesView from "@/pages/Blacklist/Series"; import Episodes from "@/pages/Episodes"; +import NotFound from "@/pages/errors/NotFound"; import MoviesHistoryView from "@/pages/History/Movies"; import SeriesHistoryView from "@/pages/History/Series"; import MovieView from "@/pages/Movies"; import MovieDetailView from "@/pages/Movies/Details"; import MovieMassEditor from "@/pages/Movies/Editor"; -import NotFound from "@/pages/NotFound"; import SeriesView from "@/pages/Series"; import SeriesMassEditor from "@/pages/Series/Editor"; import SettingsGeneralView from "@/pages/Settings/General"; diff --git a/frontend/src/components/ErrorBoundary.tsx b/frontend/src/components/ErrorBoundary.tsx index b7b7494fb..9f6228e34 100644 --- a/frontend/src/components/ErrorBoundary.tsx +++ b/frontend/src/components/ErrorBoundary.tsx @@ -1,4 +1,4 @@ -import UIError from "@/pages/UIError"; +import UIError from "@/pages/errors/UIError"; import { Component } from "react"; interface State { diff --git a/frontend/src/modules/socketio/index.ts b/frontend/src/modules/socketio/index.ts index 18934b39a..fe9536bbc 100644 --- a/frontend/src/modules/socketio/index.ts +++ b/frontend/src/modules/socketio/index.ts @@ -1,7 +1,7 @@ import { debounce, forIn, remove, uniq } from "lodash"; import { onlineManager } from "react-query"; import { io, Socket } from "socket.io-client"; -import { Environment, isDevEnv } from "../../utilities"; +import { Environment, isDevEnv, isTestEnv } from "../../utilities"; import { ENSURE, GROUP, LOG } from "../../utilities/console"; import { createDefaultReducer } from "./reducer"; @@ -51,6 +51,10 @@ class SocketIOClient { } initialize() { + if (isTestEnv) { + return; + } + LOG("info", "Initializing Socket.IO client..."); this.reducers.push(...createDefaultReducer()); diff --git a/frontend/src/pages/Blacklist/blacklist.test.tsx b/frontend/src/pages/Blacklist/blacklist.test.tsx new file mode 100644 index 000000000..4360c473c --- /dev/null +++ b/frontend/src/pages/Blacklist/blacklist.test.tsx @@ -0,0 +1,16 @@ +import { renderTest, RenderTestCase } from "@/tests/render"; +import BlacklistMoviesView from "./Movies"; +import BlacklistSeriesView from "./Series"; + +const cases: RenderTestCase[] = [ + { + name: "movie page", + ui: BlacklistMoviesView, + }, + { + name: "series page", + ui: BlacklistSeriesView, + }, +]; + +renderTest("Blacklist", cases); diff --git a/frontend/src/pages/History/history.test.tsx b/frontend/src/pages/History/history.test.tsx new file mode 100644 index 000000000..1de1e6c5d --- /dev/null +++ b/frontend/src/pages/History/history.test.tsx @@ -0,0 +1,21 @@ +import { renderTest, RenderTestCase } from "@/tests/render"; +import MoviesHistoryView from "./Movies"; +import SeriesHistoryView from "./Series"; +import HistoryStats from "./Statistics"; + +const cases: RenderTestCase[] = [ + { + name: "movie page", + ui: MoviesHistoryView, + }, + { + name: "series page", + ui: SeriesHistoryView, + }, + { + name: "statistics page", + ui: HistoryStats, + }, +]; + +renderTest("History", cases); diff --git a/frontend/src/pages/Movies/movies.test.tsx b/frontend/src/pages/Movies/movies.test.tsx new file mode 100644 index 000000000..fe5691a15 --- /dev/null +++ b/frontend/src/pages/Movies/movies.test.tsx @@ -0,0 +1,16 @@ +import { render } from "@/tests"; +import { describe } from "vitest"; +import MovieView from "."; +import MovieMassEditor from "./Editor"; + +describe("Movies page", () => { + it("should render", () => { + render(); + }); +}); + +describe("Movies editor page", () => { + it("should render", () => { + render(); + }); +}); diff --git a/frontend/src/pages/Series/series.test.tsx b/frontend/src/pages/Series/series.test.tsx new file mode 100644 index 000000000..6813c6e19 --- /dev/null +++ b/frontend/src/pages/Series/series.test.tsx @@ -0,0 +1,16 @@ +import { render } from "@/tests"; +import { describe } from "vitest"; +import SeriesView from "."; +import SeriesMassEditor from "./Editor"; + +describe("Series page", () => { + it("should render", () => { + render(); + }); +}); + +describe("Series editor page", () => { + it("should render", () => { + render(); + }); +}); diff --git a/frontend/src/pages/Settings/settings.test.tsx b/frontend/src/pages/Settings/settings.test.tsx new file mode 100644 index 000000000..71aa74158 --- /dev/null +++ b/frontend/src/pages/Settings/settings.test.tsx @@ -0,0 +1,51 @@ +import { renderTest, RenderTestCase } from "@/tests/render"; +import SettingsGeneralView from "./General"; +import SettingsLanguagesView from "./Languages"; +import SettingsNotificationsView from "./Notifications"; +import SettingsProvidersView from "./Providers"; +import SettingsRadarrView from "./Radarr"; +import SettingsSchedulerView from "./Scheduler"; +import SettingsSonarrView from "./Sonarr"; +import SettingsSubtitlesView from "./Subtitles"; +import SettingsUIView from "./UI"; + +const cases: RenderTestCase[] = [ + { + name: "general page", + ui: SettingsGeneralView, + }, + { + name: "languages page", + ui: SettingsLanguagesView, + }, + { + name: "notifications page", + ui: SettingsNotificationsView, + }, + { + name: "providers page", + ui: SettingsProvidersView, + }, + { + name: "radarr page", + ui: SettingsRadarrView, + }, + { + name: "scheduler page", + ui: SettingsSchedulerView, + }, + { + name: "sonarr page", + ui: SettingsSonarrView, + }, + { + name: "subtitles page", + ui: SettingsSubtitlesView, + }, + { + name: "ui page", + ui: SettingsUIView, + }, +]; + +renderTest("Settings", cases); diff --git a/frontend/src/pages/System/system.test.tsx b/frontend/src/pages/System/system.test.tsx new file mode 100644 index 000000000..f9c0b5dad --- /dev/null +++ b/frontend/src/pages/System/system.test.tsx @@ -0,0 +1,36 @@ +import { renderTest, RenderTestCase } from "@/tests/render"; +import SystemBackupsView from "./Backups"; +import SystemLogsView from "./Logs"; +import SystemProvidersView from "./Providers"; +import SystemReleasesView from "./Releases"; +import SystemStatusView from "./Status"; +import SystemTasksView from "./Tasks"; + +const cases: RenderTestCase[] = [ + { + name: "backups page", + ui: SystemBackupsView, + }, + { + name: "logs page", + ui: SystemLogsView, + }, + { + name: "providers page", + ui: SystemProvidersView, + }, + { + name: "releases page", + ui: SystemReleasesView, + }, + { + name: "status page", + ui: SystemStatusView, + }, + { + name: "tasks page", + ui: SystemTasksView, + }, +]; + +renderTest("System", cases); diff --git a/frontend/src/pages/Wanted/wanted.test.tsx b/frontend/src/pages/Wanted/wanted.test.tsx new file mode 100644 index 000000000..36e72c4bb --- /dev/null +++ b/frontend/src/pages/Wanted/wanted.test.tsx @@ -0,0 +1,16 @@ +import { renderTest, RenderTestCase } from "@/tests/render"; +import WantedMoviesView from "./Movies"; +import WantedSeriesView from "./Series"; + +const cases: RenderTestCase[] = [ + { + name: "movie page", + ui: WantedMoviesView, + }, + { + name: "series page", + ui: WantedSeriesView, + }, +]; + +renderTest("Wanted", cases); diff --git a/frontend/src/pages/CriticalError.tsx b/frontend/src/pages/errors/CriticalError.tsx similarity index 100% rename from frontend/src/pages/CriticalError.tsx rename to frontend/src/pages/errors/CriticalError.tsx diff --git a/frontend/src/pages/NotFound.tsx b/frontend/src/pages/errors/NotFound.tsx similarity index 100% rename from frontend/src/pages/NotFound.tsx rename to frontend/src/pages/errors/NotFound.tsx diff --git a/frontend/src/pages/UIError.tsx b/frontend/src/pages/errors/UIError.tsx similarity index 100% rename from frontend/src/pages/UIError.tsx rename to frontend/src/pages/errors/UIError.tsx diff --git a/frontend/src/pages/errors/errors.test.tsx b/frontend/src/pages/errors/errors.test.tsx new file mode 100644 index 000000000..eeacfd631 --- /dev/null +++ b/frontend/src/pages/errors/errors.test.tsx @@ -0,0 +1,22 @@ +import { render } from "@/tests"; +import CriticalError from "./CriticalError"; +import NotFound from "./NotFound"; +import UIError from "./UIError"; + +describe("Not found page", () => { + it("should display message", () => { + render(); + }); +}); + +describe("Critical error page", () => { + it("should disable error", () => { + render(); + }); +}); + +describe("UI error page", () => { + it("should disable error", () => { + render(); + }); +}); diff --git a/frontend/src/tests/index.tsx b/frontend/src/tests/index.tsx index 8239af064..9053be909 100644 --- a/frontend/src/tests/index.tsx +++ b/frontend/src/tests/index.tsx @@ -1,11 +1,19 @@ import { AllProviders } from "@/providers"; import { render, RenderOptions } from "@testing-library/react"; -import { ReactElement } from "react"; +import { FunctionComponent, ReactElement, StrictMode } from "react"; + +const AllProvidersWithStrictMode: FunctionComponent = ({ children }) => { + return ( + + {children} + + ); +}; const customRender = ( ui: ReactElement, options?: Omit -) => render(ui, { wrapper: AllProviders, ...options }); +) => render(ui, { wrapper: AllProvidersWithStrictMode, ...options }); // re-export everything export * from "@testing-library/react"; diff --git a/frontend/src/tests/render.tsx b/frontend/src/tests/render.tsx new file mode 100644 index 000000000..e0031e903 --- /dev/null +++ b/frontend/src/tests/render.tsx @@ -0,0 +1,17 @@ +import { FunctionComponent } from "react"; +import { render } from "."; + +export interface RenderTestCase { + name: string; + ui: FunctionComponent; +} + +export function renderTest(name: string, cases: RenderTestCase[]) { + describe(name, () => { + cases.forEach((element) => { + it(`${element.name.toLowerCase()} should render`, () => { + render(); + }); + }); + }); +} diff --git a/frontend/test/setup.ts b/frontend/test/setup.ts index 858b64791..2b3bf3672 100644 --- a/frontend/test/setup.ts +++ b/frontend/test/setup.ts @@ -26,3 +26,5 @@ class ResizeObserver { } window.ResizeObserver = ResizeObserver; + +window.scrollTo = () => {};