From f495c1394072df7e2951145d70ad2f6f0b33e4b7 Mon Sep 17 00:00:00 2001 From: Bamiwo Adebayo Date: Thu, 8 Aug 2024 11:43:09 +0100 Subject: [PATCH] feat: get job by id --- src/controllers/jobController.ts | 76 +++++++++++++++++++++++++++++++- src/routes/job.ts | 2 + src/services/job.service.ts | 20 +++++++++ src/test/jobService.spec.ts | 56 +++++++++++++++++++++++ 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 src/test/jobService.spec.ts diff --git a/src/controllers/jobController.ts b/src/controllers/jobController.ts index d43a0d53..5eeb3e11 100644 --- a/src/controllers/jobController.ts +++ b/src/controllers/jobController.ts @@ -1,4 +1,4 @@ -import { Request, Response } from "express"; +import { NextFunction, Request, Response } from "express"; import { JobService } from "../services/job.service"; export class JobController { @@ -20,4 +20,78 @@ export class JobController { res.status(500).json({ message: error.message, status_code: 400 }); } } + + /** + * @swagger + * /api/v1/jobs/{jobId}: + * get: + * summary: Get job details by ID + * description: Retrieve the details of a job by its unique identifier. + * tags: [Jobs] + * parameters: + * - in: path + * name: jobId + * required: true + * schema: + * type: string + * description: The unique identifier of the job. + * responses: + * 200: + * description: Successfully retrieved job details. + * content: + * application/json: + * schema: + * type: object + * properties: + * id: + * type: string + * example: "1" + * title: + * type: string + * example: "Software Engineer" + * description: + * type: string + * example: "Job description here..." + * company_name: + * type: string + * example: "Company Name" + * location: + * type: string + * example: "Remote" + * salary: + * type: number + * example: 60000 + * job_type: + * type: string + * example: Backend Devloper + * 404: + * description: Job not found. + * 400: + * description: Invalid job ID format. + * 500: + * description: Internal server error. + */ + public async getJobById(req: Request, res: Response, next: NextFunction) { + try { + const jobId = req.params.id; + + const job = await this.jobService.getById(jobId); + if (!job) { + return res.status(404).json({ + status_code: 404, + success: false, + message: "Job not found", + }); + } + + res.status(200).json({ + status_code: 200, + success: true, + message: "The Job is retrieved successfully.", + data: job, + }); + } catch (error) { + next(error); + } + } } diff --git a/src/routes/job.ts b/src/routes/job.ts index 4959e428..51782c41 100644 --- a/src/routes/job.ts +++ b/src/routes/job.ts @@ -12,4 +12,6 @@ jobRouter.post( jobController.createJob.bind(jobController), ); +jobRouter.get("/jobs/:id", jobController.getJobById.bind(jobController)); + export { jobRouter }; diff --git a/src/services/job.service.ts b/src/services/job.service.ts index 1301a1ce..6e09255a 100644 --- a/src/services/job.service.ts +++ b/src/services/job.service.ts @@ -1,7 +1,15 @@ import { NextFunction, Request, Response } from "express"; import { Job } from "../models"; +import AppDataSource from "../data-source"; + +import { Repository } from "typeorm"; export class JobService { + private jobRepository: Repository; + constructor() { + this.jobRepository = AppDataSource.getRepository(Job); + } + public async create(req: Request): Promise { const { title, description, location, salary, job_type, company_name } = req.body; @@ -19,4 +27,16 @@ export class JobService { const job = await Job.save(jobEntity); return job; } + + public async getById(jobId: string): Promise { + try { + const job = await this.jobRepository.findOne({ + where: { id: jobId }, + }); + + return job; + } catch (error) { + throw new Error("Failed to fetch job details"); + } + } } diff --git a/src/test/jobService.spec.ts b/src/test/jobService.spec.ts new file mode 100644 index 00000000..a1b3cd1b --- /dev/null +++ b/src/test/jobService.spec.ts @@ -0,0 +1,56 @@ +import { JobService } from "../services/job.service"; +import { Repository } from "typeorm"; +import { Job } from "../models/job"; +import AppDataSource from "../data-source"; +import { BadRequest } from "../middleware"; + +jest.mock("../data-source"); + +describe("JobService", () => { + let jobService: JobService; + let jobRepository: jest.Mocked>; + + beforeEach(() => { + jobRepository = { + findOne: jest.fn(), + } as any; + + AppDataSource.getRepository = jest.fn().mockImplementation((model) => { + if (model === Job) { + return jobRepository; + } + throw new Error("Unknown model"); + }); + + jobService = new JobService(); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("getJobById", () => { + it("should return job details for a valid ID", async () => { + const jobId = "1"; + const jobDetails = { + id: jobId, + title: "Software Engineer", + description: "Job description here...", + user_id: "21", + location: "Remote", + salary: "60000", + job_type: "Developer", + company_name: "Company Name", + } as Job; + + jobRepository.findOne.mockResolvedValue(jobDetails); + + const result = await jobService.getById(jobId); + + expect(jobRepository.findOne).toHaveBeenCalledWith({ + where: { id: jobId }, + }); + expect(result).toEqual(jobDetails); + }); + }); +});