-
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.
- Loading branch information
Showing
5 changed files
with
265 additions
and
2 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 |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import request from 'supertest'; | ||
import app from '../app'; | ||
import { afterAllHook, beforeAllHook } from './testSetup'; | ||
import dbConnection from '../database'; | ||
import Subscription from '../database/models/subscribe'; | ||
|
||
const subscribeRepository = dbConnection.getRepository(Subscription); | ||
|
||
beforeAll(async () => { | ||
await beforeAllHook(); | ||
}); | ||
|
||
afterAll(async () => { | ||
await afterAllHook(); | ||
}); | ||
|
||
describe('POST /api/v1/subscribe', () => { | ||
beforeEach(async () => { | ||
// Clear the table before each test | ||
await subscribeRepository.clear(); | ||
}); | ||
|
||
it('should subscribe successfully with a valid email', async () => { | ||
const response = await request(app) | ||
.post('/api/v1/subscribe') | ||
.send({ email: '[email protected]' }); | ||
|
||
expect(response.status).toBe(201); | ||
expect(response.body.message).toBe('Subscribed successfully'); | ||
expect(response.body.subscription.email).toBe('[email protected]'); | ||
|
||
const subscription = await subscribeRepository.findOne({ | ||
where: { email: '[email protected]' }, | ||
}); | ||
expect(subscription).toBeDefined(); | ||
}); | ||
|
||
it('should return 400 if the email is already subscribed', async () => { | ||
const subscription = new Subscription(); | ||
subscription.email = '[email protected]'; | ||
await subscribeRepository.save(subscription); | ||
|
||
const response = await request(app) | ||
.post('/api/v1/subscribe') | ||
.send({ email: '[email protected]' }); | ||
|
||
expect(response.status).toBe(400); | ||
expect(response.body.message).toBe('Email is already subscribed'); | ||
}); | ||
|
||
it('should return 400 for an invalid email format', async () => { | ||
const response = await request(app) | ||
.post('/api/v1/subscribe') | ||
.send({ email: 'invalid-email' }); | ||
|
||
expect(response.status).toBe(400); | ||
expect(response.body.errors[0].msg).toBe('Email is not valid'); | ||
}); | ||
}); | ||
|
||
describe('DELETE /api/v1/subscribe/delete/:id', () => { | ||
beforeEach(async () => { | ||
// Clear the table before each test | ||
await subscribeRepository.clear(); | ||
}); | ||
|
||
it('should remove a subscription successfully', async () => { | ||
const subscription = new Subscription(); | ||
subscription.email = '[email protected]'; | ||
await subscribeRepository.save(subscription); | ||
|
||
const response = await request(app) | ||
.delete(`/api/v1/subscribe/delete/${subscription.id}`) | ||
.send(); | ||
|
||
expect(response.status).toBe(200); | ||
expect(response.body.message).toBe('Subscription removed successfully'); | ||
}); | ||
|
||
it('should return 404 if the subscription does not exist', async () => { | ||
const response = await request(app) | ||
.delete('/api/v1/subscribe/delete/450') | ||
.send(); | ||
|
||
expect(response.status).toBe(404); | ||
expect(response.body.message).toBe('Subscription not found'); | ||
}); | ||
|
||
it('should return 400 for invalid ID', async () => { | ||
const response = await request(app) | ||
.delete('/api/v1/subscribe/delete/noid') | ||
.send(); | ||
|
||
expect(response.status).toBe(400); | ||
expect(response.body.message).toBeUndefined(); | ||
}); | ||
}); |
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,64 @@ | ||
import { Request, Response } from 'express'; | ||
import errorHandler from '../middlewares/errorHandler'; | ||
import dbConnection from '../database'; | ||
import Subscription from '../database/models/subscribe'; | ||
import { check, validationResult } from 'express-validator'; | ||
|
||
const subscribeRepository = dbConnection.getRepository(Subscription); | ||
const userEmailRules = [ | ||
check('email').isEmail().normalizeEmail().withMessage('Email is not valid'), | ||
]; | ||
export const subscribe = [ | ||
...userEmailRules, | ||
errorHandler(async (req: Request, res: Response) => { | ||
const { email } = req.body; | ||
const errors = validationResult(req); | ||
if (!errors.isEmpty()) { | ||
return res.status(400).json({ errors: errors.array() }); | ||
} | ||
|
||
const alreadSubscribed = await subscribeRepository.findOneBy({ | ||
email: req.body.email, | ||
}); | ||
if (alreadSubscribed) { | ||
return res.status(400).json({ message: 'Email is already subscribed' }); | ||
} | ||
|
||
const subscription = new Subscription(); | ||
subscription.email = email; | ||
|
||
await subscribeRepository.save(subscription); | ||
res.status(201).json({ message: 'Subscribed successfully', subscription }); | ||
}), | ||
]; | ||
|
||
const userIdRules = [ | ||
check('id').isInt({ min: 1 }).withMessage(' ID is required'), | ||
]; | ||
|
||
export const removeSubscriber = [ | ||
...userIdRules, | ||
errorHandler(async (req: Request, res: Response) => { | ||
const id: number = parseInt(req.params.id); | ||
|
||
const errors = validationResult(req); | ||
if (!errors.isEmpty()) { | ||
return res.status(400).json({ errors: errors.array() }); | ||
} | ||
|
||
try { | ||
const subscription = await subscribeRepository.findOne({ | ||
where: { id }, | ||
}); | ||
|
||
if (!subscription) { | ||
return res.status(404).json({ message: 'Subscription not found' }); | ||
} | ||
|
||
await subscribeRepository.remove(subscription); | ||
res.status(200).json({ message: 'Subscription removed successfully' }); | ||
} catch (error) { | ||
res.status(500).json({ message: 'Error removing subscription', error }); | ||
} | ||
}), | ||
]; |
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,12 @@ | ||
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; | ||
import { IsEmail } from 'class-validator'; | ||
|
||
@Entity() | ||
export default class Subscription { | ||
@PrimaryGeneratedColumn() | ||
id: number; | ||
|
||
@Column() | ||
@IsEmail() | ||
email: string; | ||
} |
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,87 @@ | ||
/** | ||
* @swagger | ||
* tags: | ||
* name: Subscribe | ||
* description: Subscription management | ||
*/ | ||
|
||
/** | ||
* @openapi | ||
* /api/v1/subscribe: | ||
* post: | ||
* tags: [Subscribe] | ||
* summary: Subscribe user to our app | ||
* requestBody: | ||
* required: true | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* email: | ||
* type: string | ||
* example: [email protected] | ||
* responses: | ||
* 201: | ||
* description: Subscribed successfully | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* message: | ||
* type: string | ||
* example: Subscribed successfully | ||
* subscription: | ||
* type: object | ||
* properties: | ||
* email: | ||
* type: string | ||
* example: [email protected] | ||
*/ | ||
|
||
/** | ||
* @openapi | ||
* /api/v1/subscribe/delete/{id}: | ||
* delete: | ||
* tags: [Subscribe] | ||
* summary: Removes a user from subscription | ||
* parameters: | ||
* - in: path | ||
* name: id | ||
* required: true | ||
* schema: | ||
* type: integer | ||
* example: 1 | ||
* responses: | ||
* 200: | ||
* description: Subscription removed successfully | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* message: | ||
* type: string | ||
* example: Subscription removed successfully | ||
* 404: | ||
* description: Subscription not found | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* message: | ||
* type: string | ||
* example: Subscription not found | ||
* 400: | ||
* description: Invalid ID | ||
* content: | ||
* application/json: | ||
* schema: | ||
* type: object | ||
* properties: | ||
* message: | ||
* type: string | ||
* example: Invalid ID | ||
*/ |
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