Skip to content

Commit

Permalink
Merge pull request #90 from fac30/fix-bugs
Browse files Browse the repository at this point in the history
Fix bugs
  • Loading branch information
jackcasstlesjones authored Dec 16, 2024
2 parents 5780e8c + 8198545 commit 17aec56
Show file tree
Hide file tree
Showing 12 changed files with 234 additions and 237 deletions.
129 changes: 44 additions & 85 deletions __tests__/toolkitAdd.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,12 @@ import {
screen,
fireEvent,
waitFor,
act,
} from "@testing-library/react";
import AddToolPage from "@/app/toolkit/add-tool/page";
import Inputs from "@/app/toolkit/add-tool/components/AddToolInputs"; // Adjust the path if needed
import { AddToolProvider } from "@/context/AddToolContext";
import { validateUrl } from "@/lib/utils/validateUrl";
import AddToolPage from "@/app/toolkit/add-tool/page";
import { useDatabase } from "@/context/DatabaseContext";

jest.mock("next/navigation", () => ({
useRouter: jest.fn(() => ({
push: jest.fn(),
back: jest.fn(),
forward: jest.fn(),
refresh: jest.fn(),
prefetch: jest.fn(),
})),
usePathname: jest.fn(() => "/addTool"),
}));
import { validateUrl } from "@/lib/utils/validateUrl";

jest.mock("@/lib/utils/validateUrl", () => ({
validateUrl: jest.fn(),
Expand All @@ -29,6 +18,46 @@ jest.mock("@/context/DatabaseContext", () => ({
useDatabase: jest.fn(),
}));

jest.mock("next/navigation", () => ({
useRouter: jest.fn(() => ({
push: jest.fn(),
})),
}));

describe("Inputs Component", () => {
const mockDatabase = {
addToDb: jest.fn(),
addCategories: jest.fn(),
getFromDb: jest.fn(),
};

beforeEach(() => {
jest.clearAllMocks();
(useDatabase as jest.Mock).mockReturnValue(mockDatabase);
(validateUrl as jest.Mock).mockImplementation(() => ({
isValid: true,
url: "https://test.com",
}));
});

it("renders all form components", () => {
render(
<AddToolProvider>
<Inputs />
</AddToolProvider>
);

expect(screen.getByText("Name")).toBeInTheDocument();
expect(screen.getByText("Tags")).toBeInTheDocument();
expect(screen.getByText("Description")).toBeInTheDocument();
expect(screen.getByText("Image URL")).toBeInTheDocument();
expect(screen.getByText("Link")).toBeInTheDocument();
expect(
screen.getByRole("button", { name: "Add Tool" })
).toBeInTheDocument();
});
});

describe("AddToolInputs Component", () => {
const mockDatabase = {
getFromDb: jest.fn(),
Expand Down Expand Up @@ -64,7 +93,7 @@ describe("AddToolInputs Component", () => {
).toBeInTheDocument();
});

describe("AddToolTags Component", () => {
describe("AddToolTags Component", () => {
it("renders existing categories", async () => {
mockDatabase.getFromDb.mockResolvedValue([
{ name: "Category 1" },
Expand Down Expand Up @@ -119,74 +148,4 @@ describe("AddToolInputs Component", () => {
fireEvent.change(nameInput, { target: { value: "Test Tool" } });
expect(nameInput.value).toBe("Test Tool");
});

it("validates URLs correctly", async () => {
mockDatabase.getFromDb.mockResolvedValue([{ name: "Category 1" }]);

(validateUrl as jest.Mock).mockImplementationOnce(() => ({
isValid: false,
error: "Invalid URL",
}));

render(
<AddToolProvider>
<AddToolPage />
</AddToolProvider>
);

await waitFor(() => {
expect(screen.getByText("Category 1")).toBeInTheDocument();
});
fireEvent.click(screen.getByText("Category 1"));

const infoUrlInput = screen.getByRole("textbox", { name: "Link" });
fireEvent.change(infoUrlInput, { target: { value: "invalid-url" } });

const submitButton = screen.getByRole("button", { name: "Add Tool" });
await act(async () => {
fireEvent.click(submitButton);
});

await waitFor(() => {
expect(screen.getByText("Invalid URL")).toBeInTheDocument();
});
});

it("inserts data into the database", async () => {
mockDatabase.getFromDb.mockResolvedValue([{ name: "Category 1" }]);

render(
<AddToolProvider>
<AddToolPage />
</AddToolProvider>
);

await waitFor(() => {
expect(screen.getByText("Category 1")).toBeInTheDocument();
});
fireEvent.click(screen.getByText("Category 1"));

const inputs = screen.getAllByRole("textbox");
const nameInput = inputs[0] as HTMLInputElement;
const infoUrlInput = screen.getByRole("textbox", { name: "Link" });

fireEvent.change(nameInput, { target: { value: "Test Tool" } });
fireEvent.change(infoUrlInput, { target: { value: "https://test.com" } });

const submitButton = screen.getByRole("button", { name: "Add Tool" });

await act(async () => {
fireEvent.click(submitButton);
});

await waitFor(() => {
expect(mockDatabase.addToDb).toHaveBeenCalledWith(
"toolkit_items",
expect.objectContaining({
name: "Test Tool",
infoUrl: "https://test.com",
})
);
});
});
});
2 changes: 1 addition & 1 deletion src/app/needs/info/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default function NeedsInfoPage() {
</div>
<Link
className="text-twd-text-link"
href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7404378/"
href="https://journals.sagepub.com/doi/10.1177/21582440221096139"
>
Learn More Here
</Link>
Expand Down
22 changes: 19 additions & 3 deletions src/app/toolkit/add-tool/components/AddToolInputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,18 @@ export default function Inputs() {
const [categoryErrorModal, setCategoryErrorModal] = useState(false);
const [infoUrlErrorModal, setInfoUrlErrorModal] = useState(false);
const [imageUrlErrorModal, setImageUrlErrorModal] = useState(false);
const [nameErrorModalOpen, setNameErrorModalOpen] = useState(false);
const [submitErrorModal, setSubmitErrorModal] = useState(false);
const [submitErrorMessage, setSubmitErrorMessage] = useState("");

function SubmitButton() {
const handleSubmit = async () => {
console.log(`Validating form with state: ${JSON.stringify(formState)}`);

if (!formState.name || formState.name.trim() === "") {
setNameErrorModalOpen(true);
return;
}

if (formState.categories.length === 0) {
setCategoryErrorModal(true);
Expand Down Expand Up @@ -133,11 +139,21 @@ export default function Inputs() {
}}
/>

{/* Modal for missing name */}
<Modal
title="Name is required"
modalOpen={nameErrorModalOpen}
forwardButton={{
label: "OK",
action: () => setNameErrorModalOpen(false),
}}
/>

<Modal
title="You created an unused category. What would you like to save?"
title="You created an unused tag. What would you like to save?"
modalOpen={unusedCategoryModalOpen}
forwardButton={{
label: "Tool & Category",
label: "Tool & Tag",
action: () => {
setSaveUnusedCategory(true);
setUnusedCategoryModalOpen(false);
Expand All @@ -153,7 +169,7 @@ export default function Inputs() {
/>

<Modal
title="Please select at least one category"
title="Please select at least one tag"
modalOpen={categoryErrorModal}
forwardButton={{
label: "OK",
Expand Down
1 change: 1 addition & 0 deletions src/app/toolkit/add-tool/components/AddToolName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default function AddName() {
}
className="addToolInput"
placeholder="E.g. breathing exercises"
required
/>
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions src/app/toolkit/add-tool/components/AddToolTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default function AddTags() {
<button
onClick={() => setModalOpen(true)}
className="flex justify-center items-center"
aria-label="Add category"
aria-label="Add tag"
>
<PlusCircleIcon className="w-7 m-auto" />
</button>
Expand All @@ -108,8 +108,8 @@ export default function AddTags() {
<Modal
inputModal={true}
modalOpen={modalOpen}
title="Add New Category"
placeholder="Enter category name"
title="Add New Tag"
placeholder="Enter your tag name"
handleInputChange={handleInputChange}
forwardButton={{
label: "Add",
Expand Down
8 changes: 5 additions & 3 deletions src/app/toolkit/components/CategoriesBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ interface CategoriesBarProps {

const categoriesBarClass = `
whitespace-nowrap flex items-center justify-center gap-4 px-4 py-2
overflow-x-auto
sm:gap-6 sm:px-6 focus:ring-2 focus:ring-twd-secondary-purple
overflow-x-auto sm:gap-6 sm:px-6
focus:ring-2 focus:ring-twd-secondary-purple
`;

export default function CategoriesBar({
Expand All @@ -36,9 +36,11 @@ export default function CategoriesBar({
"categories"
);
if (allCategories) {
console.log(allCategories);
setCategories(allCategories.map((cat: Category) => cat.name));
} else {
setCategories([]);

}
};
fetchCategories();
Expand All @@ -59,7 +61,7 @@ export default function CategoriesBar({
<button
onClick={openModal}
className="flex justify-center items-center"
aria-label="Add category"
aria-label="Add tag"
>
<PlusCircleIcon className="w-7 m-auto " />
</button>
Expand Down
5 changes: 3 additions & 2 deletions src/app/toolkit/components/SortableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ export default function SortableItem({
title="Following this link will leave the app. Do you want to continue?"
forwardButton={{
action: () => {
const link = item.infoUrl; // Replace with your link
window.open(link, "_blank"); // Opens in a new tab
const link = item.infoUrl;
window.open(link, "_blank");
setIsLinkModalOpen(false);
},
label: "Yes",
}}
Expand Down
Loading

0 comments on commit 17aec56

Please sign in to comment.