From df50bd9078d2754ecfdff5a05c1aea84c2f1cf2b Mon Sep 17 00:00:00 2001 From: Tony Dim Date: Sat, 23 Sep 2023 15:35:41 -0400 Subject: [PATCH] testing controllers --- tests/authController.test.js | 174 +++++++++++++++++++++++++ tests/createPasswordController.test.js | 55 ++++++++ tests/lunchController.test.js | 113 ++++++++++++++++ tests/organizationController.test.js | 119 +++++++++++++++++ tests/withdrawalController.test.js | 56 ++++++++ 5 files changed, 517 insertions(+) create mode 100644 tests/authController.test.js create mode 100644 tests/createPasswordController.test.js create mode 100644 tests/lunchController.test.js create mode 100644 tests/organizationController.test.js create mode 100644 tests/withdrawalController.test.js diff --git a/tests/authController.test.js b/tests/authController.test.js new file mode 100644 index 00000000..c381bac9 --- /dev/null +++ b/tests/authController.test.js @@ -0,0 +1,174 @@ +require('dotenv').config(); +const request = require('supertest'); +const sequelize = require('../db/db'); +const app = require('../app'); + +beforeAll(async () => { + try { + await sequelize.sync(); + } catch (error) { + console.error('Database sync error', error); + } +}); + +describe('Email Validation API', () => { + it('should validate an email address', async () => { + const validEmail = 'testemail@example.com'; + const response = await request(app) + .post('/api/auth/validate') + .send({email: validEmail}); + + expect(response.status).toEqual(200); + }); + + it('should reject an invalid email address', async () => { + const invalidEmail = 'invalid-email'; + const response = await request(app) + .post('/api/auth/validate') + .send({ email: invalidEmail }); + + expect(response.status).toEqual(400); + }) +}) + + +describe ('Create User API', () => { + it('should create a new user', async () => { + const newUser = { + first_name: 'test', + last_name: 'create', + email: 'testcreate@example.com', + phone: '02012345678', + password: 'testpassword_hash', + is_admin: false, + profile_pic: 'https://cdn-icons-png.flaticon.com/512/147/147142.png', + org_id: 976542562576, + lunch_credit_balance: 1000, + bank_code: '100011', + bank_name: 'KeyStone', + bank_number: '9292929292' + }; + const response = await request(app) + .post('/api/auth/signup') + .send({user: newUser}); + expect(response.status).toEqual(200); + expect(response.body.data).toMatchObject(newUser); + }); + + it('should return a 400 error for missing data', async () => { + const newUser = { + first_name: 'test' + }; // Missing required params last_name through to bank_name + const response = await request(app) + .post('/api/auth/signup') + .send({user: newUser}); + + expect(response.status).toEqual(400); + }); +}); + +describe('User Login API', () => { + it('should allow a valid user to login', async () => { + const user = { + email: 'testemail@example.com', + password: 'testpassword_hash' + }; + const response = await request(app) + .post('/api/auth/login') + .send(user); + + expect(response.status).toEqual(200); + expect(response.body).toHaveProperty('message', 'User authenticated sucessfully'); + }); + + it('should return a 400 error for missing data', async () => { + const user = { + email: 'testemail@example.com' + }; // Missing 'password' + const response = await request(app) + .post('/api/auth/login') + .send(user); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message', 'Fill all required fields'); + }); + + it('should return a 404 error for invalid credentials', async () => { + const user = { + email: 'invalidemail@example.com', + password: 'password_hash' + }; // email does not exist in DB + const response = await request(app) + .post('/api/auth/login') + .send(user); + + expect(response.status).toEqual(404); + expect(response.body).toHaveProperty('message', 'Invalid credentials'); + }); + + it('should return a 401 error for invalid password', async () => { + const user = { + email: 'testemail@example.com', + password: 'invalidPassword_hash' + }; // password does not exist nor correlate with DB + const response = await request(app) + .post('/api/auth/login') + .send(user); + + expect(response.status).toEqual(401); + expect(response.body).toHaveProperty('message', 'Invalid credentials'); + }); +}); + +describe('Logout API', () => { + it('should allow an authenticated user to log out', async () => { + const token = 'userToken'; + const response = await request(app) + .post('/api/auth/logout') + .set('token', token); + + expect(response.status).toEqual(200); + expect(response.body).toHaveProperty('message', 'User logged out successfully'); + }); + + it('should return a 401 error for missing token', async () => { + const response = await request(app) + .post('/api/auth/logout'); + + expect(response.status).toBe(401); + expect(response.body).toHaveProperty('message', 'Token is missing'); + }); +}); + +describe('Create Org and User API', () => { + it('should create an organization and admin user', async () => { + const adminUser = { + first_name: 'adminName', + last_name: 'adminLastName', + email: 'admintest@example.com', + phone: '01012345678', + password: '5f4dcc3b5aa765d61d8327deb882cf99', + is_admin: true, + org_id: 976542562576, + lunch_credit_balance: 10000, + }; + const response = await request(app) + .post('/api/auth/signup/org-user') + .send(adminUser); + + expect(response.status).toEqual(200); + expect(response.body).toHaveProperty('message', 'Org and User registered successfully'); + expect(response.body.data).toMatchObject(adminUser); + }); + + it('should return a 400 error for missing data', async () => { + const adminUser = { + fisrt_name: 'adminName' + }; // Missing required params email, password, org_name and lunch_price + const response = await request(app) + .post('/api/auth/signup/org-user') + .send(adminUser); + + expect(response.status).toEqual(400); + }); +}); \ No newline at end of file diff --git a/tests/createPasswordController.test.js b/tests/createPasswordController.test.js new file mode 100644 index 00000000..98c6dda7 --- /dev/null +++ b/tests/createPasswordController.test.js @@ -0,0 +1,55 @@ +require('dotenv').config(); +const request = require('supertest'); +const sequelize = require('../db/db'); +const app = require('../app'); + +beforeAll(async () => { + try { + await sequelize.sync(); + } catch (error) { + console.error('Database sync error', error); + } +}); + +describe('Update Password API', () => { + it('should update the user password', async () => { + const testUserId = '092820892'; + const password = 'updatedPassword_hash'; + const confirmPassword = 'updatedPassword_hash'; + + const response = await request(app) + .query({testUserId}) + .patch('/api/users/update-password') + .send({ password, confirmPassword }); + + expect(response.status).toEqual(200); + expect(response.status).toHaveProperty('message', 'Password created successfully'); + }); + + it('should return a 400 error if passwords do not match', async () => { + const testUserId = '092820892'; + const password = 'updatedPassword_hash'; + const confirmPassword = passwordUpdate_hash; // differs from entry in password field + + const response = await request(app) + .query({testUserId}) + .patch('/api/users/update-password') + .send({ password, confirmPassword }); + + expect(response.status).toEqual(400); + expect(response.body).toHaveProperty('message', 'Passwords do not match'); + }); + + it('should return a 400 error for missing data', async () => { + const testUserId = '092820892'; + const password = updatedPassword_hash; // Missing confirmPassword + + const response = await request(app) + .query({testUserId}) + .patch('/api/users/update-password') + .send({ password }); + + expect(response.status).toEqual(400); + expect(response.body).toHaveProperty('message', 'Fill all required fields'); + }); +}); \ No newline at end of file diff --git a/tests/lunchController.test.js b/tests/lunchController.test.js new file mode 100644 index 00000000..1470cae5 --- /dev/null +++ b/tests/lunchController.test.js @@ -0,0 +1,113 @@ +require('dotenv').config(); +const request = require('supertest'); +const sequelize = require('../db/db'); +const app = require('../app'); + +beforeAll(async () => { + try { + await sequelize.sync(); + } catch (error) { + console.error('Database sync error', error); + } +}); + +describe('Retrieve available lunches for a user', () => { + + it('should return an empty array for a user with no lunch data', async () => { + const testUserId = '9339'; //user is with no lunch data + + const response = await request(app) + .get(`/api/lunch/${testUserId}`); + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('message', 'No lunches found for this user'); + }); + + it('should retrieve all available lunches for a user by the user id', async () => { + const testUserId = '29292'; + + const response = await request(app) + .query({testUserId}) + .get(`/api/lunch/${testUserId}`); + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('message', 'Lunches retrieved successfully'); + }); + + it('should return a 500 error for missing user ID', async () => { + const testUserId = ''; + const response = await request(app) + .get(`/api/lunch/${testUserId}`); + + expect(response.status).toBe(500); + }); + +}); + +describe('Send Lunch API', () => { + it('should send lunch to a user', async () => { + const testReceiverId = '9302302'; //user id you want to send lunch to + const testQuantity = 2; + const testNote = 'Well deserved'; + + const response = await request(app) + .post('/api/lunch/send') + .send({ testReceiverId, testQuantity, testNote }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('message', 'Lunch sent successfully'); + }); + +}); + +describe('Redeem Lunch API', () => { + it('should redeem lunch into bank account', async () => { + const bank_code = '100110'; + const bank_name = 'KeyStone'; + const bank_number = '0123456789'; + const amount = 2; + const email = 'testemail@example.com'; + const user_id = 203930303; + + const response = await request(app) + .query({user_id}) + .post('/api/lunch/redeem') + .send({ bank_code, bank_name, bank_number, amount, email }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('message', 'Withdrawal request created successfully'); + }); + + it('should return a 400 error for missing data', async () => { + const bank_code = '100110'; // Missing bank_name, bank_number, amount and email + const user_id = 203930303; + + const response = await request(app) + .query({user_id}) + .post('/api/lunch/redeem') + .send({ bank_code }); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message', 'Please provide all required fields'); + }); +}); + +describe('Get Lunch Details API', () => { + it('should retrieve lunch details by lunch id', async () => { + const testLunchId = '38292'; + + const response = await request(app) + .get(`/api/lunch/${testLunchId}`); + + expect(response.status).toBe(200); + }); + + it('should return a 404 error for missing lunch details', async () => { + const testLunchId = '0101010' // Lunch Id which doesn't contain lunch data + + const response = await request(app) + .get(`/api/lunch/${testLunchId}`); + + expect(response.status).toBe(404); + }) +}); \ No newline at end of file diff --git a/tests/organizationController.test.js b/tests/organizationController.test.js new file mode 100644 index 00000000..45c37c87 --- /dev/null +++ b/tests/organizationController.test.js @@ -0,0 +1,119 @@ +require('dotenv').config(); +const request = require('supertest'); +const sequelize = require('../db/db'); +const app = require('../app'); + +beforeAll(async () => { + try { + await sequelize.sync(); + } catch (error) { + console.error('Database sync error', error); + } +}); + +describe('Create Organization API', () => { + it('should create a new organization', async () => { + const newOrg = { + name: 'testOrg', + lunch_price: 1234.56, + currency_code: 'NGN' + }; + const response = await request(app) + .post('/api/organization/create') + .send(newOrg); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('mssage', 'Organization and Lunch Wallet created successfully'); + }); + + it('should return a 400 error for missing data', async () => { + const newOrg = { + lunch_price: 1234.56 + }; // Missing required params name and currency_code + const response = await request(app) + .post('/api/organization/create') + .send(newOrg); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message', 'Missing required fields'); + }); +}); + +describe('Send Invite Code API', () => { + it('should send an invite code to user email', async () => { + const email = 'testemail@example.com'; + const org_id = '976542562576'; + const token = 'userToken'; + + const response = await request(app) + .post('/api/organization/send-invite') + .send({ email, org_id, token }); + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('message', 'Invitation sent successfully'); + }); + + it('should return a 400 error for missing email or org_id ', async () => { + const email = 'testemail@example.com'; // Missing org_id + + const response = await request(app) + .post('/api/organization/send-invite') + .send(email); + + expect(response.status).toBe(400); + }); + + it('should return a 400 error for missing token', async () => { + const email = 'testemail@example.com'; + const org_id = '976542562576'; // Missing token + + const response = await request(app) + .post('/api/organization/send-invite') + .send({ email, org_id}); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message', 'Verification code is required'); + }); + + it('should return a 400 error for invalid token', async () => { + const email = 'testemail@example.com'; + const org_id = '976542562576'; + const token = 'invalidToken'; + + const response = await request(app) + .post('/api/organization/send-invite') + .send({ email, org_id, token }); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('message', 'Invalid verification code'); + }); +}); + +describe('Update Organization Details API', () => { + it('should update organization details for an admin user', async () => { + const name = 'updatedName'; + const lunchPrice = 987.65; + const currency = 'USD'; + + const response = await request(app) + .put('/api/organization/update-info') + .query({is_admin: 'true'}) + .send({ name, lunchPrice, currency }); + + expect(response.status).toBe(201); + expect(app.organization.name).toBe('updateName'); + }); + + it('should return a 403 error for a non-admin user', async () => { + const name = 'UpdatedName'; + const lunchPrice = 12.34; + const currency = 'AUD'; + + const response = request(app) + .put('/api/organization/update-info') + .query({is_admin: 'false'}) + .send({ name, lunchPrice, currency }); + + expect(response.status).toBe(403); + }); +}); \ No newline at end of file diff --git a/tests/withdrawalController.test.js b/tests/withdrawalController.test.js new file mode 100644 index 00000000..9bf135d9 --- /dev/null +++ b/tests/withdrawalController.test.js @@ -0,0 +1,56 @@ +require('dotenv').config(); +const request = require('supertest'); +const sequelize = require('../db/db'); +const app = require('../app'); + +beforeAll(async () => { + try { + await sequelize.sync(); + } catch (error) { + console.error('Database sync error', error); + } +}); + +describe('Withdraw Cash API', () => { + it('should withdraw to user bank info', async () => { + const bank_code = '1011100'; + const bank_name = 'KeyStone'; + const bank_number = '0987654321'; + const amount = 2; + const user_id = 3039930493; + + const response = await request(app) + .query({user_id}) + .post('/api/withdrawal/request') + .send({ bank_code, bank_name, bank_number, amount }); + + expect(response.status).toBe(201); + expect(response.body).toHaveProperty('message', 'Withdrawal request created successfully'); + }); + + it('should return a 401 error for missing data', async () => { + const bank_code = 10010011; // Missing bank_name, bank_number and amount + const user_id = 3039930493; + + const response = await request(app) + .query({user_id}) + .post('/api/withdrawal/request') + .send({ bank_code }); + + expect(response.status).toBe(401); + expect(response.body).toHaveProperty('message', 'Please provide required field'); + }); +}); + +describe('Withdrawal history API', () => { + it('should retrieve the withdrawal history of a user by user_id', async () => { + const testUserId = 283798339; + + const response = await request(app) + .query({testUserId}) + .get('/api/withdrawal/all') + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('message', 'Withdrawal History'); + }); +}); \ No newline at end of file