-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the approve mentor and create category endpoints (#63)
- Loading branch information
1 parent
9f3ad01
commit 538f1fb
Showing
21 changed files
with
349 additions
and
84 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import type { Request, Response } from 'express' | ||
import type Profile from '../../entities/profile.entity' | ||
import { ProfileTypes } from '../../enums' | ||
import { createCategory } from '../../services/admin/category.service' | ||
|
||
export const addCategory = async ( | ||
req: Request, | ||
res: Response | ||
): Promise<void> => { | ||
try { | ||
const user = req.user as Profile | ||
const { categoryName } = req.body | ||
|
||
if (user.type !== ProfileTypes.ADMIN) { | ||
res.status(403).json({ message: 'Only Admins are allowed' }) | ||
} else { | ||
const { category, statusCode, message } = await createCategory( | ||
categoryName | ||
) | ||
|
||
res.status(statusCode).json({ category, message }) | ||
} | ||
} catch (err) { | ||
console.error('Error executing query', err) | ||
res.status(500).json({ error: err }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import type { Request, Response } from 'express' | ||
import { updateMentorStatus } from '../../services/admin/mentor.service' | ||
import { ApplicationStatus, ProfileTypes } from '../../enums' | ||
import type Profile from '../../entities/profile.entity' | ||
|
||
export const mentorStatusHandler = async ( | ||
req: Request, | ||
res: Response | ||
): Promise<void> => { | ||
try { | ||
const user = req.user as Profile | ||
const { status } = req.body | ||
const { mentorId } = req.params | ||
|
||
if (user.type !== ProfileTypes.ADMIN) { | ||
res.status(403).json({ message: 'Only Admins are allowed' }) | ||
} else { | ||
if (!(status.toUpperCase() in ApplicationStatus)) { | ||
res.status(400).json({ message: 'Please provide a valid status' }) | ||
return | ||
} | ||
const { mentor, statusCode, message } = await updateMentorStatus( | ||
mentorId, | ||
status | ||
) | ||
res.status(statusCode).json({ mentor, message }) | ||
} | ||
} catch (err) { | ||
if (err instanceof Error) { | ||
console.error('Error executing query', err) | ||
res | ||
.status(500) | ||
.json({ error: 'Internal server error', message: err.message }) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
import express from 'express' | ||
import { getAllUsersHandler } from '../../controllers/admin/user.controller' | ||
import { requireAuth } from '../../controllers/auth.controller' | ||
import userRouter from './user/user.route' | ||
import mentorRouter from './mentor/mentor.route' | ||
import categoryRouter from './category/category.route' | ||
|
||
const adminRouter = express.Router() | ||
const adminRouter = express() | ||
|
||
adminRouter.get('/users', requireAuth, getAllUsersHandler) | ||
adminRouter.use('/users', userRouter) | ||
adminRouter.use('/mentors', mentorRouter) | ||
adminRouter.use('/categories', categoryRouter) | ||
|
||
export default adminRouter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { startServer } from '../../../app' | ||
import type { Express } from 'express' | ||
import supertest from 'supertest' | ||
import Profile from '../../../entities/profile.entity' | ||
import { ProfileTypes } from '../../../enums' | ||
import { dataSource } from '../../../configs/dbConfig' | ||
import bcrypt from 'bcrypt' | ||
import { mockUser, mockAdmin } from '../../../../mocks' | ||
|
||
const port = Math.floor(Math.random() * (9999 - 3000 + 1)) + 3000 | ||
|
||
let server: Express | ||
let agent: supertest.SuperAgentTest | ||
let adminAgent: supertest.SuperAgentTest | ||
|
||
describe('Admin category routes', () => { | ||
beforeAll(async () => { | ||
server = await startServer(port) | ||
agent = supertest.agent(server) | ||
adminAgent = supertest.agent(server) | ||
|
||
await supertest(server) | ||
.post('/api/auth/register') | ||
.send(mockUser) | ||
.expect(201) | ||
await agent.post('/api/auth/login').send(mockUser).expect(200) | ||
|
||
const profileRepository = dataSource.getRepository(Profile) | ||
|
||
const hashedPassword = await bcrypt.hash(mockAdmin.password, 10) | ||
const newProfile = profileRepository.create({ | ||
primary_email: mockAdmin.email, | ||
password: hashedPassword, | ||
contact_email: '', | ||
first_name: '', | ||
last_name: '', | ||
image_url: '', | ||
linkedin_url: '', | ||
type: ProfileTypes.ADMIN | ||
}) | ||
|
||
await profileRepository.save(newProfile) | ||
|
||
await adminAgent.post('/api/auth/login').send(mockAdmin).expect(200) | ||
}, 5000) | ||
|
||
it('should add a category', async () => { | ||
await adminAgent | ||
.post('/api/admin/categories') | ||
.send({ categoryName: 'Computer Science' }) | ||
.expect(201) | ||
}) | ||
|
||
it('should only allow admins to add a category', async () => { | ||
await agent | ||
.post('/api/admin/categories') | ||
.send({ categoryName: 'Computer Science' }) | ||
.expect(403) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import express from 'express' | ||
import { requireAuth } from '../../../controllers/auth.controller' | ||
import { addCategory } from '../../../controllers/admin/category.controller' | ||
|
||
const categoryRouter = express.Router() | ||
|
||
categoryRouter.post('/', requireAuth, addCategory) | ||
|
||
export default categoryRouter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { startServer } from '../../../app' | ||
import type { Express } from 'express' | ||
import supertest from 'supertest' | ||
import Profile from '../../../entities/profile.entity' | ||
import { ProfileTypes } from '../../../enums' | ||
import { dataSource } from '../../../configs/dbConfig' | ||
import bcrypt from 'bcrypt' | ||
import { mentorApplicationInfo, mockAdmin, mockMentor } from '../../../../mocks' | ||
|
||
const port = Math.floor(Math.random() * (9999 - 3000 + 1)) + 3000 | ||
|
||
let server: Express | ||
let mentorAgent: supertest.SuperAgentTest | ||
let adminAgent: supertest.SuperAgentTest | ||
let mentorId: string | ||
|
||
describe('Admin mentor routes', () => { | ||
beforeAll(async () => { | ||
server = await startServer(port) | ||
mentorAgent = supertest.agent(server) | ||
adminAgent = supertest.agent(server) | ||
|
||
await mentorAgent.post('/api/auth/register').send(mockMentor).expect(201) | ||
await mentorAgent.post('/api/auth/login').send(mockMentor).expect(200) | ||
|
||
const profileRepository = dataSource.getRepository(Profile) | ||
const hashedPassword = await bcrypt.hash(mockAdmin.password, 10) | ||
const newProfile = profileRepository.create({ | ||
primary_email: mockAdmin.email, | ||
password: hashedPassword, | ||
contact_email: '', | ||
first_name: '', | ||
last_name: '', | ||
image_url: '', | ||
linkedin_url: '', | ||
type: ProfileTypes.ADMIN | ||
}) | ||
|
||
await profileRepository.save(newProfile) | ||
|
||
await adminAgent.post('/api/auth/login').send(mockAdmin).expect(200) | ||
const categoryResponse = await adminAgent | ||
.post('/api/admin/categories') | ||
.send({ categoryName: 'Computer Science' }) | ||
.expect(201) | ||
|
||
const response = await mentorAgent | ||
.post('/api/mentors') | ||
.send({ | ||
...mentorApplicationInfo, | ||
categoryId: categoryResponse.body.category.uuid | ||
}) | ||
.expect(201) | ||
|
||
mentorId = response.body.mentor.uuid | ||
}, 5000) | ||
|
||
it('should update the mentor application state', async () => { | ||
await adminAgent | ||
.put(`/api/admin/mentors/${mentorId}/status`) | ||
.send({ status: 'approved' }) | ||
.expect(200) | ||
}) | ||
|
||
it('should return 400 when an invalid status was provided', async () => { | ||
await adminAgent | ||
.put(`/api/admin/mentors/${mentorId}/status`) | ||
.send({ status: 'invalid status' }) | ||
.expect(400) | ||
}) | ||
|
||
it('should only allow admins to update the status', async () => { | ||
await mentorAgent | ||
.put(`/api/admin/mentors/${mentorId}/status`) | ||
.send({ status: 'approved' }) | ||
.expect(403) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import express from 'express' | ||
import { requireAuth } from '../../../controllers/auth.controller' | ||
import { mentorStatusHandler } from '../../../controllers/admin/mentor.controller' | ||
|
||
const mentorRouter = express.Router() | ||
|
||
mentorRouter.put('/:mentorId/status', requireAuth, mentorStatusHandler) | ||
|
||
export default mentorRouter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import express from 'express' | ||
import { getAllUsersHandler } from '../../../controllers/admin/user.controller' | ||
import { requireAuth } from '../../../controllers/auth.controller' | ||
|
||
const userRouter = express.Router() | ||
|
||
userRouter.get('/', requireAuth, getAllUsersHandler) | ||
|
||
export default userRouter |
Oops, something went wrong.