Skip to content

Commit

Permalink
Merge pull request #129 from UoaWDCC/feat/Sponsors-Page
Browse files Browse the repository at this point in the history
Feat/Sponsors-Page
  • Loading branch information
gmat224 authored Jul 6, 2024
2 parents 652b23b + c6931c8 commit 32b7308
Show file tree
Hide file tree
Showing 7 changed files with 480 additions and 1 deletion.
3 changes: 2 additions & 1 deletion web/__test__/components/ExecCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { describe, expect, it } from "vitest";
import { render, screen } from "@testing-library/react";
import ExecCard from "../../src/components/ExecCard";
import React from "react";
import { Exec } from "../../src/types/types";

const mockExec = {
const mockExec: Exec = {
id: 1,
image: "/uploads/john_doe.jpg",
position: "President",
Expand Down
45 changes: 45 additions & 0 deletions web/__test__/components/PartnerCard.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { describe, expect, it, vi } from "vitest";
import { fireEvent, render, screen } from "@testing-library/react";
import PartnerCard from "../../src/components/PartnerCard";
import React from "react";
import { Partner } from "../../src/types/types";

const mockPartner: Partner = {
id: 1,
type: "Gold",
name: "The Kebab and Chicken House",
location: "17 Mount Street",
description: "20% off Everything",
image: "/uploads/kebab.jpg",
};

describe("PartnerCard", () => {
it("renders PartnerCard with correct data", () => {
render(<PartnerCard partner={mockPartner} colour="#F3CF0B" />);

// Check if the elements are rendered correctly
expect(screen.getByAltText("Partner Image")).toBeInTheDocument();
const partnerImage = screen.getByAltText("Partner Image");
expect(partnerImage).toHaveAttribute("src", mockPartner.image);
expect(screen.getByText("The Kebab and Chicken House")).toBeInTheDocument();
expect(screen.getByText("17 Mount Street")).toBeInTheDocument();
expect(screen.getByText("20% off Everything")).toBeInTheDocument();
});

it("opens Google Maps with the correct query when 'View' button is clicked", () => {
render(<PartnerCard partner={mockPartner} colour="#F3CF0B" />);

const originalOpen = window.open;
window.open = vi.fn();

const viewButton = screen.getByText("View On Map");
fireEvent.click(viewButton);

expect(window.open).toHaveBeenCalledWith(
"https://www.google.com/maps/search/?api=1&query=17%20Mount%20Street",
"_blank"
);

window.open = originalOpen; // Restore original window.open
});
});
222 changes: 222 additions & 0 deletions web/__test__/screens/PartnerScreen.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
import { MockedProvider } from "@apollo/client/testing";
import { GET_PARTNERS } from "../../src/graphql/queries";
import { describe, expect, it } from "vitest";
import { render, screen } from "@testing-library/react";
import PartnersScreen from "../../src/screens/PartnersScreen";
import React from "react";
import { GraphQLError } from "graphql";
import "@testing-library/jest-dom";
import { MemoryRouter } from "react-router";

const partnersMock = {
request: {
query: GET_PARTNERS,
},
result: {
data: {
partners: {
data: [
{
id: 1,
attributes: {
Type: "Gold",
Name: "The Kebab and Chicken House",
Location: "17 Mount Street",
Description: "20% off Everything",
Image: {
data: {
attributes: {
url: "/uploads/kebab.jpg",
},
},
},
},
},
{
id: 2,
attributes: {
Type: "Silver",
Name: "Subi's Desserts",
Location: "128 White Swan Road, Mount Roskil",
Description: "15% off Everything",
Image: {
data: {
attributes: {
url: "/uploads/subi.jpg",
},
},
},
},
},
{
id: 3,
attributes: {
Type: "Bronze",
Name: "Beso Cafe and Kitchen",
Location: "256 Manukau Road, Epsom, Auckland",
Description: "10% off Everything",
Image: {
data: {
attributes: {
url: "/uploads/beso.jpg",
},
},
},
},
},
],
},
},
},
};

const noPartnersMock = {
request: {
query: GET_PARTNERS,
},
result: {
data: {
partners: {
data: [],
},
},
},
};

const mocks = [partnersMock];
const noDataMocks = [noPartnersMock];

describe("PartnersScreen", () => {
it("renders loading spinner initially", () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<MemoryRouter>
<PartnersScreen />
</MemoryRouter>
</MockedProvider>
);

expect(screen.getByTestId("loading-spinner")).toBeInTheDocument();
});

it("renders error message when query fails", async () => {
const errorMocks = [
{
request: {
query: GET_PARTNERS,
},
error: new GraphQLError("Error!"),
},
];

render(
<MockedProvider mocks={errorMocks} addTypename={false}>
<MemoryRouter>
<PartnersScreen />
</MemoryRouter>
</MockedProvider>
);

expect(await screen.findByText("CMS Offline")).toBeInTheDocument();
});

it("renders current gold partners correctly", async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<MemoryRouter>
<PartnersScreen />
</MemoryRouter>
</MockedProvider>
);

expect(
await screen.findByText("The Kebab and Chicken House")
).toBeInTheDocument();
expect(await screen.findByText("17 Mount Street")).toBeInTheDocument();
expect(await screen.findByText("20% off Everything")).toBeInTheDocument();

// Find the image element with alt text "Partner Image" and specific src
const goldPartnerImages = screen.getAllByAltText(
"Partner Image"
) as HTMLImageElement[];
const goldPartnerImage = goldPartnerImages.find((img) =>
img.src.includes("/uploads/kebab.jpg")
);

expect(goldPartnerImage).toBeInTheDocument();
});

it("renders current silver partners correctly", async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<MemoryRouter>
<PartnersScreen />
</MemoryRouter>
</MockedProvider>
);

expect(await screen.findByText("Subi's Desserts")).toBeInTheDocument();
expect(
await screen.findByText("128 White Swan Road, Mount Roskil")
).toBeInTheDocument();
expect(await screen.findByText("15% off Everything")).toBeInTheDocument();

// Find the image element with alt text "Partner Image" and specific src
const silverPartnerImages = screen.getAllByAltText(
"Partner Image"
) as HTMLImageElement[];
const silverPartnerImage = silverPartnerImages.find((img) =>
img.src.includes("/uploads/subi.jpg")
);

expect(silverPartnerImage).toBeInTheDocument();
});

it("renders current bronze partners correctly", async () => {
render(
<MockedProvider mocks={mocks} addTypename={false}>
<MemoryRouter>
<PartnersScreen />
</MemoryRouter>
</MockedProvider>
);

expect(
await screen.findByText("Beso Cafe and Kitchen")
).toBeInTheDocument();
expect(
await screen.findByText("256 Manukau Road, Epsom, Auckland")
).toBeInTheDocument();
expect(await screen.findByText("10% off Everything")).toBeInTheDocument();

// Find the image element with alt text "Partner Image" and specific src
const bronzePartnerImages = screen.getAllByAltText(
"Partner Image"
) as HTMLImageElement[];
const bronzePartnerImage = bronzePartnerImages.find((img) =>
img.src.includes("/uploads/beso.jpg")
);

expect(bronzePartnerImage).toBeInTheDocument();
});

it("renders no data from cms", async () => {
render(
<MockedProvider mocks={noDataMocks} addTypename={false}>
<MemoryRouter>
<PartnersScreen />
</MemoryRouter>
</MockedProvider>
);

expect(
await screen.findByText("No gold partners to display")
).toBeInTheDocument();
expect(
await screen.findByText("No silver partners to display")
).toBeInTheDocument();
expect(
await screen.findByText("No bronze partners to display")
).toBeInTheDocument();
});
});
58 changes: 58 additions & 0 deletions web/src/components/PartnerCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { PartnerCardProps } from "../types/types";

export default function PartnerCard({ partner, colour }: PartnerCardProps) {
// Function to convert hex to RGBA
const hexToRgba = (hex: string, alpha: number) => {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);

return `rgba(${r}, ${g}, ${b}, ${alpha})`;
};

const bgColorWithOpacity = hexToRgba(colour, 0.2); // 0.2 for 20% opacity

// Function to handle the button click
const handleViewOnMapClick = () => {
const googleMapsUrl = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(partner.location)}`;
window.open(googleMapsUrl, "_blank");
};

return (
<>
<div
className="flex h-auto w-72 flex-col items-center overflow-hidden rounded-2xl border-4 p-5"
style={{ borderColor: colour, backgroundColor: bgColorWithOpacity }}
>
<div className="h-auto w-full">
<img
src={partner.image}
alt="Partner Image"
className="rounded-2xl"
/>
</div>

<h1 className="text-md my-2 text-center font-bold text-black">
{partner.name}
</h1>

<div className="mb-2 h-auto w-full text-black">
<h2 className="font-bold">Benefits Provided</h2>
<p>{partner.description}</p>
</div>

<div className="mb-2 h-auto w-full text-black">
<h2 className="font-bold">Location</h2>
<p>{partner.location}</p>
</div>

<button
className="bg-primary-orange rounded-full px-5 py-2 font-bold text-white"
onClick={handleViewOnMapClick}
>
View On Map
</button>
</div>
</>
);
}
2 changes: 2 additions & 0 deletions web/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { graphqlClient } from "./graphql/client.ts";
import CreditsScreen from "./screens/CreditsScreen.tsx";
import SignInScreen from "./screens/SignInScreen.tsx";
import EventScreen from "./screens/EventScreen.tsx";
import PartnersScreen from "./screens/PartnersScreen.tsx";

//Add any routes for screens below
const router = createBrowserRouter(
Expand All @@ -31,6 +32,7 @@ const router = createBrowserRouter(
<Route path="/test" element={<TestScreen />} />
<Route path="/credits" element={<CreditsScreen />} />
<Route path="/exec" element={<ExecScreen />} />
<Route path="/sponsors" element={<PartnersScreen />} />
<Route path="/login" element={<SignInScreen />} />
<Route path="/signup" element={<SignUpScreen />} />
<Route path="/about-us" element={<AboutUsScreen />} />
Expand Down
Loading

0 comments on commit 32b7308

Please sign in to comment.