Skip to content

Commit

Permalink
Merge branch 'dev' into chore/unit-testing
Browse files Browse the repository at this point in the history
  • Loading branch information
incredible-phoenix246 authored Jul 22, 2024
2 parents bd52fb3 + 49a76e7 commit d3efa2f
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 3 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"swagger-ui-express": "^5.0.1",
"ts-jest": "^29.2.3",
"ts-node-dev": "^2.0.0",
"twilio": "^5.2.2",
"typeorm": "^0.3.20"
}
}
4 changes: 4 additions & 0 deletions src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const config = {
SMTP_HOST: process.env.SMTP_HOST,
SMTP_SERVICE: process.env.SMTP_SERVICE,
NODE_ENV: process.env.NODE_ENV,
TWILIO_SID: process.env.TWILIO_SID,
TWILIO_AUTH_TOKEN: process.env.TWILIO_AUTH_TOKEN,
TWILIO_PHONE_NUMBER: process.env.TWILIO_PHONE_NUMBER,

};

export default config;
46 changes: 46 additions & 0 deletions src/controllers/SmsController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Request, Response } from "express";
import SmsService from "../services/sms.services";
import AppDataSource from "../data-source";
import { User } from "../models";

export const sendSms = async (req: Request, res: Response): Promise<void> => {
const { phone_number, message } = req.body;
const sender_id = req.user.id;

if (!phone_number || !message || !sender_id) {
res.status(400).json({
status: "unsuccessful",
status_code: 400,
message:
"Valid phone number, message content, and sender ID must be provided.",
});
return;
}

try {
const userRepository = AppDataSource.getRepository(User);
const sender = await userRepository.findOneBy({ id: sender_id });

if (!sender) {
res.status(404).json({
status: "unsuccessful",
status_code: 404,
message: "Sender not found.",
});
return;
}

await SmsService.sendSms(sender, phone_number, message);
res.status(200).json({
status: "success",
status_code: 200,
message: "SMS sent successfully.",
});
} catch (error) {
res.status(500).json({
status: "unsuccessful",
status_code: 500,
message: "Failed to send SMS. Please try again later.",
});
}
};
39 changes: 39 additions & 0 deletions src/controllers/TestimonialsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,43 @@ export default class TestimonialsController {
res.status(500).send({ message: error.message });
}
}

// CODE BY TOMILLA OLUWAFEMI
public async getAllTestimonials(req: Request, res: Response) {
try {
const testimonials = await AppDataSource.getRepository(Testimonial).find();
res.status(200).json({
message: "Testimonials retrieved successfully",
status_code: 200,
data: testimonials,
});
} catch (error) {
res.status(500).send({ message: error.message });
}
}

public async deleteTestimonial(req: Request, res: Response) {
try {
const { testimonial_id } = req.params;

const testimonialToDelete = await AppDataSource.getRepository(Testimonial).findOne({
where: { id: testimonial_id },
});

if (!testimonialToDelete) {
return res
.status(404)
.send({ message: "Testimonial not found", status_code: 404 });
}

await AppDataSource.getRepository(Testimonial).remove(testimonialToDelete);

res.status(200).json({
message: "Testimonial deleted successfully",
status_code: 200,
});
} catch (error) {
res.status(500).send({ message: error.message });
}
}
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
authRoute,
testimonialRoute,
notificationRouter,
smsRouter,
} from "./routes";
import { routeNotFound, errorHandler } from "./middleware";
import { orgRouter } from "./routes/organisation";
Expand Down Expand Up @@ -42,6 +43,7 @@ server.get("/", (req: Request, res: Response) => {
});
server.use("/api/v1", userRouter, orgRouter);
server.use("/api/v1/auth", authRoute);
server.use("/api/v1/sms", smsRouter);
server.use("/api/v1", testimonialRoute);
server.use("/api/v1/docs", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
server.use(routeNotFound);
Expand Down
3 changes: 2 additions & 1 deletion src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
export * from "./auth";
export * from "./user";
export * from "./testimonial";
export * from "./notificationsettings"
export * from "./sms";
export * from "./notificationsettings";
9 changes: 9 additions & 0 deletions src/routes/sms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Router } from "express";
import { sendSms } from "../controllers/SmsController";
import { authMiddleware } from "../middleware";

const smsRouter = Router();

smsRouter.post("/send", authMiddleware, sendSms);

export { smsRouter };
12 changes: 12 additions & 0 deletions src/routes/testimonial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,16 @@ testimonialRoute.get(
testimonialController.getTestimonial.bind(testimonialController)
);

// CODE BY TOMILOLA OLUWAFEMI
testimonialRoute.get(
"/testimonials",
authMiddleware,
testimonialController.getAllTestimonials.bind(testimonialController)
);
testimonialRoute.delete(
"/testimonials/:testimonial_id",
authMiddleware,
testimonialController.deleteTestimonial.bind(testimonialController)
);

export { testimonialRoute };
35 changes: 35 additions & 0 deletions src/services/sms.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Twilio } from "twilio";
import config from "../config";
import AppDataSource from "../data-source";
import { Sms } from "../models/sms";
import { User } from "../models";

class SmsService {
private twilioClient: Twilio;

constructor() {
this.twilioClient = new Twilio(config.TWILIO_SID, config.TWILIO_AUTH_TOKEN);
}

public async sendSms(
sender: User,
phoneNumber: string,
message: string
): Promise<void> {
await this.twilioClient.messages.create({
body: message,
from: config.TWILIO_PHONE_NUMBER,
to: phoneNumber,
});

const sms = new Sms();
sms.sender = sender;
sms.phone_number = phoneNumber;
sms.message = message;

const smsRepository = AppDataSource.getRepository(Sms);
await smsRepository.save(sms);
}
}

export default new SmsService();
61 changes: 59 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,13 @@ acorn@^8.11.0, acorn@^8.4.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248"
integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==

agent-base@6:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
dependencies:
debug "4"

ansi-escapes@^4.2.1:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
Expand Down Expand Up @@ -1041,6 +1048,15 @@ atomic-sleep@^1.0.0:
resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==

axios@^1.6.8:
version "1.7.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621"
integrity sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

babel-jest@^29.7.0:
version "29.7.0"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5"
Expand Down Expand Up @@ -1487,7 +1503,7 @@ [email protected]:
dependencies:
ms "2.0.0"

debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4:
version "4.3.5"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
Expand Down Expand Up @@ -1828,6 +1844,11 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"

follow-redirects@^1.15.6:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==

foreground-child@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.2.1.tgz#767004ccf3a5b30df39bed90718bab43fe0a59f7"
Expand Down Expand Up @@ -2047,6 +2068,14 @@ [email protected]:
statuses "2.0.1"
toidentifier "1.0.1"

https-proxy-agent@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
dependencies:
agent-base "6"
debug "4"

human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
Expand Down Expand Up @@ -3258,6 +3287,11 @@ proxy-addr@~2.0.7:
forwarded "0.2.0"
ipaddr.js "1.9.1"

proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==

pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
Expand All @@ -3278,7 +3312,7 @@ [email protected]:
dependencies:
side-channel "^1.0.4"

qs@^6.11.0:
qs@^6.11.0, qs@^6.9.4:
version "6.12.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.3.tgz#e43ce03c8521b9c7fd7f1f13e514e5ca37727754"
integrity sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==
Expand Down Expand Up @@ -3396,6 +3430,11 @@ safe-stable-stringify@^2.3.1:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==

scmp@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/scmp/-/scmp-2.1.0.tgz#37b8e197c425bdeb570ab91cc356b311a11f9c9a"
integrity sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==

secure-json-parse@^2.4.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.7.0.tgz#5a5f9cd6ae47df23dba3151edd06855d47e09862"
Expand Down Expand Up @@ -3847,6 +3886,19 @@ tslib@^2.5.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==

twilio@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/twilio/-/twilio-5.2.2.tgz#56285174e72fcfdbe28d4ca021337910c3d8191b"
integrity sha512-t2Nd8CvqAc0YxbJghKYQl1Vxc7e6SrWk4U28wwkarUohGcsUMLsGpYeGXKw1Va0KB9TGVZYCs8dcP4TdLJUN9Q==
dependencies:
axios "^1.6.8"
dayjs "^1.11.9"
https-proxy-agent "^5.0.0"
jsonwebtoken "^9.0.2"
qs "^6.9.4"
scmp "^2.1.0"
xmlbuilder "^13.0.2"

[email protected]:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
Expand Down Expand Up @@ -4007,6 +4059,11 @@ write-file-atomic@^4.0.2:
imurmurhash "^0.1.4"
signal-exit "^3.0.7"

xmlbuilder@^13.0.2:
version "13.0.2"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-13.0.2.tgz#02ae33614b6a047d1c32b5389c1fdacb2bce47a7"
integrity sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==

xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
Expand Down

0 comments on commit d3efa2f

Please sign in to comment.