diff --git a/__tests__/Answer.test.js b/__tests__/Answer.test.js
new file mode 100644
index 0000000..a9b79b6
--- /dev/null
+++ b/__tests__/Answer.test.js
@@ -0,0 +1,13 @@
+import React from "react";
+import { render } from "@testing-library/react";
+import Answer from "../components/Answer";
+import "@testing-library/jest-dom";
+
+describe("Answer component", () => {
+ it("should render the text correctly", () => {
+ const text = "This is the answer text";
+ const { getByText } = render();
+ const answerElement = getByText(text);
+ expect(answerElement).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/Footer.test.js b/__tests__/Footer.test.js
new file mode 100644
index 0000000..2fefc56
--- /dev/null
+++ b/__tests__/Footer.test.js
@@ -0,0 +1,14 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import Footer from "../components/Footer";
+import "@testing-library/jest-dom";
+
+describe("Footer Component", () => {
+ it("should render the footer text", () => {
+ render();
+ const footerText = screen.getByText((content, element) => {
+ return content.startsWith("Made with");
+ });
+ expect(footerText).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/Question.test.js b/__tests__/Question.test.js
new file mode 100644
index 0000000..3c184b5
--- /dev/null
+++ b/__tests__/Question.test.js
@@ -0,0 +1,13 @@
+import React from "react";
+import { render } from "@testing-library/react";
+import Question from "../components/Question";
+import "@testing-library/jest-dom";
+
+describe("Question component", () => {
+ it("should render the text correctly", () => {
+ const text = "This is the Question text";
+ const { getByText } = render();
+ const QuestionElement = getByText(text);
+ expect(QuestionElement).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/QueueSection.test.js b/__tests__/QueueSection.test.js
new file mode 100644
index 0000000..513135d
--- /dev/null
+++ b/__tests__/QueueSection.test.js
@@ -0,0 +1,39 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import QueueSection from "../components/QueueSection";
+
+describe("QueueSection Component", () => {
+ it("should render the current active job", () => {
+ const activeJob = "Active Job Title";
+ render();
+ const activeJobTitle = screen.getByText("Current active");
+ const activeJobDescription = screen.getByText(activeJob);
+ expect(activeJobTitle).toBeInTheDocument();
+ expect(activeJobDescription).toBeInTheDocument();
+ });
+
+ it("should render 'No active job' when no active job provided", () => {
+ render();
+ const activeJobTitle = screen.getByText("Current active");
+ const noActiveJobMessage = screen.getByText("No active job");
+ expect(activeJobTitle).toBeInTheDocument();
+ expect(noActiveJobMessage).toBeInTheDocument();
+ });
+
+ it("should render the next job", () => {
+ const nextJob = "Next Job Title";
+ render();
+ const nextJobTitle = screen.getByText("Next job");
+ const nextJobDescription = screen.getByText(nextJob);
+ expect(nextJobTitle).toBeInTheDocument();
+ expect(nextJobDescription).toBeInTheDocument();
+ });
+
+ it("should render 'No waiting job' when no next job provided", () => {
+ render();
+ const nextJobTitle = screen.getByText("Next job");
+ const noWaitingJobMessage = screen.getByText("No waiting job");
+ expect(nextJobTitle).toBeInTheDocument();
+ expect(noWaitingJobMessage).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/ShowQueue.test.js b/__tests__/ShowQueue.test.js
new file mode 100644
index 0000000..ac35f7e
--- /dev/null
+++ b/__tests__/ShowQueue.test.js
@@ -0,0 +1,35 @@
+import React from "react";
+import { render } from "@testing-library/react";
+import ShowQueue from "../components/ShowQueue";
+import "@testing-library/jest-dom";
+
+describe("ShowQueue Component", () => {
+ it("renders the component with library name and queue data", () => {
+ const data = {
+ waiting: 10,
+ active: 5,
+ completed: 20,
+ failed: 3,
+ delayed: 2,
+ };
+ const library = "Sample Library";
+
+ const { getByText } = render();
+ expect(getByText("Sample Library")).toBeInTheDocument();
+ expect(getByText("Waiting: 10")).toBeInTheDocument();
+ expect(getByText("Active: 5")).toBeInTheDocument();
+ expect(getByText("Completed: 20")).toBeInTheDocument();
+ expect(getByText("Failed: 3")).toBeInTheDocument();
+ expect(getByText("Delayed: 2")).toBeInTheDocument();
+ });
+
+ it("renders the component with no data", () => {
+ const { getByText } = render();
+ expect(getByText("No Data")).toBeInTheDocument();
+ expect(getByText("Waiting:")).toBeInTheDocument();
+ expect(getByText("Active:")).toBeInTheDocument();
+ expect(getByText("Completed:")).toBeInTheDocument();
+ expect(getByText("Failed:")).toBeInTheDocument();
+ expect(getByText("Delayed:")).toBeInTheDocument();
+ });
+});
diff --git a/__tests__/UploadedItems.test.js b/__tests__/UploadedItems.test.js
new file mode 100644
index 0000000..75c6565
--- /dev/null
+++ b/__tests__/UploadedItems.test.js
@@ -0,0 +1,28 @@
+import React from "react";
+import { render, waitFor } from "@testing-library/react";
+import "@testing-library/jest-dom";
+import UploadedItems from "../components/UploadedItems";
+
+global.fetch = jest.fn(() =>
+ Promise.resolve({
+ json: () =>
+ Promise.resolve({
+ response: {
+ numFound: 42,
+ },
+ }),
+ })
+);
+
+describe("UploadedItems Component", () => {
+ it("fetches and displays the number of books uploaded", async () => {
+ const { getByText } = render();
+
+ await waitFor(() => {
+ expect(fetch).toHaveBeenCalledTimes(1);
+ expect(
+ getByText("42 books uploaded to Internet Archive using BUB2!")
+ ).toBeInTheDocument();
+ });
+ });
+});
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..cd276eb
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,10 @@
+const nextJest = require("next/jest");
+const createJestConfig = nextJest({
+ dir: "./",
+});
+const customJestConfig = {
+ moduleDirectories: ["node_modules", "/"],
+ testEnvironment: "jest-environment-jsdom",
+ setupFilesAfterEnv: ["@testing-library/jest-dom"],
+};
+module.exports = createJestConfig(customJestConfig);
diff --git a/package.json b/package.json
index cb8f5ed..32f528a 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,8 @@
"scripts": {
"dev": "next dev",
"build": "next build;",
- "start": "npm run build; NODE_ENV=production node server.js"
+ "start": "npm run build; NODE_ENV=production node server.js",
+ "test": "jest --watch"
},
"husky": {
"hooks": {
@@ -73,9 +74,14 @@
"winston": "^3.9.0"
},
"devDependencies": {
+ "@testing-library/jest-dom": "^6.1.3",
+ "@testing-library/react": "^12.1.5",
+ "@testing-library/user-event": "^14.5.1",
"@wikimedia/codex": "^0.13.0",
"@wikimedia/codex-design-tokens": "^0.13.0",
"husky": "^4.2.3",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
"lint-staged": "^10.0.9",
"prettier": "2.0.2"
}