diff --git a/__tests__/__mocks__/mockRegistry.tsx b/__tests__/__mocks__/mockRegistry.tsx index ac1ec53a..e4bdb36a 100644 --- a/__tests__/__mocks__/mockRegistry.tsx +++ b/__tests__/__mocks__/mockRegistry.tsx @@ -17,9 +17,15 @@ import extendedMocks from "./extendedMocks"; */ export const MockRegistrationLink = ({ className }: { className?: string }) => { return ( -
- Registration Link -
+ + Register Here! + ); }; diff --git a/__tests__/components/about-us.test.tsx b/__tests__/components/about-us.test.tsx index 3435fbfa..6a2779dd 100644 --- a/__tests__/components/about-us.test.tsx +++ b/__tests__/components/about-us.test.tsx @@ -22,17 +22,6 @@ jest.mock("next/navigation", () => ({ usePathname: () => "/", })); -jest.mock("@/components/themed-components/registration-link", () => { - return { - __esModule: true, - default: ({ children, className }: { children?: React.ReactNode; className?: string }) => ( -
- {children || "Registration Link"} -
- ), - }; -}); - // Define the current theme and year for better test maintainability const CURRENT_THEME = "Retro vs. Modern"; const HACKRPI_YEAR = getCurrentHackrpiYear(); @@ -109,22 +98,16 @@ describe("AboutUs Component", () => { expect(parentContainer).toContainElement(venueElement); }); - it("renders the registration link with correct styling", () => { - // 2025 best practice: Render the component and get the container + it("renders the registration banner with correct styling", () => { const { container } = renderWithProviders(); - // 2025 best practice: Use data-testid for more reliable selection - const registrationLink = screen.getByTestId("registration-link"); - expect(registrationLink).toBeInTheDocument(); - expect(registrationLink).toHaveClass("text-xl"); - - // 2025 best practice: Find the REGISTER NOW text using a pattern - const registerNowText = screen.getByText(/REGISTER NOW!/i); - expect(registerNowText).toBeInTheDocument(); + const registerBanner = screen.getByTestId("register-now-banner"); + expect(registerBanner).toBeInTheDocument(); + expect(registerBanner).toHaveTextContent(/REGISTER NOW!/i); + expect(registerBanner).toHaveClass("bg-hackrpi-secondary-orange"); + expect(registerBanner).toHaveClass("text-white"); - // Verify they are both in the document but don't assert they're in the same container - expect(container).toContainElement(registrationLink); - expect(container).toContainElement(registerNowText); + expect(container).toContainElement(registerBanner); }); it('renders the scrolling "REGISTER NOW!" text with correct styling', () => { @@ -137,7 +120,7 @@ describe("AboutUs Component", () => { // Check styling directly on the element with data-testid expect(registerBanner).toHaveClass("bg-hackrpi-secondary-orange"); - expect(registerBanner).toHaveClass("text-black"); + expect(registerBanner).toHaveClass("text-white"); expect(registerBanner).toHaveClass("overflow-hidden"); expect(registerBanner).toHaveClass("whitespace-nowrap"); }); @@ -164,11 +147,8 @@ describe("AboutUs Component", () => { const { container } = renderWithProviders(); // 2025 best practice: Test for basic accessibility patterns - const links = screen.getAllByRole("link"); - expect(links.length).toBeGreaterThan(0); - links.forEach((link) => { - expect(link).toHaveAccessibleName(); - }); + const links = screen.queryAllByRole("link"); + expect(links.length).toBe(0); const headings = screen.getAllByRole("heading"); expect(headings.length).toBeGreaterThan(1); @@ -187,7 +167,7 @@ describe("AboutUs Component", () => { // Check that key elements are still visible on mobile expect(screen.getByRole("heading", { name: /About HackRPI/i })).toBeInTheDocument(); - expect(screen.getByTestId("registration-link")).toBeInTheDocument(); + expect(screen.getByTestId("register-now-banner")).toBeInTheDocument(); // Clean up mobile test and set up desktop test cleanup(); @@ -197,7 +177,7 @@ describe("AboutUs Component", () => { // Verify desktop layout elements expect(screen.getByRole("heading", { name: /About HackRPI/i })).toBeInTheDocument(); - expect(screen.getByTestId("registration-link")).toBeInTheDocument(); + expect(screen.getByTestId("register-now-banner")).toBeInTheDocument(); }); // 2025 Best Practice: Add automated accessibility testing diff --git a/__tests__/components/event.test.tsx b/__tests__/components/event.test.tsx index 8ee6eac8..676a5e1e 100644 --- a/__tests__/components/event.test.tsx +++ b/__tests__/components/event.test.tsx @@ -61,7 +61,7 @@ jest.mock("next/image", () => ({ })); // Import the component after all mocks are defined -import EventPage from "@/app/event/page"; +import EventPage from "@/app/(with-layout)/event/page"; describe("Event Page", () => { beforeEach(() => { @@ -71,11 +71,9 @@ describe("Event Page", () => { it("renders the main layout components", () => { render(); - // Check if the navbar component is rendered - expect(screen.getByTestId("nav-bar")).toBeInTheDocument(); - - // Note: Footer is imported but not actually used in the component - // so we should not expect it in the test + // Verify key structural headings render + expect(screen.getByText("Location:")).toBeInTheDocument(); + expect(screen.getByText("Need Help?")).toBeInTheDocument(); }); it("renders the map component", () => { diff --git a/__tests__/components/faq.test.tsx b/__tests__/components/faq.test.tsx index 363d8d42..265521d3 100644 --- a/__tests__/components/faq.test.tsx +++ b/__tests__/components/faq.test.tsx @@ -8,10 +8,16 @@ import "@testing-library/jest-dom"; jest.mock("@/components/themed-components/registration-link", () => { return { __esModule: true, - default: ({ children, className }: { children?: React.ReactNode; className?: string }) => ( -
- {children || "Registration Link"} -
+ default: ({ className }: { className?: string }) => ( + + Register Here! + ), }; }); @@ -95,8 +101,9 @@ describe("FAQ Component", () => { fireEvent.click(registrationFAQ); // Check if the registration link is rendered - const registrationLink = screen.getByTestId("registration-link"); + const registrationLink = screen.getByRole("link", { name: /register here!/i }); expect(registrationLink).toBeInTheDocument(); + expect(registrationLink).toHaveAttribute("href", "https://hackrpi2025.devpost.com/"); }); it("renders the contact information at the bottom", () => { diff --git a/__tests__/components/footer.test.tsx b/__tests__/components/footer.test.tsx index e67b17e9..ba90fa48 100644 --- a/__tests__/components/footer.test.tsx +++ b/__tests__/components/footer.test.tsx @@ -11,8 +11,8 @@ jest.mock("next/image", () => ({ })); // Mock logo import -jest.mock("@/public/HackRPI_Logo_Yellow_Arrow.png", () => ({ - default: "mock-logo-path", +jest.mock("@/public/Retro_HackRPI_Logo.png", () => ({ + default: "mock-retro-logo", })); jest.mock("@/components/socials-links/social-links", () => { @@ -24,9 +24,15 @@ jest.mock("@/components/socials-links/social-links", () => { jest.mock("@/components/themed-components/registration-link", () => { return function MockRegistrationLink({ className }: { className?: string }) { return ( -
- Registration Link -
+ + Register Here! + ); }; }); @@ -72,6 +78,7 @@ describe("Footer Component", () => { expect(registrationLink).toBeInTheDocument(); expect(registrationLink).toHaveClass("text-xl"); expect(registrationLink).toHaveClass("mb-4"); + expect(registrationLink).toHaveAttribute("href", "https://hackrpi2025.devpost.com/"); }); it("renders the social links", () => { diff --git a/__tests__/components/last-year.test.tsx b/__tests__/components/last-year.test.tsx index 569afff6..e3ee2147 100644 --- a/__tests__/components/last-year.test.tsx +++ b/__tests__/components/last-year.test.tsx @@ -80,6 +80,23 @@ jest.mock("@/components/themed-components/hackrpi-link", () => { }; }); +jest.mock("@/components/prev-projects/LastYearCollage", () => { + return function MockLastYearCollage() { + return ( +
+ {Array.from({ length: 12 }).map((_, index) => ( + {`HackRPI + ))} +
+ ); + }; +}); + jest.mock("next/image", () => ({ __esModule: true, default: (props: any) => { @@ -88,7 +105,7 @@ jest.mock("next/image", () => ({ })); // Import the component after all mocks are defined -import PastYearProjects from "@/app/last-year/page"; +import PastYearProjects from "@/app/(with-layout)/last-year/page"; describe("Last Year Projects Page", () => { beforeEach(() => { diff --git a/__tests__/components/nav-bar.test.tsx b/__tests__/components/nav-bar.test.tsx index b5f06df4..22714ff1 100644 --- a/__tests__/components/nav-bar.test.tsx +++ b/__tests__/components/nav-bar.test.tsx @@ -1,6 +1,6 @@ import React from "react"; import { render, screen, cleanup } from "@testing-library/react"; -import NavBar from "@/components/nav-bar/nav-bar"; +import NavBar, { links as navLinks } from "@/components/nav-bar/nav-bar"; import { renderWithProviders, resetAllMocks, setWindowDimensions } from "../test-utils"; /** @@ -42,29 +42,6 @@ jest.mock("@/data/nav-bar-links", () => { }; }); -// Mock the links directly in the NavBar component -jest.mock("@/components/nav-bar/nav-bar", () => { - const originalModule = jest.requireActual("@/components/nav-bar/nav-bar"); - return { - __esModule: true, - ...originalModule, - links: [ - { - name: "Home", - links: [ - { href: "/", children: "Home" }, - { href: "/#about", children: "About" }, - ], - }, - { - name: "HackRPI XI", - links: [{ href: "/last-year#winners", children: "Winners" }], - }, - ], - default: originalModule.default, - }; -}); - // Mock MLH Banner jest.mock("@/components/mlh-banner/mlh-banner", () => { return function MockMlhBanner() { @@ -134,9 +111,10 @@ describe("NavBar Component", () => { // Act - Render the component renderWithProviders(); - // Assert - Check if links are passed correctly - we expect 2 links based on our mock + // Assert - Check if links are passed correctly based on the exported navigation data const mobileNav = screen.getByTestId("nav-bar-mobile"); - expect(mobileNav.textContent).toContain("2 links"); + const expectedCount = navLinks.length; + expect(mobileNav.textContent).toContain(`${expectedCount} links`); // Clean up before rendering again cleanup(); @@ -146,7 +124,7 @@ describe("NavBar Component", () => { renderWithProviders(); const desktopNav = screen.getByTestId("nav-bar-desktop"); - expect(desktopNav.textContent).toContain("2 links"); + expect(desktopNav.textContent).toContain(`${expectedCount} links`); }); it("should handle showOnScroll prop correctly", async () => { diff --git a/__tests__/components/nav-bar/desktop/nav-bar-desktop.test.tsx b/__tests__/components/nav-bar/desktop/nav-bar-desktop.test.tsx index e4bd3afd..ccafcd18 100644 --- a/__tests__/components/nav-bar/desktop/nav-bar-desktop.test.tsx +++ b/__tests__/components/nav-bar/desktop/nav-bar-desktop.test.tsx @@ -2,7 +2,7 @@ import { render, screen } from "@testing-library/react"; import "@testing-library/jest-dom"; // Mock the image imports -jest.mock("@/public/HackRPI_Logo_Yellow_Arrow.png", () => "logo-image-stub"); +jest.mock("@/public/Retro_HackRPI_Logo.png", () => "logo-image-stub"); jest.mock("next/image", () => ({ __esModule: true, default: (props: any) => { @@ -12,11 +12,6 @@ jest.mock("next/image", () => ({ })); // Mock the registration button -jest.mock("@/components/themed-components/registration-link", () => ({ - __esModule: true, - default: () =>
Register Now
, -})); - // Mock NavGroupComponent jest.mock("@/components/nav-bar/desktop/nav-group", () => ({ __esModule: true, @@ -70,19 +65,15 @@ describe("DesktopNavBar Component", () => { // Check direct links expect(screen.getByText("Sponsor Us")).toBeInTheDocument(); - expect(screen.getByText("Event Info")).toBeInTheDocument(); - expect(screen.getByText("Schedule")).toBeInTheDocument(); - expect(screen.getByText("Announcements")).toBeInTheDocument(); - expect(screen.getByText("Prizes")).toBeInTheDocument(); - expect(screen.getByText("2048 Leaderboard")).toBeInTheDocument(); expect(screen.getByText("Code of Conduct")).toBeInTheDocument(); }); - it("includes registration button", () => { + it("includes registration link", () => { render(); - // Check for the registration button - expect(screen.getByTestId("registration-button")).toBeInTheDocument(); + const registerLink = screen.getByRole("link", { name: /register/i }); + expect(registerLink).toHaveAttribute("href", "https://hackrpi2024.devpost.com/project-gallery"); + expect(registerLink).toHaveAttribute("target", "_blank"); }); it("applies correct styling to the navbar", () => { diff --git a/__tests__/components/resources.test.tsx b/__tests__/components/resources.test.tsx index 0519ef14..6c0ae65b 100644 --- a/__tests__/components/resources.test.tsx +++ b/__tests__/components/resources.test.tsx @@ -46,7 +46,7 @@ jest.mock("next/image", () => ({ })); // Import the component after all mocks are defined -import ResourcesPage from "@/app/resources/page"; +import ResourcesPage from "@/app/(with-layout)/resources/page"; describe("Resources Page", () => { beforeEach(() => { @@ -56,9 +56,9 @@ describe("Resources Page", () => { it("renders the main layout components", () => { render(); - // Check if the main structural components are rendered - expect(screen.getByTestId("nav-bar")).toBeInTheDocument(); - // Footer is imported but not actually used in the component + // Verify primary headings render + expect(screen.getByText("Web Development")).toBeInTheDocument(); + expect(screen.getByText("Submitting Your Project")).toBeInTheDocument(); }); it("renders all resource section headings", () => { diff --git a/__tests__/components/schedule.test.tsx b/__tests__/components/schedule.test.tsx index ddfa4281..0a22f34b 100644 --- a/__tests__/components/schedule.test.tsx +++ b/__tests__/components/schedule.test.tsx @@ -23,6 +23,7 @@ describe("Schedule Component", () => { endHour: number, eventType: string = "default", visible: boolean = true, + column: number = 1, ): Event => ({ id, title: `Event ${id}`, @@ -33,7 +34,8 @@ describe("Schedule Component", () => { speaker: startHour % 2 === 0 ? `Speaker ${id}` : "", // Alternate between having a speaker and not eventType, visible, - column: 0, + column, + width: 1, }); // Sample data for testing @@ -250,10 +252,10 @@ describe("Schedule Component", () => { it("renders multiple columns for overlapping events", () => { // Create events that overlap - const overlappingEvents = [ - createEvent("1", 10, 12, "default"), // 10:00 AM - 12:00 PM - createEvent("2", 11, 13, "workshop"), // 11:00 AM - 1:00 PM - overlaps with event 1 - ]; + const overlappingEvents = [ + createEvent("1", 10, 12, "default", true, 1), // 10:00 AM - 12:00 PM + createEvent("2", 11, 13, "workshop", true, 2), // 11:00 AM - 1:00 PM - overlaps with event 1 + ]; render( + Footer Component + + ); +} + // 2025 Best Practice: More organized setup with clear purpose const mockHandleFAQClick = jest.fn(); const mockHandleAboutClick = jest.fn(); @@ -125,7 +133,7 @@ jest.mock("@/components/sponsors", () => { // Use centralized mock registry for Footer jest.mock("@/components/footer/footer", () => ({ __esModule: true, - default: MockFooter, + default: MockFooterComponent, })); jest.mock("@/components/faq/faq", () => { diff --git a/__tests__/integration/page-navigation.test.tsx b/__tests__/integration/page-navigation.test.tsx index 87bdda9f..a8bcc4ce 100644 --- a/__tests__/integration/page-navigation.test.tsx +++ b/__tests__/integration/page-navigation.test.tsx @@ -6,10 +6,10 @@ import { render, screen, within, act } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; // Import the components -import Home from "@/app/page"; -import EventPage from "@/app/event/page"; -import ResourcesPage from "@/app/resources/page"; -import PastYearProjects from "@/app/last-year/page"; +import Home from "@/app/(without-layout)/page"; +import EventPage from "@/app/(with-layout)/event/page"; +import ResourcesPage from "@/app/(with-layout)/resources/page"; +import PastYearProjects from "@/app/(with-layout)/last-year/page"; // Mock CSS import jest.mock("@/app/globals.css", () => ({}), { virtual: true }); @@ -111,7 +111,7 @@ jest.mock("@/components/nav-bar/nav-bar", () => { }); // Mock the pages to avoid DOM element access issues -jest.mock("@/app/page", () => { +jest.mock("@/app/(without-layout)/page", () => { return () => (