Skip to content

Commit

Permalink
Merge pull request #273 from Kvngstar/feat/get-product-by-id
Browse files Browse the repository at this point in the history
feat: get product by Id
  • Loading branch information
incredible-phoenix246 authored Jul 24, 2024
2 parents b83a49e + da063f7 commit 673b573
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 13 deletions.
79 changes: 66 additions & 13 deletions src/controllers/ProductController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,25 +168,25 @@ export class ProductController {
* @swagger
* /api/v1/products/{product_id}:
* get:
* summary: Fetch a product by {id}
* summary: Fetch a product by its ID
* tags: [Product]
* parameters:
* - in: path
* name: product_id
* required: true
* schema:
* type: integer
* description: String ID of the product
* description: The ID of the product to fetch
* responses:
* 200:
* description: Successful response
* description: Product retrieved successfully
* content:
* application/json:
* schema:
* type: object
* properties:
* id:
* type: string
* type: integer
* example: 123
* name:
* type: string
Expand All @@ -196,42 +196,92 @@ export class ProductController {
* example: Product is robust
* price:
* type: number
* exanple: 19
* example: 19
* category:
* type: string
* example: Gadgets
* 400:
* description: Bad request
* description: Bad request due to invalid product ID
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* status:
* type: string
* example: Bad Request
* message:
* type: string
* example: Invalid product ID
* example: Invalid Product Id
* status_code:
* type: integer
* example: 400
* 404:
* description: Not found
* description: Product not found
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* status:
* type: string
* example: Not Found
* message:
* type: string
* example: Product not found
* status_code:
* type: integer
* example: 404
* 500:
* description: Internal server error
* content:
* application/json:
* schema:
* type: object
* properties:
* error:
* status:
* type: string
* example: An unexpected error occurred
* message:
* type: string
* example: Internal server error
* status_code:
* type: integer
* example: 500
*/
async fetchProductById(req: Request, res: Response) {}

async fetchProductById(req: Request, res: Response) {

const productId = req.params.product_id;

if(isNaN(Number(productId))){
return res.status(400).json({
status: "Bad Request",
message: "Invalid Product Id",
status_code: 400,
})
}

try {
const product = await this.productService.getOneProduct(productId)
if (!product) {
return res.status(404).json({
status: "Not found",
message: "Product not found",
status_code: 404,
});

}
return res.status(200).json(product);
} catch (error) {
return res.status(500).json({
status: "An unexpected error occurred",
message: "Internal server error",
status_code: 500,
});
}

}

/**
* @swagger
Expand Down Expand Up @@ -515,7 +565,10 @@ export class ProductController {
* type: string
* example: Product not found
*/
async deleteProduct(req: Request, res: Response) {}
async deleteProduct(req: Request, res: Response) {


}
}

export default ProductController;
9 changes: 9 additions & 0 deletions src/services/product.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,13 @@ export class ProductService {
throw new Error(err.message);
}
}
async getOneProduct(id: string): Promise<Product> {

const product = await this.productRepository.findOneBy({id});

return product;


}

}
84 changes: 84 additions & 0 deletions src/test/product.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Repository } from "typeorm";
import AppDataSource from "../data-source";
import { Product } from "../models/product";
import { User } from "../models";
import { ProductService } from "../services";
import { describe, expect, it, beforeEach, afterEach } from "@jest/globals";

jest.mock("../data-source", () => ({
__esModule: true,
default: {
getRepository: jest.fn(),
initialize: jest.fn(),
isInitialized: false,
},
}));

describe("ProductService", () => {
let productService: ProductService;
let mockRepository: jest.Mocked<Repository<Product>>;

beforeEach(() => {
mockRepository = {
findOneBy: jest.fn(),
// Add other methods if needed
} as any;

(AppDataSource.getRepository as jest.Mock).mockReturnValue(mockRepository);

productService = new ProductService();
});

afterEach(() => {
jest.resetAllMocks();
});

describe("fetchProductById", () => {
it("should return the product if it exists", async () => {
const productId = "123";
const user: User = {
id: 'user-123',
name: 'John Doe',
// Add any other necessary properties
} as User;
const product = {
id: "123",
name: "Product 1",
description: "Product is robust",
price: 19,
category: "Gadgets",
user:user

} as Product;

mockRepository.findOneBy.mockResolvedValue(product);

const result = await productService.getOneProduct(productId);
expect(result).toEqual(product);
expect(mockRepository.findOneBy).toHaveBeenCalledWith({ id: productId });
});

it("should return null if the product does not exist", async () => {
const productId = "non-existing-id";

mockRepository.findOneBy.mockResolvedValue(null);

const result = await productService.getOneProduct(productId);

expect(result).toBeNull();
expect(mockRepository.findOneBy).toHaveBeenCalledWith({ id: productId });
});

it("should throw an error if there is an issue with fetching the product", async () => {
const productId = "123";
const error = new Error("Error fetching product");

mockRepository.findOneBy.mockRejectedValue(error);

await expect(productService.getOneProduct(productId)).rejects.toThrow(
"Error fetching product",
);
expect(mockRepository.findOneBy).toHaveBeenCalledWith({ id: productId });
});
});
});

0 comments on commit 673b573

Please sign in to comment.