Skip to content

Commit

Permalink
Merge pull request #160 from Code-Hammers/CHE-84/subtask/Create-Tests…
Browse files Browse the repository at this point in the history
…-And-Error-Handling-For-userController-authUser

Che 84/subtask/create tests and error handling for user controller auth user
  • Loading branch information
brok3turtl3 authored Aug 8, 2024
2 parents a59881d + 8217643 commit 4224d74
Show file tree
Hide file tree
Showing 56 changed files with 1,312 additions and 1,031 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/build-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ jobs:
uses: actions/setup-node@v2
with:
node-version: '20.14.0'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Install Docker Compose
run: sudo apt-get update && sudo apt-get install -y docker-compose
- name: Build Docker Image
run: docker build -t codehammers/ch-dev-dep-v3:latest -f Dockerfile-dev .
- name: Install Root Dependencies
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import Alumni from '../models/alumniModel';
import Alumni from '../../../models/alumniModel';
import { Request, Response } from 'express';
import { IAlumni } from '../types/alumni';
import { IAlumni } from '../../../types/alumni';

interface SearchQuery {
name?: { $regex: string; $options: string };
company?: { $regex: string; $options: string };
}

// ENDPOINT GET api/users/login
// PURPOSE Retrieve all alumni data
// ACCESS Private
const getAllAlumniData = async (req: Request, res: Response) => {
const page = parseInt(req.query.page as string) || 1;
const limit = parseInt(req.query.limit as string) || 10;
Expand Down Expand Up @@ -38,4 +41,4 @@ const getAllAlumniData = async (req: Request, res: Response) => {
}
};

export { getAllAlumniData };
export default getAllAlumniData;
3 changes: 3 additions & 0 deletions server/controllers/alumniController/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import getAllAlumniData from './getAllAlumniData/getAllAumniData';

export { getAllAlumniData };
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const createApplication = async (req: Request, res: Response) => {
try {
const {
title,
company,
location,
description,
url,
status_id,
quick_apply,
date_applied,
general_notes,
user_id,
} = req.body;

const appliedDate = new Date(date_applied).toISOString();

const jobQuery = `
INSERT INTO jobs (title, company, location, description, url)
VALUES ($1, $2, $3, $4, $5)
RETURNING id
`;
const jobValues = [title, company, location, description, url];
const jobResult = await pool.query(jobQuery, jobValues);
const job_id = jobResult.rows[0].id;

const applicationQuery = `
INSERT INTO applications (job_id, status_id, user_id, quick_apply, date_applied, general_notes, last_updated)
VALUES ($1, $2, $3, $4, $5, $6, NOW())
RETURNING id
`;
const applicationValues = [job_id, status_id, user_id, quick_apply, appliedDate, general_notes];
const applicationResult = await pool.query(applicationQuery, applicationValues);

res.status(201).json({ id: applicationResult.rows[0].id });
} catch (error) {
console.error('Error creating application:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default createApplication;
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

interface StatusCount {
status: string;
count: string;
}

const getAggregatedUserStats = async (req: Request, res: Response) => {
const { userId } = req.params;
if (!req.user || req.user.id !== userId)
return res.status(401).json({ message: 'You are not authorized to retrieve those records' });
try {
const applicationsByStatusQuery = `
SELECT statuses.name AS status, COUNT(*) AS count
FROM applications
JOIN statuses ON applications.status_id = statuses.id
WHERE applications.user_id = $1
GROUP BY statuses.name
`;
const applicationsByStatusResult = await pool.query<StatusCount>(applicationsByStatusQuery, [
userId,
]);

const totalApplications = applicationsByStatusResult.rows.reduce(
(sum: number, row: StatusCount) => sum + parseInt(row.count, 10),
0,
);

res.json({
totalApplications,
applicationsByStatus: applicationsByStatusResult.rows,
});
} catch (error) {
console.error('Error fetching aggregated data:', error);
res.status(500).send('Internal server error');
}
};

export default getAggregatedUserStats;
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const getAllApplications = async (req: Request, res: Response) => {
try {
const { userId, status, date } = req.query;

let query = `
SELECT
applications.id,
jobs.company,
jobs.title,
statuses.name AS status,
applications.general_notes,
applications.date_applied,
applications.last_updated,
applications.notification_period,
applications.notifications_paused
FROM
applications
INNER JOIN jobs ON applications.job_id = jobs.id
INNER JOIN statuses ON applications.status_id = statuses.id
WHERE
applications.user_id = $1
`;

const queryParams = [userId];
let paramIndex = 2;

if (status) {
query += ` AND statuses.name != $${paramIndex}`;
queryParams.push(status);
paramIndex += 1;
}

if (date) {
query += ` AND applications.date_applied >= $${paramIndex}`;
queryParams.push(date);
}

const { rows } = await pool.query(query, queryParams);

res.json(rows);
} catch (error) {
console.error('Error fetching job applications:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default getAllApplications;
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const getApplicationById = async (req: Request, res: Response) => {
const { id } = req.params;
try {
const query = `
SELECT
applications.id,
jobs.title,
jobs.company,
jobs.location,
jobs.description,
jobs.url,
statuses.id AS status_id,
statuses.name AS status,
applications.quick_apply,
applications.date_applied,
applications.general_notes,
applications.job_id,
applications.user_id
FROM
applications
INNER JOIN jobs ON applications.job_id = jobs.id
INNER JOIN statuses ON applications.status_id = statuses.id
WHERE
applications.id = $1
`;
const { rows } = await pool.query(query, [id]);

if (rows.length === 0) {
return res.status(404).json({ message: 'Application not found' });
}

if (!req.user || req.user.id !== rows[0].user_id)
return res.status(401).json({ message: 'You are not authorized to retrieve those records' });

res.json(rows[0]);
} catch (error) {
console.error('Error fetching application by id:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default getApplicationById;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const getStatuses = async (req: Request, res: Response) => {
try {
const { rows } = await pool.query('SELECT * FROM statuses');
res.json(rows);
} catch (error) {
console.error('Error fetching statuses:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default getStatuses;
19 changes: 19 additions & 0 deletions server/controllers/applicationController/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import createApplication from './createApplication/createApplication';
import getAggregatedUserStats from './getAggregateUserStats/getAggregateUserStats';
import getAllApplications from './getAllApplications/getAllApplications';
import getApplicationById from './getApplicationById/getApplicationById';
import getStatuses from './getStatuses/getStatuses';
import pauseNotifications from './pauseNotifications/pauseNotifications';
import updateApplication from './updateApplication/updateApplication';
import updateNotificationPeriod from './updateNotificationPeriod/updateNotificationPeriod';

export {
createApplication,
getAggregatedUserStats,
getAllApplications,
getApplicationById,
getStatuses,
pauseNotifications,
updateNotificationPeriod,
updateApplication,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const pauseNotifications = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const { pause } = req.body;

const query = `
UPDATE applications
SET notifications_paused = $1
WHERE id = $2
`;
await pool.query(query, [pause, id]);
res.status(200).json({ message: `Notifications ${pause ? 'paused' : 'resumed'} successfully` });
} catch (error) {
console.error('Error pausing/resuming notifications:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default pauseNotifications;
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const updateApplication = async (req: Request, res: Response) => {
const { id } = req.params;

if (!req.user) {
return res.status(401).json({ message: 'You are not authorized to update this record' });
}

try {
const { job_id, status_id, user_id, quick_apply, date_applied, general_notes } = req.body;
const query = `
UPDATE applications
SET job_id = $1, status_id = $2, user_id = $3, quick_apply = $4, date_applied = $5, general_notes = $6, last_updated = NOW()
WHERE id = $7 AND user_id = $8
RETURNING id
`;
const { rows } = await pool.query(query, [
job_id,
status_id,
user_id,
quick_apply,
date_applied,
general_notes,
id,
req.user.id,
]);

if (rows.length === 0) {
return res
.status(401)
.json({ message: 'You are not authorized to update this record or application not found' });
}

res.status(200).json({ message: 'Application updated successfully' });
} catch (error) {
console.error('Error updating application:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default updateApplication;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Request, Response } from 'express';
import { pool } from '../../../config/sql-db';

const updateNotificationPeriod = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const { period } = req.body;

const query = `
UPDATE applications
SET notification_period = $1
WHERE id = $2
`;
await pool.query(query, [period, id]);
res.status(200).json({ message: 'Notification period updated successfully' });
} catch (error) {
console.error('Error updating notification period:', error);
res.status(500).json({ message: 'Internal server error' });
}
};

export default updateNotificationPeriod;
Loading

0 comments on commit 4224d74

Please sign in to comment.