Skip to content

Commit

Permalink
* feat(rbac): Implement role based access control
Browse files Browse the repository at this point in the history
-define roles and permissions for vendors and buyers
-assign roles and permissions to users during registration or profile update
-enforce role-based access control throughout the application
-write comprehensive unit tests

[Delivers #34]

* feat(rbac): integrate rbac into user registration

-integrate role based access control into user registration

[Delivers #34]

* feat(rbac): integrate rbac into user registration

-integrate role based access control into user registration

[Delivers #34]

---------

Co-authored-by: ambroisegithub <muhayimana21@gmail.com>

Social Logins (#45)

* squashing commits

implementing routes for auth

create passport callback function

adding new user from Google

creating new user

check if user is exist in db

implementing cookie session

Fix error of TypeError: req.session.regenerate is not a function using Passport

fix secret keys

remove Google client secret keys

working on facebook strategy

get email from fb login and update the scope

after verification save the user into db

add profile image in db

fixing minor bugs

fix minor bugs in codes

after rebasing & updating some fts

link social login with userModel

Addong Google client keys & FB client key into yml

send confrim email after register a new user

send email after register from facebook

fix minor bugs

* fix minor errors

* remove lints errors

user register

register user test

register user testing fix

register user testing fix

register user testing fix

Authentication for User

Added slint changes

removed  mocha

 added new features

 added new features

Solved comflicts

changed file

added changes

added new Test

added new Test

resolved test cases

resolved test cases

implemented two-factor authentication for enhanced security

implemented two-factor authentication for enhanced security

check whether the usertype is vendor to proceed with 2FA

test the 2fa authentication

Design the database schema for storing seller products and related information

create endpoints for category and also database schema

fix routes for products & categories

implement CRUD operations for category entity

create swagger docs for category routes

adds delete  documentation for category routes

complete documentation for category routes

implementing craate new product route and its controller

implementing get product route and its controller

working on update function

Extend API endpoints

store reference ID of vendor

ft-Product-Docs

This PR add the product swagger docs and some test category

bug-documentation-fixes

Fixing the errors on the doumentation

add new tests for buyers login
  • Loading branch information
wayneleon1 committed May 17, 2024
2 parents 9a140f2 + 87b2694 commit a21cc7f
Show file tree
Hide file tree
Showing 29 changed files with 2,489 additions and 241 deletions.
601 changes: 591 additions & 10 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"build": "tsc",
"lint": "eslint --config .eslintrc.json .",
"format": "prettier --write .",
"test": "jest --no-cache",
"test:ci": "jest --coverage"
"test": "jest --no-cache --detectOpenHandles",
"test:ci": "jest --coverage --detectOpenHandles"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -40,6 +40,7 @@
"jest": "^29.7.0",
"joi": "^17.13.1",
"jsonwebtoken": "^9.0.2",
"mailgun-js": "^0.22.0",
"morgan": "^1.10.0",
"nodemailer": "^6.9.13",
"nodemon": "^3.1.0",
Expand All @@ -65,12 +66,14 @@
]
},
"devDependencies": {
"@types/bcrypt": "^5.0.2",
"@types/bcryptjs": "^2.4.6",
"@types/cookie-session": "^2.0.49",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jest": "^29.5.12",
"@types/jsonwebtoken": "^9.0.6",
"@types/mailgun-js": "^0.22.18",
"@types/morgan": "^1.9.9",
"@types/nodemailer": "^6.4.15",
"@types/passport": "^1.0.16",
Expand Down
183 changes: 183 additions & 0 deletions src/__test__/category.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import request from 'supertest';
import app from '../app';
import { afterAllHook, beforeAllHook, getVendorToken } from './testSetup';

beforeAll(beforeAllHook);
afterAll(afterAllHook);

describe('Category Creation Tests', () => {
beforeAll(async () => {
token = await getVendorToken();
});
let token: string;
let categoryId: number;

it('should create a new category with valid data', async () => {
const categoryData = {
name: 'Test Category',
description: 'Test category description',
};

const response = await request(app)
.post('/api/v1/category')
.set('Authorization', `Bearer ${token}`)
.send(categoryData);
expect(response.status).toBe(201);
expect(response.body.message).toBe('Category successfully created');
expect(response.body.data).toHaveProperty('id');
expect(response.body.data).toHaveProperty('name', categoryData.name);
expect(response.body.data).toHaveProperty(
'description',
categoryData.description
);
categoryId = response.body.data.id;
});

it('should return a 400 status code if name is missing', async () => {
const invalidData = {
description: 'Test category description',
};

const response = await request(app)
.post('/api/v1/category')
.set('Authorization', `Bearer ${token}`)
.send(invalidData);

expect(response.status).toBe(400);
expect(response.body.errors[0].msg).toBe('Category name is required');
});

it('should return 400 if request data is invalid', async () => {
const invalidData = {};

const response = await request(app)
.put(`/api/v1/category/${categoryId}`)
.set('Authorization', `Bearer ${token}`)
.send(invalidData);

expect(response.status).toBe(400);
expect(response.body.errors).toBeDefined();
});

it('should return a 409 status code if category name already exists', async () => {
const existingCategoryData = {
name: 'Existing Category',
description: 'Existing category description',
};
await request(app)
.post('/api/v1/category')
.set('Authorization', `Bearer ${token}`)
.send(existingCategoryData);

const newCategoryData = {
name: 'Existing Category',
description: 'Existing category description',
};
const response = await request(app)
.post('/api/v1/category')
.set('Authorization', `Bearer ${token}`)
.send(newCategoryData);

expect(response.status).toBe(409);
expect(response.body.message).toBe('Category name already exists');
});

it('should return all categories with status 200', async () => {
const response = await request(app).get('/api/v1/category');
expect(response.status).toBe(200);
expect(response.body.message).toBe('Data retrieved successfully');
expect(response.body.data).toBeDefined;
});

it('should return a category by ID with status 200', async () => {
const response = await request(app).get(`/api/v1/category/${categoryId}`);

expect(response.status).toBe(200);
expect(response.body.message).toBe('Data retrieved successfully');
expect(response.body.data).toBeDefined;
});

it('should return 404 if category is not found', async () => {
const nonExistentCategoryId = 9999;

const response = await request(app).get(
`/api/v1/category/${nonExistentCategoryId}`
);

expect(response.status).toBe(404);
expect(response.body.message).toBe('Category Not Found');
});

it('should update the category with status 200', async () => {
const updatedCategoryData = {
name: 'Updated Category Name',
description: 'Updated category description',
};

const response = await request(app)
.put(`/api/v1/category/${categoryId}`)
.set('Authorization', `Bearer ${token}`)
.send(updatedCategoryData);

expect(response.status).toBe(200);
expect(response.body.message).toBe('Category successfully updated');
expect(response.body.data.name).toBe(updatedCategoryData.name);
expect(response.body.data.description).toBe(
updatedCategoryData.description
);
});

it('should return a 409 status code if category update name already exists', async () => {
const existingCategoryData = {
name: 'Existing Category',
description: 'Existing category description',
};
await request(app)
.post('/api/v1/category')
.set('Authorization', `Bearer ${token}`)
.send(existingCategoryData);

const updateCategoryData = {
name: 'Existing Category',
description: 'Existing category description',
};
const response = await request(app)
.put(`/api/v1/category/${categoryId}`)
.set('Authorization', `Bearer ${token}`)
.send(updateCategoryData);

expect(response.status).toBe(409);
expect(response.body.message).toBe('Category name already exists');
});

it('should return 404 if category is not found', async () => {
const response = await request(app)
.put('/api/v1/category/9999')
.set('Authorization', `Bearer ${token}`)
.send({
name: 'Updated Category Name',
description: 'Updated category description',
});

expect(response.status).toBe(404);
expect(response.body.message).toBe('Category Not Found');
});

it('should delete the category with status 200', async () => {
const response = await request(app)
.delete(`/api/v1/category/${categoryId}`)
.set('Authorization', `Bearer ${token}`);

expect(response.status).toBe(200);
expect(response.body.message).toBe('Category deleted successfully');
});

it('should return 404 if category is not found', async () => {
const response = await request(app)
.delete('/api/v1/category/9999')
.set('Authorization', `Bearer ${token}`);

expect(response.status).toBe(404);
expect(response.body.message).toBe('Category Not Found');
});
});
Loading

0 comments on commit a21cc7f

Please sign in to comment.