-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented user registration feature with input validation, password…
… hashing, and database integration fix(user registration): resolve registration bug - ensure that a user provide neccessary inputs - restructure user entity - refactor other codes depending on user registration logic [Fixes #39] rebasing from develop , adding verifie route and service and send email to the user rebasing from develop , adding verifie route and service and send email to the user
- Loading branch information
1 parent
618cb5c
commit 2abbc37
Showing
23 changed files
with
520 additions
and
74 deletions.
There are no files selected for viewing
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,13 +1,20 @@ | ||
PORT= ******************************** | ||
APP_ENV= ******************************** | ||
PDN_DB_NAME= ***************************** | ||
|
||
TEST_DB_HOST= ******************************** | ||
TEST_DB_PORT= ******************************** | ||
TEST_DB_USER= ******************************** | ||
TEST_DB_PASS= ******************************** | ||
TEST_DB_NAME= ******************************** | ||
|
||
DEV_DB_HOST= ******************************** | ||
DEV_DB_PORT= ******************************** | ||
DEV_DB_USER= ******************************** | ||
DEV_DB_PASS= ***************************** | ||
DEV_DB_TYPE= ******************************* | ||
DEV_DB_NAME= ******************************* | ||
|
||
PDN_DB_HOST= ******************************** | ||
PDN_DB_PORT= ******************************** | ||
PDN_DB_USER= ******************************** | ||
PDN_DB_PASS= ******************************** | ||
PDN_DB_PASS= ******************************** | ||
PDN_DB_NAME= ***************************** |
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 |
---|---|---|
|
@@ -5,4 +5,4 @@ package-lock.json | |
coverage/ | ||
dist | ||
/src/logs | ||
.DS_Stor | ||
.DS_Store |
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,29 @@ | ||
import { MigrationInterface, QueryRunner } from 'typeorm'; | ||
|
||
export class CreateUserMigration1614495123940 implements MigrationInterface { | ||
public async up (queryRunner: QueryRunner): Promise<void> { | ||
await queryRunner.query(` | ||
CREATE TABLE "user" ( | ||
"id" uuid NOT NULL DEFAULT uuid_generate_v4(), | ||
"firstName" character varying NOT NULL, | ||
"lastName" character varying NOT NULL, | ||
"email" character varying NOT NULL, | ||
"password" character varying NOT NULL, | ||
"gender" character varying NOT NULL, | ||
"phoneNumber" character varying NOT NULL, | ||
"photoUrl" character varying, | ||
"verified" boolean NOT NULL, | ||
"status" character varying NOT NULL CHECK (status IN ('active', 'suspended')), | ||
"userType" character varying NOT NULL DEFAULT 'Buyer' CHECK (userType IN ('Admin', 'Buyer', 'Vendor')), | ||
"createdAt" TIMESTAMP NOT NULL DEFAULT now(), | ||
"updatedAt" TIMESTAMP NOT NULL DEFAULT now(), | ||
CONSTRAINT "UQ_e12875dfb3b1d92d7d7c5377e22" UNIQUE ("email"), | ||
CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id") | ||
) | ||
`); | ||
} | ||
|
||
public async down (queryRunner: QueryRunner): Promise<void> { | ||
await queryRunner.query(`DROP TABLE "user"`); | ||
} | ||
} |
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,24 +1,39 @@ | ||
module.exports = { | ||
"type": "postgres", | ||
"host": `${process.env.DEV_DB_HOST}`, | ||
"port": `${process.env.DEV_DB_PORT}`, | ||
"username": `${process.env.DEV_DB_USER}`, | ||
"password": `${process.env.DEV_DB_PASS}`, | ||
"database": `${process.env.DEV_DB_NAME}`, | ||
"synchronize": true, | ||
"logging": false, | ||
"entities": [ | ||
"src/entities/**/*.ts" | ||
], | ||
"migrations": [ | ||
"src/migrations/**/*.ts" | ||
], | ||
"subscribers": [ | ||
"src/subscribers/**/*.ts" | ||
], | ||
"cli": { | ||
"entitiesDir": "src/entities", | ||
"migrationsDir": "src/migrations", | ||
"subscribersDir": "src/subscribers" | ||
} | ||
}; | ||
const devConfig = { | ||
type: 'postgres', | ||
host: process.env.DEV_DB_HOST, | ||
port: process.env.DEV_DB_PORT, | ||
username: process.env.DEV_DB_USER, | ||
password: process.env.DEV_DB_PASS, | ||
database: process.env.DEV_DB_NAME, | ||
synchronize: true, | ||
logging: false, | ||
entities: ['src/entities/**/*.ts'], | ||
migrations: ['src/migrations/**/*.ts'], | ||
subscribers: ['src/subscribers/**/*.ts'], | ||
cli: { | ||
entitiesDir: 'src/entities', | ||
migrationsDir: 'src/migrations', | ||
subscribersDir: 'src/subscribers', | ||
}, | ||
}; | ||
|
||
const testConfig = { | ||
type: 'postgres', | ||
host: process.env.TEST_DB_HOST, | ||
port: process.env.TEST_DB_PORT, | ||
username: process.env.TEST_DB_USER, | ||
password: process.env.TEST_DB_PASS, | ||
database: process.env.TEST_DB_NAME, | ||
synchronize: true, | ||
logging: false, | ||
entities: ['src/entities/**/*.ts'], | ||
migrations: ['src/migrations/**/*.ts'], | ||
subscribers: ['src/subscribers/**/*.ts'], | ||
cli: { | ||
entitiesDir: 'src/entities', | ||
migrationsDir: 'src/migrations', | ||
subscribersDir: 'src/subscribers', | ||
}, | ||
}; | ||
|
||
module.exports = process.env.NODE_ENV === 'test' ? testConfig : devConfig; |
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,24 +1,118 @@ | ||
import request from 'supertest'; | ||
import { app, server } from '../index'; // update this with the path to your app file | ||
|
||
import { createConnection, getConnection, getConnectionOptions } from 'typeorm'; | ||
import { app, server } from '../index'; | ||
import { createConnection, getConnection, getConnectionOptions, getRepository } from 'typeorm'; | ||
import { User } from '../entities/User'; | ||
|
||
beforeAll(async () => { | ||
// Connect to the test database | ||
const connectionOptions = await getConnectionOptions(); | ||
|
||
await createConnection({ ...connectionOptions, name: 'testConnection' }); | ||
}); | ||
|
||
afterAll(async () => { | ||
await getConnection('testConnection').close(); | ||
const connection = getConnection('testConnection'); | ||
const userRepository = connection.getRepository(User); | ||
|
||
// Delete all records from the User | ||
await userRepository.clear(); | ||
|
||
// Close the connection to the test database | ||
await connection.close(); | ||
|
||
server.close(); | ||
}); | ||
|
||
describe('GET /', () => { | ||
// afterAll(done => { | ||
// server.close(done); | ||
// }); | ||
it('This is a testing route that returns', done => { | ||
request(app) | ||
.get('/api/v1/status') | ||
.expect(200) | ||
.expect('Content-Type', /json/) | ||
.expect( | ||
{ | ||
status: 'success', | ||
data: { | ||
code: 200, | ||
message: 'This is a testing route.', | ||
}, | ||
}, | ||
done | ||
); | ||
}); | ||
}); | ||
describe('POST /user/register', () => { | ||
it('should register a new user', async () => { | ||
// Arrange | ||
const newUser = { | ||
firstName: 'John', | ||
lastName: 'Doe', | ||
email: '[email protected]', | ||
password: 'password', | ||
gender: 'Male', | ||
phoneNumber: '123678116', | ||
userType: 'Buyer', | ||
photoUrl: 'https://example.com/photo.jpg', | ||
}; | ||
|
||
it('responds with "Knights Ecommerce API"', done => { | ||
request(app).get('/').expect(200, 'Knights Ecommerce API', done); | ||
// Act | ||
const res = await request(app).post('/user/register').send(newUser); | ||
console.log(res.body); | ||
// Assert | ||
expect(res.status).toBe(201); | ||
expect(res.body).toEqual({ | ||
status: 'success', | ||
data: { | ||
code: 201, | ||
message: 'User registered successfully', | ||
}, | ||
}); | ||
|
||
// Clean up: delete the test user | ||
const userRepository = getRepository(User); | ||
const user = await userRepository.findOne({ where: { email: newUser.email } }); | ||
if (user) { | ||
await userRepository.remove(user); | ||
} | ||
}); | ||
}); | ||
describe('POST /user/verify/:id', () => { | ||
it('should verify a user', async () => { | ||
// Arrange | ||
const newUser = { | ||
firstName: 'John', | ||
lastName: 'Doe', | ||
email: '[email protected]', | ||
password: 'password', | ||
gender: 'Male', | ||
phoneNumber: '123456789', | ||
userType: 'Buyer', | ||
photoUrl: 'https://example.com/photo.jpg', | ||
}; | ||
|
||
// Create a new user | ||
const res = await request(app).post('/user/register').send(newUser); | ||
Check warning on line 94 in src/__test__/route.test.ts GitHub Actions / build-lint-test-coverage
|
||
|
||
const userRepository = getRepository(User); | ||
const user = await userRepository.findOne({ where: { email: newUser.email } }); | ||
|
||
if(user){ | ||
const verifyRes = await request(app).get(`/user/verify/${user.id}`); | ||
|
||
// Assert | ||
expect(verifyRes.status).toBe(200); | ||
expect(verifyRes.text).toEqual('<p>User verified successfully</p>'); | ||
|
||
// Check that the user's verified field is now true | ||
const verifiedUser = await userRepository.findOne({ where: { email: newUser.email } }); | ||
if (verifiedUser){ | ||
expect(verifiedUser.verified).toBe(true); | ||
} | ||
|
||
} | ||
|
||
if (user) { | ||
await userRepository.remove(user); | ||
} | ||
}); | ||
}); |
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,15 @@ | ||
import { Request, Response } from 'express'; | ||
import { User } from '../entities/User'; | ||
Check warning on line 2 in src/controllers/authController.ts GitHub Actions / build-lint-test-coverage
|
||
import bcrypt from 'bcrypt'; | ||
Check warning on line 3 in src/controllers/authController.ts GitHub Actions / build-lint-test-coverage
|
||
import { getRepository } from 'typeorm'; | ||
Check warning on line 4 in src/controllers/authController.ts GitHub Actions / build-lint-test-coverage
|
||
import { responseError, responseServerError, responseSuccess } from '../utils/response.utils'; | ||
import { validate } from 'class-validator'; | ||
import { userVerificationService, userRegistrationService } from '../services'; | ||
|
||
export const userRegistration = async (req: Request, res: Response) => { | ||
await userRegistrationService(req, res); | ||
} | ||
export const userVerification = async (req: Request, res: Response) => { | ||
await userVerificationService(req, res); | ||
} | ||
|
Oops, something went wrong.