Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
590 changes: 346 additions & 244 deletions src/App.tsx

Large diffs are not rendered by default.

116 changes: 63 additions & 53 deletions src/config/firebaseUtility.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { addDoc, collection, doc, setDoc } from "firebase/firestore";
import type { Firestore } from "firebase/firestore";
import { terminate } from "firebase/firestore";
import { initializeFirebase, initializeFirebaseUnit } from "./firebaseUtilityTest";
import {
initializeFirebase,
initializeFirebaseUnit,
} from "./firebaseUtilityTest";
import { clearFirestore } from "./firebaseUtilityTest";
import { checkAdmin, checkDuplicatedUrl } from "./firebaseUtility";
import { Sector } from "../utils/Sector";
Expand All @@ -10,77 +13,84 @@ import { Level } from "../utils/Level";
let db: Firestore;

beforeAll(async () => {
db = initializeFirebaseUnit();
})
db = initializeFirebaseUnit();
});

beforeEach(async () => {
await clearFirestore(db);
await clearFirestore(db);
});

afterAll(async () => {
await terminate(db);
await terminate(db);
});

const dummyJob = {
company_name: "testname1",
programme_name: "testprogramme1",
url: "https://www.google.com/",
closing_date: Date.now(),
salary: 0,
cv: false,
cover_letter: false,
questions: false,
visa_sponsorship: false,
sector: Sector.Technology,
level: Level.Graduate,
admin_approved_on: 200
company_name: "testname1",
programme_name: "testprogramme1",
url: "https://www.google.com/",
closing_date: Date.now(),
salary: 0,
cv: false,
cover_letter: false,
questions: false,
visa_sponsorship: false,
sector: Sector.Technology,
level: Level.Graduate,
admin_approved_on: 200,
};


test("existing_user_admin", async () => {
// add the user to the database before the test starts
const userRef = await setDoc(doc(db, "users", "user123@gmail.com"), {
admin_granted_on: "0",
is_admin: true,
last_posted_on: "0"
});

const result = await checkAdmin(db, "user123@gmail.com");
expect(result).toBe(true);
})
// add the user to the database before the test starts
const userRef = await setDoc(doc(db, "users", "uid123"), {
admin_granted_on: "0",
is_admin: true,
last_posted_on: "0",
});

const result = await checkAdmin(db, "uid123");
expect(result).toBe(true);
});

test("existing_user_not_admin", async () => {
// add the user to the database before the test starts
const userRef = await setDoc(doc(db, "users", "user123@gmail.com"), {
admin_granted_on: "0",
is_admin: false,
last_posted_on: "0"
});

const result = await checkAdmin(db, "user123@gmail.com");
expect(result).toBe(false);
// add the user to the database before the test starts
const userRef = await setDoc(doc(db, "users", "uid123"), {
admin_granted_on: "0",
is_admin: false,
last_posted_on: "0",
});

const result = await checkAdmin(db, "uid123");
expect(result).toBe(false);
});

// if a user does not exist, checkAdmin should return false
// if a user does not exist, checkAdmin should return false
test("non_existing_user", async () => {
const result = await checkAdmin(db, "not-exist@gmail.com");
expect(result).toBe(false);
const result = await checkAdmin(db, "not-exist-uid");
expect(result).toBe(false);
});

// check that duplicated urls in the same sector and same level return true
// check that duplicated urls in the same sector and same level return true
test("duplicated_url", async () => {
const job1 = await addDoc(collection(db, "jobs"), dummyJob);

const duplicated = await checkDuplicatedUrl(db, Sector.Technology, Level.Graduate, dummyJob.url);
expect(duplicated).toBeTruthy();

const job1 = await addDoc(collection(db, "jobs"), dummyJob);

const duplicated = await checkDuplicatedUrl(
db,
Sector.Technology,
Level.Graduate,
dummyJob.url
);
expect(duplicated).toBeTruthy();
});

// check that duplicated urls in different sector or level return false
// check that duplicated urls in different sector or level return false
test("duplicated_different_sector", async () => {
const job1 = await addDoc(collection(db, "jobs"), dummyJob);

const duplicated = await checkDuplicatedUrl(db, Sector.Finance, Level.Graduate, dummyJob.url);
expect(duplicated).toBeFalsy();

});
const job1 = await addDoc(collection(db, "jobs"), dummyJob);

const duplicated = await checkDuplicatedUrl(
db,
Sector.Finance,
Level.Graduate,
dummyJob.url
);
expect(duplicated).toBeFalsy();
});
75 changes: 43 additions & 32 deletions src/config/firebaseUtility.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,49 @@
import { collection, doc, getDoc, getDocs, query, where } from "firebase/firestore";
import {
collection,
doc,
getDoc,
getDocs,
query,
where,
} from "firebase/firestore";
import type { Firestore } from "firebase/firestore";

// async function to check if user is admin from the database
export async function checkAdmin(db: Firestore, email: string): Promise<boolean> {
try {
const docRef = doc(db, "users", email);
const docSnap = await getDoc(docRef);
const data = docSnap.data();
if (docSnap.exists()) {
return data ? data.is_admin : false;
} else {
return false;
}
} catch (error) {
console.log(error);
return false;
export async function checkAdmin(db: Firestore, uid: string): Promise<boolean> {
try {
const docRef = doc(db, "users", uid);
const docSnap = await getDoc(docRef);
const data = docSnap.data();
if (docSnap.exists()) {
return data ? data.is_admin : false;
} else {
return false;
}
} catch (error) {
console.log(error);
return false;
}
}

// check if a job corresponding to a url already exists in the job tab
// to prevent duplicated urls
export async function checkDuplicatedUrl(db: Firestore, sector: string, level: string, url: string): Promise<boolean> {
try {
const q = query(
collection(db, 'jobs'),
where("sector", "==", sector),
where("level", "==", level),
where("url", "==", url)
);
const querySnapshot = await getDocs(q);
return querySnapshot.size !== 0;

} catch (error) {
console.log(error);
return false;
}
}
// check if a job corresponding to a url already exists in the job tab
// to prevent duplicated urls
export async function checkDuplicatedUrl(
db: Firestore,
sector: string,
level: string,
url: string
): Promise<boolean> {
try {
const q = query(
collection(db, "jobs"),
where("sector", "==", sector),
where("level", "==", level),
where("url", "==", url)
);
const querySnapshot = await getDocs(q);
return querySnapshot.size !== 0;
} catch (error) {
console.log(error);
return false;
}
}
22 changes: 20 additions & 2 deletions src/config/firebaseUtilityFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,38 @@ export async function fetchJobs(
}
}

export async function fetchUserIDFromEmail(
db: Firestore,
email: string
): Promise<string> {
try {
const q = query(collection(db, "users"), where("email", "==", email));
const querySnapshot = await getDocs(q);
const uid = querySnapshot.docs[0].id;
return uid;
} catch (error: any) {
console.log(error);
return "";
}
}

export async function fetchAdmins(
db: Firestore
): Promise<{ email: string; granted_on: Date }[]> {
try {
const q = query(
collection(db, "users"),
where("is_admin", "==", true),
orderBy("admin_granted_on")
orderBy("admin_granted_on") // this field must be present for the admin to be returned
);
const querySnapshot = await getDocs(q);
const adminData: { email: string; granted_on: Date }[] = [];
querySnapshot.forEach((elem) => {
const data = elem.data();
adminData.push({ email: elem.id, granted_on: data.admin_granted_on });
adminData.push({
email: data.email,
granted_on: data.admin_granted_on,
});
});

return adminData;
Expand Down
Loading