Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ft: implement user logout feature #67

Merged
merged 1 commit into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/__test__/logout.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import request from 'supertest';
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();
server.close();
});

describe('POST /user/logout', () => {
it('should logout a user', async () => {
// sign up a user
const registerUser = {
firstName: 'Ndevu',
lastName: 'Elisa',
email: 'ndevukumurindi@gmail.com',
gender: 'male',
phoneNumber: '078907987443',
photoUrl: 'https://example.com/images/photo.jpg',
userType: 'vender',
verified: true,
status: 'active',
password: process.env.TEST_USER_LOGIN_PASS,
};

await request(app).post('/user/register').send(registerUser);

const loginUser = {
email: registerUser.email,
password: process.env.TEST_USER_LOGIN_PASS,
};

const userRepository = getRepository(User);
const user = await userRepository.findOne({ where: { email: registerUser.email } });
if (user) {
const verifyRes = await request(app).get(`/user/verify/${user.id}`);

if (!verifyRes) throw new Error(`Test User verification failed for ${user.email}`);

const loginResponse = await request(app).post('/user/login').send(loginUser);
const setCookie = loginResponse.headers['set-cookie'];

if (!setCookie) {
throw new Error('No cookies set in login response');
}

const resp = await request(app).post('/user/logout').set('Cookie', setCookie);
expect(resp.status).toBe(200);
expect(resp.body).toEqual({ Message: 'Logged out successfully' });

// Clean up: delete the test user
await userRepository.remove(user);
}
});

it('should not logout a user who is not logged in or with no token', async () => {
const fakeEmail = 'ndevukkkk@gmail.com';
const loginUser = {
email: fakeEmail,
password: process.env.TEST_USER_LOGIN_PASS,
};
const token = '';
const res = await request(app).post('/user/logout').send(loginUser).set('Cookie', token);
expect(res.status).toBe(400);
expect(res.body).toEqual({ Message: 'Access denied. You must be logged in' });
});
});
41 changes: 17 additions & 24 deletions src/__test__/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
const connectionOptions = await getConnectionOptions();

await createConnection({ ...connectionOptions, name: 'testConnection' });

});



afterAll(async () => {
const connection = getConnection('testConnection');
const userRepository = connection.getRepository(User);
Expand Down Expand Up @@ -84,7 +81,7 @@
};

// Create a new user
const res = await request(app).post('/user/register').send(newUser);

Check warning on line 84 in src/__test__/route.test.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'res' is assigned a value but never used. Allowed unused vars must match /^_/u

Check warning on line 84 in src/__test__/route.test.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'res' is assigned a value but never used

Check warning on line 84 in src/__test__/route.test.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'res' is assigned a value but never used. Allowed unused vars must match /^_/u

Check warning on line 84 in src/__test__/route.test.ts

View workflow job for this annotation

GitHub Actions / build-lint-test-coverage

'res' is assigned a value but never used

const userRepository = getRepository(User);
const user = await userRepository.findOne({ where: { email: newUser.email } });
Expand All @@ -106,9 +103,8 @@
});

describe('Send password reset link', () => {

it('Attempt to send email with rate limiting', async () => {
const email = "elijahladdiedv@gmail.com";
const email = 'elijahladdiedv@gmail.com';

const requests = Array.from({ length: 5 }, async () => {
return await request(app).post(`/user/password/reset/link?email=${email}`);
Expand All @@ -118,34 +114,33 @@
const lastResponse = responses[responses.length - 1];
expect(lastResponse.status).toBe(404);
expect(lastResponse.body.message).toEqual('User not found');
});
}, 20000);

it('Attempt to send email with invalid email template', async () => {
const email = "elijahladdiedv@gmail.com";
const email = 'elijahladdiedv@gmail.com';

const res = await request(app).post(`/user/password/reset/link?email=${email}`);

expect(res.status).toBe(404);
expect(res.body.message).toEqual('User not found');
});
}, 10000);

it('Send email to a user with special characters in email address', async () => {
const email = "user+test@example.com";
const email = 'user+test@example.com';

const res = await request(app).post(`/user/password/reset/link?email=${encodeURIComponent(email)}`);

expect(res.status).toBe(404);
expect(res.body.message).toEqual('User not found');
});

}, 10000);
});
describe('Password Reset Service', () => {
it('Should reset password successfully', async () => {
const data = {
"newPassword": "user",
"confirmPassword": "user",
newPassword: 'user',
confirmPassword: 'user',
};
const email = "elijahladdiedv@gmail.com";
const email = 'elijahladdiedv@gmail.com';
const userRepository = getRepository(User);
const user = await userRepository.findOne({ where: { email: email } });
if (user) {
Expand All @@ -158,22 +153,21 @@

it('Should return 404 if user not found', async () => {
const data = {
"newPassword": "user",
"confirmPassword": "user",
newPassword: 'user',
confirmPassword: 'user',
};
const email = "nonexistentemail@example.com";
const userId = "nonexistentuserid";
const email = 'nonexistentemail@example.com';
const userId = 'nonexistentuserid';
const res: any = await request(app).post(`/user/password/reset?userid=${userId}&email=${email}`).send(data);
// Asser
expect(res).toBeTruthy;

});

it('Should return 204 if required fields are missing', async () => {
const data = {
//
};
const email = "elijahladdiedv@gmail.com";
const email = 'elijahladdiedv@gmail.com';

const userRepository = getRepository(User);
const user = await userRepository.findOne({ where: { email: email } });
Expand All @@ -186,10 +180,10 @@

it('Should return 204 if newPassword and confirmPassword do not match', async () => {
const data = {
"newPassword": "user123",
"confirmPassword": "user456",
newPassword: 'user123',
confirmPassword: 'user456',
};
const email = "elijahladdiedv@gmail.com";
const email = 'elijahladdiedv@gmail.com';

const userRepository = getRepository(User);
const user = await userRepository.findOne({ where: { email: email } });
Expand All @@ -200,4 +194,3 @@
}
});
});

25 changes: 22 additions & 3 deletions src/__test__/userServices.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ describe('start2FAProcess', () => {

it('should return 403 if OTP is expired', async () => {
const email = 'john.doe1@example.com';
const user = await getRepository(User).findOneBy({ email });
const userRepository = getRepository(User);
const user = await userRepository.findOneBy({ email });
if (user) {
user.twoFactorEnabled = true;
user.twoFactorCode = '123456';
Expand All @@ -168,6 +169,9 @@ describe('start2FAProcess', () => {
const res = await request(app).post('/user/verify-otp').send(data);
expect(res.status).toBe(403);
expect(res.body).toEqual({ status: 'error', message: 'Authentication code expired' });
if (user) {
await userRepository.remove(user);
}
});

it('should return 400 if not sent email in body on resending OTP', async () => {
Expand All @@ -190,14 +194,29 @@ describe('start2FAProcess', () => {
});

it('should resend OTP', async () => {
const newUser = {
firstName: 'John',
lastName: 'Doe',
email: 'john.doe187@example.com',
password: 'password',
gender: 'Male',
phoneNumber: '0785044398',
userType: 'Buyer',
};

// Act
const resp = await request(app).post('/user/register').send(newUser);
if (!resp) {
console.log('Error creating user in resend otp test case');
}
const data = {
email: 'john.doe1@example.com',
email: 'john.doe187@example.com',
};

const res = await request(app).post('/user/resend-otp').send(data);
expect(res.status).toBe(200);
expect(res.body).toEqual({ status: 'success', data: { message: 'OTP sent successfully' } });
});
}, 20000);

it('should return 400 if not sent email in body on login', async () => {
const data = {};
Expand Down
Loading
Loading