diff --git a/package-lock.json b/package-lock.json index fd0cbd65..197a909a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,8 @@ "swagger-ui-express": "^5.0.0", "ts-node": "^10.9.2", "ts-node-dev": "^2.0.0", - "typescript": "^5.4.5" + "typescript": "^5.4.5", + "uuid": "^9.0.1" }, "devDependencies": { "@types/bcrypt": "^5.0.2", @@ -65,6 +66,7 @@ "@types/sequelize": "^4.28.20", "@types/swagger-jsdoc": "^6.0.4", "@types/swagger-ui-express": "^4.1.6", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^7.10.0", "@typescript-eslint/parser": "^7.10.0", "eslint": "^8.57.0", @@ -1521,6 +1523,12 @@ "@types/serve-static": "*" } }, + "node_modules/@types/uuid": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", + "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", + "dev": true + }, "node_modules/@types/validator": { "version": "13.11.10", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.10.tgz", @@ -8659,6 +8667,15 @@ "node": ">=0.6" } }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -10441,12 +10458,15 @@ } }, "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], "bin": { - "uuid": "bin/uuid" + "uuid": "dist/bin/uuid" } }, "node_modules/v8-compile-cache-lib": { diff --git a/package.json b/package.json index 8d7eda87..74d34e9b 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,8 @@ "swagger-ui-express": "^5.0.0", "ts-node": "^10.9.2", "ts-node-dev": "^2.0.0", - "typescript": "^5.4.5" + "typescript": "^5.4.5", + "uuid": "^9.0.1" }, "devDependencies": { "@types/bcrypt": "^5.0.2", @@ -107,6 +108,7 @@ "@types/sequelize": "^4.28.20", "@types/swagger-jsdoc": "^6.0.4", "@types/swagger-ui-express": "^4.1.6", + "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^7.10.0", "@typescript-eslint/parser": "^7.10.0", "eslint": "^8.57.0", diff --git a/src/databases/migrations/20240520180022-create-users.ts b/src/databases/migrations/20240520180022-create-users.ts index 0a1986f2..f94f413c 100644 --- a/src/databases/migrations/20240520180022-create-users.ts +++ b/src/databases/migrations/20240520180022-create-users.ts @@ -13,9 +13,9 @@ export default { await queryInterface.createTable("users", { id: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, - autoIncrement: true, + defaultValue: DataTypes.UUIDV4, primaryKey: true }, firstName: { diff --git a/src/databases/migrations/20240521161805-create-shops-table.ts b/src/databases/migrations/20240521161805-create-shops-table.ts index 646b1dba..78859032 100644 --- a/src/databases/migrations/20240521161805-create-shops-table.ts +++ b/src/databases/migrations/20240521161805-create-shops-table.ts @@ -4,12 +4,13 @@ export = { up: async (queryInterface: QueryInterface) => { await queryInterface.createTable("shops", { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true }, userId: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, references: { model: "users", diff --git a/src/databases/migrations/20240523180022-create-sessions.ts b/src/databases/migrations/20240523180022-create-sessions.ts index cfb24af0..dedbe5f5 100644 --- a/src/databases/migrations/20240523180022-create-sessions.ts +++ b/src/databases/migrations/20240523180022-create-sessions.ts @@ -3,12 +3,13 @@ export default { up: async (queryInterface: QueryInterface) => { await queryInterface.createTable("sessions", { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true }, userId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, device: { diff --git a/src/databases/migrations/20240601223523-create-collection.ts b/src/databases/migrations/20240601223523-create-collection.ts index d2ddecfe..1e472556 100644 --- a/src/databases/migrations/20240601223523-create-collection.ts +++ b/src/databases/migrations/20240601223523-create-collection.ts @@ -5,20 +5,20 @@ export default { up:async(queryInterface: QueryInterface, Sequelize: Sequelize)=> { await queryInterface.createTable("collection", { id: { + type: DataTypes.UUID, allowNull: false, - primaryKey: true, - type: DataTypes.INTEGER, - autoIncrement: true + defaultValue: DataTypes.UUIDV4, + primaryKey: true }, name: { allowNull: false, type: DataTypes.STRING(128) }, - sellerId: { + shopId: { allowNull: false, - type: DataTypes.INTEGER, + type: DataTypes.UUID, references: { - model: "users", + model: "shops", key: "id" }, onDelete: "CASCADE" diff --git a/src/databases/migrations/20240601223524-create-products.ts b/src/databases/migrations/20240601223524-create-products.ts index ccd3fe97..149d246c 100644 --- a/src/databases/migrations/20240601223524-create-products.ts +++ b/src/databases/migrations/20240601223524-create-products.ts @@ -4,11 +4,11 @@ import { QueryInterface, DataTypes } from "sequelize"; export default{ up :async (queryInterface: QueryInterface, Sequelize: any)=> { await queryInterface.createTable("Products", { - id: { - allowNull: false, - primaryKey: true, - type: DataTypes.INTEGER, - autoIncrement: true + id: { + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, + primaryKey: true }, name: { allowNull: false, @@ -42,7 +42,7 @@ export default{ }, collectionId: { allowNull: false, - type: DataTypes.INTEGER, + type: DataTypes.UUID, references: { model: "collection", key: "id" @@ -51,7 +51,7 @@ export default{ }, shopId: { allowNull: false, - type: DataTypes.INTEGER, + type: DataTypes.UUID, references: { model: "shops", key: "id" diff --git a/src/databases/migrations/20240603150804-create-orders.ts b/src/databases/migrations/20240603150804-create-orders.ts index 4bb4c00b..704b84ff 100644 --- a/src/databases/migrations/20240603150804-create-orders.ts +++ b/src/databases/migrations/20240603150804-create-orders.ts @@ -4,12 +4,13 @@ export = { up: async (queryInterface: QueryInterface) => { await queryInterface.createTable("orders", { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true }, userId: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, references: { model: "users", @@ -19,10 +20,10 @@ export = { onDelete: "CASCADE" }, shopId: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, references: { - model: "users", + model: "shops", key: "id" }, onUpdate: "CASCADE", diff --git a/src/databases/migrations/20240604150545-create-order-products.ts b/src/databases/migrations/20240604150545-create-order-products.ts index 4e49afb1..601035e8 100644 --- a/src/databases/migrations/20240604150545-create-order-products.ts +++ b/src/databases/migrations/20240604150545-create-order-products.ts @@ -4,12 +4,13 @@ export = { up: async (queryInterface: QueryInterface) => { await queryInterface.createTable("order_products", { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true }, productId: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, references: { model: "Products", @@ -19,7 +20,7 @@ export = { onDelete: "CASCADE" }, orderId: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, references: { model: "orders", diff --git a/src/databases/models/collection.ts b/src/databases/models/collection.ts index 0b984319..051b592b 100644 --- a/src/databases/models/collection.ts +++ b/src/databases/models/collection.ts @@ -5,7 +5,7 @@ import { ICollection } from "../../types"; class collection extends Model { declare id: number; - declare sellerId: number; + declare shopId: number; declare name: string; declare description?: string; } @@ -13,16 +13,16 @@ class collection extends Model { collection.init( { id: { - type: DataTypes.INTEGER, + type: DataTypes.UUID, allowNull: false, - autoIncrement: true, + defaultValue: DataTypes.UUIDV4, primaryKey: true - }, - sellerId: { + }, + shopId: { allowNull: false, - type: DataTypes.INTEGER, + type: DataTypes.UUID, references: { - model: "users", + model: "shops", key: "id" }, onDelete: "CASCADE" diff --git a/src/databases/models/orderProducts.ts b/src/databases/models/orderProducts.ts index 9d994926..4eb1ec85 100644 --- a/src/databases/models/orderProducts.ts +++ b/src/databases/models/orderProducts.ts @@ -33,16 +33,17 @@ class OrderProduct extends Model implements OrderProduct OrderProduct.init( { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true - }, + }, productId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, orderId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, quantity: { diff --git a/src/databases/models/orders.ts b/src/databases/models/orders.ts index 8934ff50..311458b8 100644 --- a/src/databases/models/orders.ts +++ b/src/databases/models/orders.ts @@ -35,16 +35,17 @@ class Order extends Model implements OrderAttributes { Order.init( { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true - }, + }, userId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, shopId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, paymentMethodId: { diff --git a/src/databases/models/products.ts b/src/databases/models/products.ts index 926c1a42..68813a15 100644 --- a/src/databases/models/products.ts +++ b/src/databases/models/products.ts @@ -25,14 +25,14 @@ class Products extends Model { Products.init( { id: { + type: DataTypes.UUID, allowNull: false, - primaryKey: true, - autoIncrement: true, - type: DataTypes.INTEGER - }, + defaultValue: DataTypes.UUIDV4, + primaryKey: true + }, collectionId: { allowNull: false, - type: DataTypes.INTEGER, + type: DataTypes.UUID, references: { model: "collection", key: "id" @@ -41,7 +41,7 @@ Products.init( }, shopId: { allowNull: false, - type: DataTypes.INTEGER, + type: DataTypes.UUID, references: { model: "shops", key: "id" diff --git a/src/databases/models/session.ts b/src/databases/models/session.ts index 67c196a4..fcfa10c5 100644 --- a/src/databases/models/session.ts +++ b/src/databases/models/session.ts @@ -29,12 +29,13 @@ export interface SessionAttributes { Session.init( { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true - }, + }, userId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, device: { diff --git a/src/databases/models/shops.ts b/src/databases/models/shops.ts index a7821ee7..3d605817 100644 --- a/src/databases/models/shops.ts +++ b/src/databases/models/shops.ts @@ -27,12 +27,13 @@ export interface ShopAttributes { Shop.init( { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true - }, + }, userId: { - type: new DataTypes.INTEGER, + type: new DataTypes.UUID, allowNull: false }, name: { diff --git a/src/databases/models/users.ts b/src/databases/models/users.ts index 5de2f026..f107bcfd 100644 --- a/src/databases/models/users.ts +++ b/src/databases/models/users.ts @@ -57,8 +57,9 @@ class Users Users.init( { id: { - type: DataTypes.INTEGER, - autoIncrement: true, + type: DataTypes.UUID, + allowNull: false, + defaultValue: DataTypes.UUIDV4, primaryKey: true }, firstName: { diff --git a/src/databases/seeders/20240520202759-users.ts b/src/databases/seeders/20240520202759-users.ts index dc6d7d33..99a05e6b 100644 --- a/src/databases/seeders/20240520202759-users.ts +++ b/src/databases/seeders/20240520202759-users.ts @@ -1,6 +1,9 @@ + import { QueryInterface } from "sequelize" import { hashPassword } from "../../helpers" +import { userFourId, userOneId, userThreeId, userTwoId } from "../../types/uuid" const userOne = { + id: userOneId, createdAt: new Date(), updatedAt: new Date(), firstName:"hyassin509", @@ -14,10 +17,10 @@ const userOne = { language: "english", currency: "USD", role: "admin", - status: "enabled", - id: 1 + status: "enabled" } const userTwo = { + id: userTwoId, createdAt: new Date(), updatedAt: new Date(), firstName: "John", @@ -31,11 +34,11 @@ const userTwo = { language: "English", currency: "USD", role: "buyer", - status: "enabled", - id: 2 + status: "enabled" } const userThree = { + id: userThreeId, createdAt: new Date(), updatedAt: new Date(), firstName:"paccy509", @@ -49,11 +52,11 @@ const userThree = { language: "english", currency: "USD", role: "buyer", - status: "enabled", - id: 3 + status: "enabled" } const userFour = { + id: userFourId, createdAt: new Date(), updatedAt: new Date(), firstName:"SellerTest", @@ -67,8 +70,7 @@ const userFour = { language: "english", currency: "USD", role: "seller", - status: "enabled", - id: 4 + status: "enabled" } const up = (queryInterface: QueryInterface) => queryInterface.bulkInsert("users",[userOne, userTwo, userThree, userFour]) diff --git a/src/databases/seeders/20240521162108-shops.ts b/src/databases/seeders/20240521162108-shops.ts index ff594639..daccad20 100644 --- a/src/databases/seeders/20240521162108-shops.ts +++ b/src/databases/seeders/20240521162108-shops.ts @@ -1,11 +1,12 @@ import { QueryInterface } from "sequelize"; +import { shopOneId, userFourId } from "../../types/uuid"; module.exports = { async up(queryInterface: QueryInterface) { await queryInterface.bulkInsert("shops", [ { - id: 1, - userId: 4, + id: shopOneId, + userId: userFourId, name: "Shop One", description: "Description for Shop One", createdAt: new Date(), diff --git a/src/databases/seeders/20240601224834-collection.ts b/src/databases/seeders/20240601224834-collection.ts index 43260579..977bcbe4 100644 --- a/src/databases/seeders/20240601224834-collection.ts +++ b/src/databases/seeders/20240601224834-collection.ts @@ -1,20 +1,21 @@ import { QueryInterface } from "sequelize"; +import { collectionOneId, collectionTwoId, shopOneId } from "../../types/uuid"; module.exports = { async up(queryInterface: QueryInterface) { await queryInterface.bulkInsert("collection", [ { - id: 1, + id: collectionOneId, name: "Shoes", - sellerId: 1, + shopId: shopOneId, description: "Shoes", createdAt: new Date(), updatedAt: new Date() }, { - id: 2, + id: collectionTwoId, name: "Electronics", - sellerId: 2, + shopId: shopOneId, description: "Electronics", createdAt: new Date(), updatedAt: new Date() diff --git a/src/databases/seeders/20240601224835-products.ts b/src/databases/seeders/20240601224835-products.ts index eecfd586..b099f777 100644 --- a/src/databases/seeders/20240601224835-products.ts +++ b/src/databases/seeders/20240601224835-products.ts @@ -1,10 +1,11 @@ import { QueryInterface } from "sequelize"; +import { collectionTwoId, productOneId, productTwoId, shopOneId } from "../../types/uuid"; module.exports = { async up(queryInterface: QueryInterface) { await queryInterface.bulkInsert("Products", [ { - id: 1, + id: productOneId, name: "Product 1", description: "Description for product 1", price: 19.99, @@ -13,8 +14,8 @@ module.exports = { expiryDate: new Date("2023-12-31"), expired: false, bonus: "Bonus 1", - collectionId: 1, - shopId: 1, + collectionId: collectionTwoId, + shopId: shopOneId, images: ["image1.jpg", "image2.jpg"], quantity: 50, isAvailable: "available", @@ -22,7 +23,7 @@ module.exports = { updatedAt: new Date() }, { - id: 2, + id: productTwoId, name: "Product 2", description: "Description for product 2", price: 29.99, @@ -31,8 +32,8 @@ module.exports = { expiryDate: new Date("2024-12-31"), expired: false, bonus: "Bonus 2", - collectionId: 2, - shopId:1, + collectionId: collectionTwoId, + shopId:shopOneId, images: ["image3.jpg", "image4.jpg"], quantity: 100, isAvailable: "available", diff --git a/src/databases/seeders/20240604133044-orders.ts b/src/databases/seeders/20240604133044-orders.ts index 911ddcd9..7ad8863f 100644 --- a/src/databases/seeders/20240604133044-orders.ts +++ b/src/databases/seeders/20240604133044-orders.ts @@ -1,12 +1,13 @@ import { QueryInterface } from "sequelize"; +import { orderOneId, orderTwoId, shopOneId, userOneId, userTwoId } from "../../types/uuid"; module.exports = { async up(queryInterface: QueryInterface) { await queryInterface.bulkInsert("orders", [ { - id: 1, - userId: 1, - shopId: 1, + id: orderOneId, + userId: userOneId, + shopId: shopOneId, paymentMethodId: 1, amount: 150.0, orderDate: new Date("2024-01-01"), @@ -15,9 +16,9 @@ module.exports = { updatedAt: new Date() }, { - id: 2, - userId: 2, - shopId: 1, + id: orderTwoId, + userId: userTwoId, + shopId: shopOneId, paymentMethodId: 2, amount: 200.0, orderDate: new Date("2024-01-15"), diff --git a/src/databases/seeders/20240604133118-order-products.ts b/src/databases/seeders/20240604133118-order-products.ts index b3b0c31c..f438e435 100644 --- a/src/databases/seeders/20240604133118-order-products.ts +++ b/src/databases/seeders/20240604133118-order-products.ts @@ -1,12 +1,13 @@ import { QueryInterface } from "sequelize"; +import { orderOneId, orderProductFourId, orderProductThreeId, orderTwoId, productOneId, productTwoId } from "../../types/uuid"; module.exports = { async up(queryInterface: QueryInterface) { await queryInterface.bulkInsert("order_products", [ { - id: 1, - productId: 1, - orderId: 1, + id: orderOneId, + productId: productOneId, + orderId: orderOneId, quantity: 5, discount: 10.0, unitPrice: 30.0, @@ -14,9 +15,9 @@ module.exports = { updatedAt: new Date() }, { - id: 2, - productId: 2, - orderId: 1, + id: orderTwoId, + productId: productTwoId, + orderId: orderOneId, quantity: 19, discount: 5.0, unitPrice: 100.0, @@ -24,9 +25,9 @@ module.exports = { updatedAt: new Date() }, { - id: 3, - productId: 1, - orderId: 2, + id: orderProductThreeId, + productId: productOneId, + orderId: orderTwoId, quantity: 23, discount: 0.0, unitPrice: 30.0, @@ -34,9 +35,9 @@ module.exports = { updatedAt: new Date() }, { - id: 4, - productId: 2, - orderId: 2, + id: orderProductFourId, + productId: productTwoId, + orderId: orderTwoId, quantity: 40, discount: 15.0, unitPrice: 100.0, diff --git a/src/modules/auth/test/auth.spec.ts b/src/modules/auth/test/auth.spec.ts index 11061f9e..012b9d0f 100644 --- a/src/modules/auth/test/auth.spec.ts +++ b/src/modules/auth/test/auth.spec.ts @@ -25,7 +25,7 @@ dotenv.config(); chai.use(chaiHttp); const router = () => chai.request(app); -let userId: number = 0; +let userId: string; let verifyToken: string | null = null; describe("Authentication Test Cases", () => { diff --git a/src/modules/user/controller/userControllers.ts b/src/modules/user/controller/userControllers.ts index 8bd21d6a..db19e110 100644 --- a/src/modules/user/controller/userControllers.ts +++ b/src/modules/user/controller/userControllers.ts @@ -4,7 +4,7 @@ import uploadImages from "../../../helpers/uploadImage"; import userRepositories from "../repository/userRepositories"; import authRepositories from "../../auth/repository/authRepositories"; -const adminGetUsers = async (req:Request, res:Response) =>{ +const adminGetUsers = async (req: Request, res: Response) => { try { const data = await userRepositories.getAllUsers() return res.status(httpStatus.OK).json({ @@ -19,7 +19,7 @@ const adminGetUsers = async (req:Request, res:Response) =>{ } } -const adminGetUser = async (req:Request, res:Response) =>{ +const adminGetUser = async (req: Request, res: Response) => { try { const data = await authRepositories.findUserByAttributes("id", req.params.id); return res.status(httpStatus.OK).json({ @@ -52,17 +52,17 @@ const updateUserRole = async (req: Request, res: Response) => { const updateUserStatus = async (req: Request, res: Response): Promise => { try { - const userId: number = Number(req.params.id); + const userId: string = req.params.id; const data = await authRepositories.updateUserByAttributes("status", req.body.status, "id", userId); res.status(httpStatus.OK).json({ message: "Status updated successfully.", data }); } catch (error) { res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ status: httpStatus.INTERNAL_SERVER_ERROR, message: error.message }); } }; -const getUserDetails = async(req:Request,res:Response)=>{ +const getUserDetails = async (req: Request, res: Response) => { try { - const user = await authRepositories.findUserByAttributes("id", req.user.id); - res.status(httpStatus.OK).json({status: httpStatus.OK,data:{user:user}}); + const user = await authRepositories.findUserByAttributes("id", req.user.id); + res.status(httpStatus.OK).json({ status: httpStatus.OK, data: { user: user } }); } catch (error) { res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ status: httpStatus.INTERNAL_SERVER_ERROR, message: error.message }) } @@ -70,14 +70,14 @@ const getUserDetails = async(req:Request,res:Response)=>{ const updateUserProfile = async (req: Request, res: Response) => { try { - const upload = await uploadImages(req.file); - const userData = { ...req.body, profilePicture:upload.secure_url }; - const user = await userRepositories.updateUserProfile(userData, Number(req.user.id)); - res.status(httpStatus.OK).json({status:httpStatus.OK, data:{user:user}}); + const upload = await uploadImages(req.file); + const userData = { ...req.body, profilePicture: upload.secure_url }; + const user = await userRepositories.updateUserProfile(userData, req.user.id); + res.status(httpStatus.OK).json({ status: httpStatus.OK, data: { user: user } }); } catch (error) { - res.status(httpStatus.INTERNAL_SERVER_ERROR).json({status:httpStatus.INTERNAL_SERVER_ERROR, error: error.message}); + res.status(httpStatus.INTERNAL_SERVER_ERROR).json({ status: httpStatus.INTERNAL_SERVER_ERROR, error: error.message }); } } -export default { updateUserStatus, updateUserRole, adminGetUsers , adminGetUser,updateUserProfile ,getUserDetails}; \ No newline at end of file +export default { updateUserStatus, updateUserRole, adminGetUsers, adminGetUser, updateUserProfile, getUserDetails }; \ No newline at end of file diff --git a/src/modules/user/repository/userRepositories.ts b/src/modules/user/repository/userRepositories.ts index 90d0906b..1d375416 100644 --- a/src/modules/user/repository/userRepositories.ts +++ b/src/modules/user/repository/userRepositories.ts @@ -5,7 +5,7 @@ const getAllUsers = async () => { return Users.findAll(); } -const updateUserProfile = async (user: any, id:number) => { +const updateUserProfile = async (user: any, id:string) => { await Users.update({...user},{where:{id},returning:true}) const updateUser = await Users.findOne({where:{id}}) return updateUser; diff --git a/src/modules/user/test/user.spec.ts b/src/modules/user/test/user.spec.ts index 6a53d9e3..bb4dc9c3 100644 --- a/src/modules/user/test/user.spec.ts +++ b/src/modules/user/test/user.spec.ts @@ -6,6 +6,7 @@ import chai, { expect } from "chai"; import chaiHttp from "chai-http"; import sinon, { SinonStub } from "sinon"; import httpStatus from "http-status"; +import { v4 as uuidv4 } from "uuid"; import app from "../../../index"; import Users from "../../../databases/models/users"; import authRepositories from "../../auth/repository/authRepositories" @@ -15,6 +16,8 @@ import path from "path"; import fs from 'fs' import uploadImages from "../../../helpers/uploadImage"; import { v2 as cloudinary } from "cloudinary"; +import Shop from "../../../databases/models/shops"; +import collection from "../../../databases/models/collection"; const imagePath = path.join(__dirname, "../test/testImage.jpg"); const imageBuffer = fs.readFileSync(imagePath) @@ -26,8 +29,8 @@ describe("Update User Status test case ", () => { let getUserStub: sinon.SinonStub; let updateUserStub: sinon.SinonStub; const testUserId = 1; - let userId: number = null; - const unknownId = 100; + let userId: string = null; + const unknownId: string = "000d0b18-ac99-0dcc-ba34-027ae72c6c00"; let token it("should register a new user", (done) => { @@ -50,8 +53,8 @@ describe("Update User Status test case ", () => { router() .post("/api/auth/login") .send({ - email:"admin@gmail.com", - password:"$321!Pass!123$" + email: "admin@gmail.com", + password: "$321!Pass!123$" }) .end((error, response) => { expect(response.status).to.equal(httpStatus.OK); @@ -162,7 +165,7 @@ describe("User Repository Functions", () => { describe("Admin update User roles", () => { - let userIdd: number ; + let userIdd: string; let token = null; it("should register a new user", (done) => { @@ -186,8 +189,8 @@ describe("Admin update User roles", () => { router() .post("/api/auth/login") .send({ - email:"admin@gmail.com", - password:"$321!Pass!123$" + email: "admin@gmail.com", + password: "$321!Pass!123$" }) .end((error, response) => { expect(response.status).to.equal(httpStatus.OK); @@ -247,15 +250,15 @@ describe("Admin update User roles", () => { it("Should return 404 if user is not found", (done) => { - router().put("/api/user/admin-update-role/10001") - .send({ role: "admin" }) - .set("authorization", `Bearer ${token}`) - .end((err, res) => { - expect(res).to.have.status(httpStatus.NOT_FOUND); - expect(res.body).to.be.an("object"); - expect(res.body).to.have.property("message", "User not found") - done(err) - }) + router().put("/api/user/admin-update-role/00004a00-1f61-4000-a96a-bb0a1c0fe0ce") + .send({ role: "admin" }) + .set("authorization", `Bearer ${token}`) + .end((err, res) => { + expect(res).to.have.status(httpStatus.NOT_FOUND); + expect(res.body).to.be.an("object"); + expect(res.body).to.have.property("message", "User not found") + done(err) + }) }) @@ -264,8 +267,8 @@ describe("Admin update User roles", () => { describe("Middleware: isUsersExist", () => { it("should call next if users exist", async () => { const userCountStub = sinon.stub(Users, "count").resolves(1); - const req: any = {} ; - const res: any = {} ; + const req: any = {}; + const res: any = {}; const next = sinon.spy(); await isUsersExist(req, res, next); @@ -276,11 +279,11 @@ describe("Middleware: isUsersExist", () => { it("should return 404 if no users exist", async () => { const userCountStub = sinon.stub(Users, "count").resolves(0); - const req: any = {} ; + const req: any = {}; const res: any = { status: sinon.stub().returnsThis(), json: sinon.spy() - } ; + }; const next = sinon.spy(); await isUsersExist(req, res, next); @@ -293,11 +296,11 @@ describe("Middleware: isUsersExist", () => { it("should return 500 if there is an error", async () => { const userCountStub = sinon.stub(Users, "count").throws(new Error("DB error")); - const req: any = {} ; + const req: any = {}; const res: any = { status: sinon.stub().returnsThis(), json: sinon.spy() - } ; + }; const next = sinon.spy(); await isUsersExist(req, res, next); @@ -309,6 +312,12 @@ describe("Middleware: isUsersExist", () => { describe("Admin Controllers", () => { after(async () => { + await collection.destroy({ + where: {} + }); + await Shop.destroy({ + where: {} + }); await Users.destroy({ where: { role: { @@ -318,14 +327,14 @@ describe("Admin Controllers", () => { }); }); let tokens: string = null; - let id:number =null; - let userId:number; + let id: number = null; + let userId: string; it("Should be able to login a registered user", (done) => { router() .post("/api/auth/login") .send({ - email:"admin@gmail.com", - password:"$321!Pass!123$" + email: "admin@gmail.com", + password: "$321!Pass!123$" }) .end((error, response) => { expect(response.status).to.equal(httpStatus.OK); @@ -334,150 +343,157 @@ describe("Admin Controllers", () => { expect(response.body.message).to.be.a("string"); expect(response.body.data).to.have.property("token"); tokens = response.body.data.token; - id=response.body.data.id; + id = response.body.data.id; done(error); }); }); it("should return all users", (done) => { router() - .get("/api/user/admin-get-users") - .set("authorization", `Bearer ${tokens}`) - .end((error, response) => { - userId = response.body.data[0].id; - - expect(response.status).to.equal(httpStatus.OK); - expect(response.body).to.be.an("object"); - done(error) - }); + .get("/api/user/admin-get-users") + .set("authorization", `Bearer ${tokens}`) + .end((error, response) => { + userId = response.body.data[0].id; + + expect(response.status).to.equal(httpStatus.OK); + expect(response.body).to.be.an("object"); + done(error) + }); }); it("should return one user", (done) => { router() - .get(`/api/user/admin-get-user/${userId}`) - .set("authorization", `Bearer ${tokens}`) - .end((error, response) => { - expect(response.status).to.equal(httpStatus.OK); - expect(response.body).to.be.an("object"); - done(error) - }); + .get(`/api/user/admin-get-user/${userId}`) + .set("authorization", `Bearer ${tokens}`) + .end((error, response) => { + expect(response.status).to.equal(httpStatus.OK); + expect(response.body).to.be.an("object"); + done(error) + }); }); }); describe("updateUserProfile", () => { - let profileId :number = null; -let token - -it("should register a new user", (done) => { -router() - .post("/api/auth/register") - .send({ - email: "salt23@gmail.com", - password: "userPassword@123" - }) - .end((error, response) => { - expect(response.status).to.equal(httpStatus.CREATED); - expect(response.body).to.be.an("object"); - expect(response.body).to.have.property("data"); - profileId = response.body.data.user.id; - expect(response.body).to.have.property("message", "Account created successfully. Please check email to verify account."); - done(error); + let profileId: string = null; + let token + + it("should register a new user", (done) => { + router() + .post("/api/auth/register") + .send({ + email: "salt23@gmail.com", + password: "userPassword@123" + }) + .end((error, response) => { + expect(response.status).to.equal(httpStatus.CREATED); + expect(response.body).to.be.an("object"); + expect(response.body).to.have.property("data"); + profileId = response.body.data.user.id; + expect(response.body).to.have.property("message", "Account created successfully. Please check email to verify account."); + done(error); + }); }); -}); -it("Should be able to login a registered user", (done) => { - router() - .post("/api/auth/login") - .send({ - email: "salt23@gmail.com", - password: "userPassword@123" - }) - .end((error, response) => { - expect(response.status).to.equal(httpStatus.OK); - expect(response.body).to.be.a("object"); - expect(response.body).to.have.property("data"); - expect(response.body.message).to.be.a("string"); - expect(response.body.data).to.have.property("token"); - token = response.body.data.token; - done(error); - }); -}); + it("Should be able to login a registered user", (done) => { + router() + .post("/api/auth/login") + .send({ + email: "salt23@gmail.com", + password: "userPassword@123" + }) + .end((error, response) => { + expect(response.status).to.equal(httpStatus.OK); + expect(response.body).to.be.a("object"); + expect(response.body).to.have.property("data"); + expect(response.body.message).to.be.a("string"); + expect(response.body.data).to.have.property("token"); + token = response.body.data.token; + done(error); + }); + }); -it("Should be able to get profile", (done) => { -router() - .get(`/api/user/user-get-profile/`) - .set("authorization", `Bearer ${token}`) - .end((error, response) => { - expect(response).to.have.status(200); - expect(response.body).to.be.a("object"); - done(error); + it("Should be able to get profile", (done) => { + router() + .get(`/api/user/user-get-profile/`) + .set("authorization", `Bearer ${token}`) + .end((error, response) => { + expect(response).to.have.status(200); + expect(response.body).to.be.a("object"); + done(error); + }); }); -}); -it("should update profile ", (done) => { - router().put(`/api/user/user-update-profile/`) - .set("Authorization", `Bearer ${token}`) - .field('firstName', 'MANISHIMWE') - .field('lastName', 'Salton Joseph') - .field('phone', '787312593') - .field('gender', 'male') - .field('birthDate', '1943-02-04') - .field('language', 'english') - .field('currency', 'USD') - .attach("profilePicture",imageBuffer,'testImage.jpg') - .end((error, response) => { - - expect(response.status).to.equal(200); - done(error); + it("should update profile ", (done) => { + router().put(`/api/user/user-update-profile/`) + .set("Authorization", `Bearer ${token}`) + .field('firstName', 'MANISHIMWE') + .field('lastName', 'Salton Joseph') + .field('phone', '787312593') + .field('gender', 'male') + .field('birthDate', '1943-02-04') + .field('language', 'english') + .field('currency', 'USD') + .attach("profilePicture", imageBuffer, 'testImage.jpg') + .end((error, response) => { + + expect(response.status).to.equal(200); + done(error); + }); }); -}); -describe('uploadImages', () => { - let uploadStub: sinon.SinonStub; + describe('uploadImages', () => { + let uploadStub: sinon.SinonStub; - beforeEach(() => { - uploadStub = sinon.stub(cloudinary.uploader, 'upload'); - }); + beforeEach(() => { + uploadStub = sinon.stub(cloudinary.uploader, 'upload'); + }); - afterEach(() => { - uploadStub.restore(); - }); + afterEach(() => { + uploadStub.restore(); + }); - it('should upload an image and return the public_id and secure_url', async () => { - const fileToUpload = { path: 'path/to/file.jpg' }; - const mockResult = { - public_id: 'mock_public_id', - secure_url: 'https://mock_secure_url.com', - }; + it('should upload an image and return the public_id and secure_url', async () => { + const fileToUpload = { path: 'path/to/file.jpg' }; + const mockResult = { + public_id: 'mock_public_id', + secure_url: 'https://mock_secure_url.com', + }; - uploadStub.resolves(mockResult); + uploadStub.resolves(mockResult); - const result = await uploadImages(fileToUpload); + const result = await uploadImages(fileToUpload); - expect(uploadStub.calledOnceWith(fileToUpload.path)).to.be.true; - expect(result).to.deep.equal(mockResult); - }); + expect(uploadStub.calledOnceWith(fileToUpload.path)).to.be.true; + expect(result).to.deep.equal(mockResult); + }); - it('should handle errors from the upload process', async () => { - const fileToUpload = { path: 'path/to/file.jpg' }; - const mockError = new Error('Upload failed'); + it('should handle errors from the upload process', async () => { + const fileToUpload = { path: 'path/to/file.jpg' }; + const mockError = new Error('Upload failed'); - uploadStub.rejects(mockError); + uploadStub.rejects(mockError); - try { - await uploadImages(fileToUpload); - expect.fail('Expected error was not thrown'); - } catch (error) { - expect(error).to.be.an('error'); - expect(error.message).to.equal('Upload failed'); - } - }); + try { + await uploadImages(fileToUpload); + expect.fail('Expected error was not thrown'); + } catch (error) { + expect(error).to.be.an('error'); + expect(error.message).to.equal('Upload failed'); + } + }); - after(async () => { - await Users.destroy({ - where: {} - }) - }); + after(async () => { + await collection.destroy({ + where: {} + }); + await Shop.destroy({ + where: {} + }); + await Users.destroy({ + where: {} + }); -}); + }); + + }); }) \ No newline at end of file diff --git a/src/types/index.d.ts b/src/types/index.d.ts index b76255d6..e3f0a25f 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -47,7 +47,7 @@ export interface IProduct { export interface ICollection { id: number; - sellerId: number; + shopId: number; name: string; description?: string; } diff --git a/src/types/uuid.ts b/src/types/uuid.ts new file mode 100644 index 00000000..0e20c311 --- /dev/null +++ b/src/types/uuid.ts @@ -0,0 +1,22 @@ +import { v4 as uuidv4 } from "uuid"; + +export const userOneId = uuidv4(); +export const userTwoId = uuidv4(); +export const userThreeId = uuidv4(); +export const userFourId = uuidv4(); + +export const collectionOneId = uuidv4(); +export const collectionTwoId = uuidv4(); + +export const shopOneId = uuidv4(); + +export const productOneId = uuidv4(); +export const productTwoId = uuidv4(); + +export const orderOneId = uuidv4(); +export const orderTwoId = uuidv4(); + +export const orderProductOneId = uuidv4(); +export const orderProductTwoId = uuidv4(); +export const orderProductThreeId = uuidv4(); +export const orderProductFourId = uuidv4(); \ No newline at end of file