Skip to content

Commit

Permalink
Merge pull request #30 from SFU-Blueprint/test/supadb
Browse files Browse the repository at this point in the history
Test/supadb
  • Loading branch information
Sallin142 authored Jun 25, 2024
2 parents 52894a4 + 14b0bfd commit 8965d16
Show file tree
Hide file tree
Showing 22 changed files with 457 additions and 786 deletions.
38 changes: 38 additions & 0 deletions client/src/app/auth/api/checkin/route.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createMocks } from "node-mocks-http";
import { NextApiRequest } from "next/types";
import POST from "./route";

jest.mock("@supabase/supabase-js", () => ({
createClient: jest.fn(() => ({
from: jest.fn().mockReturnThis(),
select: jest.fn().mockReturnThis(),
eq: jest.fn().mockReturnThis(),
single: jest
.fn()
.mockResolvedValue({ data: { sid: "user_id" }, error: null }),
update: jest.fn().mockResolvedValue({ data: [], error: null })
}))
}));

describe("Check-in API Route", () => {
let req: NextApiRequest;

beforeEach(() => {
const { req: mockReq } = createMocks();
req = mockReq as unknown as NextApiRequest;
});

it("should return 400 if email or shiftId is missing", async () => {
const mockReq = {
...req,
json: async () => ({})
} as unknown as Request;

const response = await POST(mockReq);

expect(response.status).toBe(400);
expect(await response.json()).toEqual({
error: "Email and Shift ID are required"
});
});
});
77 changes: 77 additions & 0 deletions client/src/app/auth/api/checkin/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY as string;

const supabase = createClient(supabaseUrl, supabaseServiceRoleKey);

export default async function POST(req: Request) {
const body = await req.json();
const { email, shiftId } = body;

if (!email || !shiftId) {
return NextResponse.json(
{ error: "Email and Shift ID are required" },
{ status: 400 }
);
}

try {
const { data: userData, error: userError } = await supabase
.from("users")
.select("sid")
.eq("email", email)
.single();

if (userError || !userData) {
return NextResponse.json(
{ error: userError?.message || "User not found" },
{ status: 500 }
);
}

const userId = userData.sid;

const { data: volunteerData, error: volunteerError } = await supabase
.from("volunteers")
.select("vid")
.eq("user_id", userId)
.single();

if (volunteerError || !volunteerData) {
return NextResponse.json(
{ error: volunteerError?.message || "Volunteer not found" },
{ status: 500 }
);
}

const volunteerId = volunteerData.vid;

const { data, error } = await supabase
.from("volunteer_shifts")
.update({
status: "checked in",
checked_in_at: new Date().toISOString()
})
.eq("volunteer_id", volunteerId)
.eq("shift_id", shiftId);

if (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}

return NextResponse.json({
message: "Volunteer checked in successfully",
data
});
} catch (error) {
let errorMessage = "An unknown error occurred";

if (error instanceof Error) {
errorMessage = error.message;
}

return NextResponse.json({ error: errorMessage }, { status: 500 });
}
}
30 changes: 30 additions & 0 deletions client/src/app/auth/api/checkout.ts/route.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { createMocks } from "node-mocks-http";
import { NextApiRequest } from "next/types";
import POST from "./route";

jest.mock("@supabase/supabase-js", () => ({
createClient: jest.fn(() => ({}))
}));

describe("Check-out API Route", () => {
let req: NextApiRequest;

beforeEach(() => {
const { req: mockReq } = createMocks();
req = mockReq as unknown as NextApiRequest;
});

it("should return 400 if email or shiftId is missing", async () => {
const mockReq = {
...req,
json: async () => ({})
} as unknown as Request;

const response = await POST(mockReq);

expect(response.status).toBe(400);
expect(await response.json()).toEqual({
error: "Email and Shift ID are required"
});
});
});
77 changes: 77 additions & 0 deletions client/src/app/auth/api/checkout.ts/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY as string;

const supabase = createClient(supabaseUrl, supabaseServiceRoleKey);

export default async function POST(req: Request) {
const body = await req.json();
const { email, shiftId } = body;

if (!email || !shiftId) {
return NextResponse.json(
{ error: "Email and Shift ID are required" },
{ status: 400 }
);
}

try {
const { data: userData, error: userError } = await supabase
.from("users")
.select("sid")
.eq("email", email)
.single();

if (userError || !userData) {
return NextResponse.json(
{ error: userError?.message || "User not found" },
{ status: 500 }
);
}

const userId = userData.sid;

const { data: volunteerData, error: volunteerError } = await supabase
.from("volunteers")
.select("vid")
.eq("user_id", userId)
.single();

if (volunteerError || !volunteerData) {
return NextResponse.json(
{ error: volunteerError?.message || "Volunteer not found" },
{ status: 500 }
);
}

const volunteerId = volunteerData.vid;

const { data, error } = await supabase
.from("volunteer_shifts")
.update({
status: "checked out",
checked_out_at: new Date().toISOString()
})
.eq("volunteer_id", volunteerId)
.eq("shift_id", shiftId);

if (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}

return NextResponse.json({
message: "Volunteer checked out successfully",
data
});
} catch (error) {
let errorMessage = "An unknown error occurred";

if (error instanceof Error) {
errorMessage = error.message;
}

return NextResponse.json({ error: errorMessage }, { status: 500 });
}
}
52 changes: 52 additions & 0 deletions client/src/app/auth/api/login/route.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { createMocks } from "node-mocks-http";
import { NextApiRequest } from "next/types";
import GET from "./route";

jest.mock("@supabase/supabase-js", () => ({
createClient: jest.fn(() => ({
from: jest.fn().mockReturnThis(),
select: jest.fn().mockReturnThis(),
eq: jest.fn().mockReturnThis(),
single: jest
.fn()
.mockResolvedValue({ data: { sid: "user_id" }, error: null }),
update: jest.fn().mockResolvedValue({ data: [], error: null })
}))
}));

describe("login API Route", () => {
let req: NextApiRequest;

beforeEach(() => {
const { req: mockReq } = createMocks();
req = mockReq as unknown as NextApiRequest;
});

it("should return 400 if userId is missing", async () => {
req.url = "http://localhost/api/login"; // ambiguous URL
const mockReq = {
...req,
json: async () => ({})
} as unknown as Request;

const response = await GET(mockReq);

expect(response.status).toBe(400);
expect(await response.json()).toEqual({ error: "User ID is required" });
});

it("should return 200 and user data if userId is provided", async () => {
const userId = "user_id";
req.url = `http://localhost/api/login?userId=${userId}`;

const mockReq = {
...req,
json: async () => ({})
} as unknown as Request;

const response = await GET(mockReq);

expect(response.status).toBe(200);
expect(await response.json()).toEqual({ user: { sid: userId } });
});
});
41 changes: 41 additions & 0 deletions client/src/app/auth/api/login/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY as string;
const supabase = createClient(supabaseUrl, supabaseKey);

export default async function GET(req: Request) {
const url = new URL(req.url);
const userId = url.searchParams.get("userId");

if (!userId) {
return NextResponse.json({ error: "User ID is required" }, { status: 400 });
}

try {
const { data, error } = await supabase
.from("users")
.select("*")
.eq("sid", userId)
.single();

if (error) {
if (error.details.includes("0 rows")) {
return NextResponse.json({ error: "User not found" }, { status: 404 });
}
return NextResponse.json({ error: error.message }, { status: 500 });
}

if (!data) {
return NextResponse.json({ error: "User not found" }, { status: 404 });
}

return NextResponse.json({ user: data });
} catch (err) {
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
20 changes: 20 additions & 0 deletions client/src/app/auth/api/logout/route.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import POST from "./route"; // Adjust the path as needed

jest.mock("@supabase/supabase-js", () => ({
createClient: jest.fn(() => ({
auth: {
signOut: jest.fn().mockResolvedValue({ error: null })
}
}))
}));

describe("logout API Route", () => {
it("should return 200 and success message when logout is successful", async () => {
const response = await POST();

expect(response.status).toBe(200);
expect(await response.json()).toEqual({
message: "Successfully logged out"
});
});
});
26 changes: 26 additions & 0 deletions client/src/app/auth/api/logout/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { NextResponse } from "next/server";
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY as string;
const supabase = createClient(supabaseUrl, supabaseKey);

export default async function POST() {
try {
const { error } = await supabase.auth.signOut();

if (error) {
return NextResponse.json({ error: error.message }, { status: 500 });
}

return NextResponse.json(
{ message: "Successfully logged out" },
{ status: 200 }
);
} catch (err) {
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
Loading

0 comments on commit 8965d16

Please sign in to comment.