Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #19

Closed
wants to merge 52 commits into from
Closed

Dev #19

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
aecdde2
Progress on task 12 test and ts file
dylandunsheath Nov 16, 2024
8727138
Update inMemory code for clearAllData of in-memory storage
dylandunsheath Nov 16, 2024
4726cb9
Edit comments in inMemory.ts to adhere to standards
dylandunsheath Nov 16, 2024
d738473
Update to remove export from interface SessionData
dylandunsheath Nov 16, 2024
83625ba
Update to ensure format standards
dylandunsheath Nov 19, 2024
8c56bf1
Update to adhere to Julia review of code
dylandunsheath Nov 19, 2024
f5ae568
Add task8 implementation folder
ags54 Nov 24, 2024
dd55453
use oak for upload endpoints instead of deno serve
AlaraBread Nov 24, 2024
fe2e49c
fix formdata parsing in tests
AlaraBread Nov 24, 2024
d9e7fce
remove console.log from test
AlaraBread Nov 24, 2024
81c1e22
normalize response type
AlaraBread Nov 24, 2024
cad91a7
format with deno
AlaraBread Nov 24, 2024
554da42
deno fmt
AlaraBread Nov 24, 2024
9828213
move create body to util and use in job description
AlaraBread Nov 24, 2024
053450b
deno fmt
AlaraBread Nov 24, 2024
1499a1a
Task 9 and 10 completed
cns28 Nov 22, 2024
a81daaa
Renamed files and updated/fixed files for Task 9 and 10
cns28 Nov 23, 2024
b17da1c
use form to submit file data
AlaraBread Nov 23, 2024
abcdd10
Current using a real text file to pass unit test
cns28 Nov 23, 2024
b2ceb98
mock formdata get in resume form test
AlaraBread Nov 24, 2024
da2a1fd
remove unnessecary user-event
AlaraBread Nov 24, 2024
31a2a61
Progress for dashboard
dylandunsheath Nov 21, 2024
df9c49d
Update to ImprovementSuggestions function naming
dylandunsheath Nov 21, 2024
16f52b6
Update to rename dashboard files
dylandunsheath Nov 21, 2024
fab7193
Update with css file for readability
dylandunsheath Nov 22, 2024
cbb4d8f
Progress with React List and React Card Components
dylandunsheath Nov 23, 2024
405f6bf
Update dashboard: Rating, Card, CardContent, and styling
dylandunsheath Nov 23, 2024
a9e15f0
Update styling of dashboard along with CardHeader
dylandunsheath Nov 23, 2024
048eef5
Update to improve styling and appearence of the cards on dashboard
dylandunsheath Nov 23, 2024
631530a
Remove unusued import in fit score
dylandunsheath Nov 23, 2024
b287b86
Update: dashboard.test.tsx and fix to package-lock.json
dylandunsheath Nov 23, 2024
0700f6e
Update for CSS module
dylandunsheath Nov 24, 2024
74897f1
Update to fix min-width
dylandunsheath Nov 24, 2024
65808d0
rename css module
AlaraBread Nov 24, 2024
43801e2
add eslint
AlaraBread Nov 24, 2024
a35744d
add deno vscode config
AlaraBread Nov 24, 2024
ee224b1
add file structure to style guide
AlaraBread Nov 24, 2024
c66b971
fix typo
AlaraBread Nov 24, 2024
4fbccf5
rename in_memory to relfect style guide
AlaraBread Nov 24, 2024
40d9f8b
add isError to frontend type
AlaraBread Nov 24, 2024
a8da60e
format with prettier
AlaraBread Nov 24, 2024
a105881
add check scripts
AlaraBread Nov 24, 2024
4e02639
dont commit temporary files
AlaraBread Nov 24, 2024
2ba0233
add pre-commit hook
AlaraBread Nov 24, 2024
f3d8d04
allow next.js named slot
AlaraBread Nov 24, 2024
473f3e0
demonstrate mocking fetching functions in page.test.tsx
AlaraBread Nov 25, 2024
607107c
add register and login to fetching (#11)
aidank25 Nov 26, 2024
d5ad181
Completed Tasks 4 & 5 with unit tests. (#8)
FormalProcess3909 Nov 26, 2024
9413d9b
routing and login/registration integration
AlaraBread Nov 26, 2024
278d286
add loading spinner & protect routes if not logged in
AlaraBread Nov 26, 2024
f5a7e30
add more unit tests
AlaraBread Nov 26, 2024
9a47e37
cleanup and refactor (#16)
AlaraBread Nov 26, 2024
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
3 changes: 2 additions & 1 deletion .github/workflows/deno.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ jobs:
run: cd backend; deno lint

- name: Run tests
run: cd backend; deno test -A
run: cd backend; deno test --allow-read --allow-env --trace-leaks

2 changes: 2 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
run: cd frontend; npm ci
- name: check formatting with prettier
run: cd frontend; npm run check-formatting
- name: lint
run: cd frontend; npm run lint
- name: nextjs build
run: cd frontend; npm run build
- name: run tests
Expand Down
9 changes: 6 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# editor
/.vscode/

# node
/node_modules

# temporary files
*.tmp

# Environment variables
.env
4 changes: 4 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"deno.enable": true,
"deno.enablePaths": ["backend"]
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ deno run dev

(in `/backend`)
```sh
deno run test
deno test --allow-read --allow-env --trace-leaks
```
1 change: 1 addition & 0 deletions backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
JWT_SECRET_KEY=team6-resume-analyser
190 changes: 190 additions & 0 deletions backend/api/login/login.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import { assertEquals } from "@std/assert";
import { createMockContext } from "@oak/oak/testing";
import { Router } from "@oak/oak";
import userLogin from "./login.ts";
import { users } from "../register/register.ts";
import { createBody } from "../../util/util.test.ts";
import { generateHash } from "../../util/generate_hash.ts";

Deno.test("POST /api/login - Successful Login", async () => {
// Generate the hashed password
const hashedPassword = await generateHash(
"[email protected]",
"securePassword",
);

// Pre-populate the imported users object with a registered user
users["[email protected]"] = {
email: "[email protected]",
username: "user123",
password: hashedPassword, // SHA-256 hash for 'securePassword'
};
const ctx = createMockContext({
method: "POST",
path: "/api/login",
headers: [["Content-Type", "application/json"]],
body: createBody(
JSON.stringify({
email: "[email protected]",
password: "securePassword",
}),
),
});

const router = new Router();
userLogin(router);

// Mock `next` function
const next = async () => {};

// Call the login handler
await router.routes()(ctx, next);

// Assertions
assertEquals(ctx.response.status, 200);

// Cleanup: Remove the user from the users object after the test
delete users["[email protected]"];
});

Deno.test("POST /api/login - Missing User Email", async () => {
// Generate the hashed password
const hashedPassword = await generateHash(
"[email protected]",
"securePassword",
);

// Pre-populate the imported users object with a registered user
users["[email protected]"] = {
email: "[email protected]",
username: "user123",
password: hashedPassword, // SHA-256 hash for 'securePassword'
};
const ctx = createMockContext({
method: "POST",
path: "/api/login",
headers: [["Content-Type", "application/json"]],
body: createBody(
JSON.stringify({
password: "securePassword",
}),
),
});

const router = new Router();
userLogin(router);

// Mock `next` function
const next = async () => {};

// Call the login handler
await router.routes()(ctx, next);

// Assertions
assertEquals(ctx.response.status, 400);
assertEquals(
ctx.response.body,
JSON.stringify({
isError: true,
message: "Email and password are required",
}),
);

// Cleanup: Remove the user from the users object after the test
delete users["[email protected]"];
});

Deno.test("POST /api/login - Missing User Password", async () => {
// Generate the hashed password
const hashedPassword = await generateHash(
"[email protected]",
"securePassword",
);

// Pre-populate the imported users object with a registered user
users["[email protected]"] = {
email: "[email protected]",
username: "user123",
password: hashedPassword, // SHA-256 hash for 'securePassword'
};
const ctx = createMockContext({
method: "POST",
path: "/api/login",
headers: [["Content-Type", "application/json"]],
body: createBody(
JSON.stringify({
email: "[email protected]",
}),
),
});

const router = new Router();
userLogin(router);

// Mock `next` function
const next = async () => {};

// Call the login handler
await router.routes()(ctx, next);

// Assertions
assertEquals(ctx.response.status, 400);
assertEquals(
ctx.response.body,
JSON.stringify({
isError: true,
message: "Email and password are required",
}),
);

// Cleanup: Remove the user from the users object after the test
delete users["[email protected]"];
});

Deno.test("POST /api/login - Invalid password", async () => {
// Generate the hashed password
const hashedPassword = await generateHash(
"[email protected]",
"securePassword",
);

// Pre-populate the imported users object with a registered user
users["[email protected]"] = {
email: "[email protected]",
username: "user123",
password: hashedPassword, // SHA-256 hash for 'securePassword'
};
const ctx = createMockContext({
method: "POST",
path: "/api/login",
headers: [["Content-Type", "application/json"]],
body: createBody(
JSON.stringify({
email: "[email protected]",
password: "securePassword11",
}),
),
});

const router = new Router();
userLogin(router);

// Mock `next` function
const next = async () => {};

// Call the login handler
await router.routes()(ctx, next);

// Assertions
assertEquals(ctx.response.status, 401);
assertEquals(
ctx.response.body,
JSON.stringify({
isError: true,
message: "Invalid email or password",
}),
);

// Cleanup: Remove the user from the users object after the test
delete users["[email protected]"];
});
45 changes: 45 additions & 0 deletions backend/api/login/login.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Context, Router } from "@oak/oak";
import { createJWT } from "../../util/jwt.ts";
import { generateHash } from "../../util/generate_hash.ts";
import { users } from "../register/register.ts";

export default function (router: Router) {
router.post("/api/login", login);
}

async function login(ctx: Context) {
const { email, password } = await ctx.request.body.json();

if (!email || !password) {
ctx.response.status = 400;
ctx.response.body = JSON.stringify({
isError: true,
message: "Email and password are required",
});
return;
}

const user = users[email];

const hashedPassword = await generateHash(email, password);

if (user.email !== email || user.password !== hashedPassword) {
ctx.response.status = 401;
ctx.response.body = JSON.stringify({
isError: true,
message: "Invalid email or password",
});
return;
}

// Generate JWT
const token = await createJWT(email);

// Send the token
ctx.response.status = 200;
ctx.response.body = JSON.stringify({
isError: false,
message: "Logged in",
token,
});
}
110 changes: 110 additions & 0 deletions backend/api/register/register.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { assertEquals } from "@std/assert";
import { createMockContext } from "@oak/oak/testing";
import { Router } from "@oak/oak";
import userRegistration from "./register.ts";
import { createBody } from "../../util/util.test.ts";

Deno.test("POST /api/register - Successful Registration", async () => {
const ctx = createMockContext({
method: "POST",
path: "/api/register",
headers: [["Content-Type", "application/json"]],
body: createBody(
JSON.stringify({
email: "[email protected]",
password: "securePassword",
username: "user123",
}),
),
});

const router = new Router();
userRegistration(router);

// Mock `next` function
const next = async () => {};

// Call the registration handler
await router.routes()(ctx, next);

assertEquals(ctx.response.status, 201);
assertEquals(
ctx.response.body,
JSON.stringify({
isError: false,
message: "Registered successfully",
}),
);
});

Deno.test("POST /api/register - Missing Fields", async () => {
const ctx = createMockContext({
method: "POST",
path: "/api/register",
headers: [["Content-Type", "application/json"]],
body: createBody(
JSON.stringify({
email: "[email protected]",
username: "user123", // Missing password
}),
),
});

const router = new Router();
userRegistration(router);

const next = async () => {};

await router.routes()(ctx, next);

assertEquals(ctx.response.status, 400);
assertEquals(
ctx.response.body,
JSON.stringify({
isError: true,
message: "All fields are required",
}),
);
});

Deno.test("POST /api/register - Duplicate Email", async () => {
const mockBody = {
email: "[email protected]",
password: "securePassword",
username: "user123",
};

const router = new Router();
userRegistration(router);

// First registration
const ctx1 = createMockContext({
method: "POST",
path: "/api/register",
headers: [["Content-Type", "application/json"]],
body: createBody(JSON.stringify(mockBody)),
});

const next = async () => {};

await router.routes()(ctx1, next);

// Duplicate registration
const ctx2 = createMockContext({
method: "POST",
path: "/api/register",
headers: [["Content-Type", "application/json"]],
body: createBody(JSON.stringify(mockBody)),
});

await router.routes()(ctx2, next);

assertEquals(ctx2.response.status, 400);
assertEquals(
ctx2.response.body,
JSON.stringify({
isError: true,
message: "Email already registered",
}),
);
});
Loading
Loading