diff --git a/README.md b/README.md index 187a38ef..67b0fdda 100644 --- a/README.md +++ b/README.md @@ -20,8 +20,8 @@ We welcome contributions to make ScholarX even better! Feel free to send us a pu Before you can start using this project, make sure you have the following installed on your machine: -- Node.js (version 14 or later) -- npm (version 6 or later) +- Node.js (version 18 or later) +- npm (version 9 or later) ## Getting Started @@ -69,29 +69,27 @@ If you prefer to use Docker for development, follow these steps: 2. Build the Docker images: -```docker-compose build``` +`docker-compose build` 3. Start the Docker containers: -```docker-compose up``` +`docker-compose up` -4. The application and its services are now running in Docker containers. You can access the application at ```http://localhost:${SERVER_PORT}```, where ```SERVER_PORT``` is the port number specified in your ```.env``` file. +4. The application and its services are now running in Docker containers. You can access the application at `http://localhost:${SERVER_PORT}`, where `SERVER_PORT` is the port number specified in your `.env` file. 5. To stop the Docker containers, use the following commnd: -```docker-compose down``` +`docker-compose down` -Please note that the Docker Compose setup assumes that you have a ```.env``` file in your project root. You can create one by copying the ```.env.example``` file: +Please note that the Docker Compose setup assumes that you have a `.env` file in your project root. You can create one by copying the `.env.example` file: -```cp .env.example .env``` +`cp .env.example .env` -Then, replace the environment variables in the newly created ```.env``` file with your configuration. +Then, replace the environment variables in the newly created `.env` file with your configuration. -The environment directive sets environment variables inside the Docker container. These variables are used to configure the PostgreSQL server. The values for ```${DB_USER}```, ```${DB_PASSWORD}```, and ```${DB_NAME}``` should be specified in your .env file. - - -Remember to replace ```${SERVER_PORT}``` with the actual port number if it's a fixed value. If it's specified in the ```.env``` file, you can leave it as is. +The environment directive sets environment variables inside the Docker container. These variables are used to configure the PostgreSQL server. The values for `${DB_USER}`, `${DB_PASSWORD}`, and `${DB_NAME}` should be specified in your .env file. +Remember to replace `${SERVER_PORT}` with the actual port number if it's a fixed value. If it's specified in the `.env` file, you can leave it as is. In the `docker-compose.yml` file, we also have a `db` service for the PostgreSQL database: @@ -106,16 +104,15 @@ db: - POSTGRES_DB=${DB_NAME} ``` -This service uses the official postgres:15 Docker image. The ports directive maps port 5432 inside the Docker container to port 5432 on your host machine, allowing you to connect to the PostgreSQL server at ```localhost:5432```. +This service uses the official postgres:15 Docker image. The ports directive maps port 5432 inside the Docker container to port 5432 on your host machine, allowing you to connect to the PostgreSQL server at `localhost:5432`. -Now, you can connect to the PostgreSQL server running inside the Docker container using a database client. Use ```localhost:5432``` as the server address, and the ```${DB_USER}```, ```${DB_PASSWORD}```, and ```${DB_NAME}``` values from your ```.env``` file for the username, password, and database name, respectively. +Now, you can connect to the PostgreSQL server running inside the Docker container using a database client. Use `localhost:5432` as the server address, and the `${DB_USER}`, `${DB_PASSWORD}`, and `${DB_NAME}` values from your `.env` file for the username, password, and database name, respectively. -### Note +### Note If you have a local PostgreSQL server running on port 5432, you will need to stop it before starting the Docker container, or change the port mapping to avoid a conflict. - -Remember to replace ```${SERVER_PORT}``` with the actual port number if it's a fixed value. If it's specified in the ```.env``` file, you can leave it as is. +Remember to replace `${SERVER_PORT}` with the actual port number if it's a fixed value. If it's specified in the `.env` file, you can leave it as is. --- @@ -172,6 +169,7 @@ scholarx-backend/ - `tsconfig.json`: Configuration file for the TypeScript compiler. ## Setting up Google Authentication + 1. Open Google Cloud Console: Visit https://console.cloud.google.com @@ -200,22 +198,23 @@ Once the details are filled, click the "Create" button at the bottom. Google Cloud Platform will now create your project. This might take a few moments. - ## Enabling Google+ API for the Project + 1. Navigate to the Google Cloud Console. -Select your project using the project selector at the top. -In the left navigation pane, click on "APIs & Services" and then click on "Library." + Select your project using the project selector at the top. + In the left navigation pane, click on "APIs & Services" and then click on "Library." 2. Search for "Google+ API" in the library. 3. Click on the Google+ API and then click the "Enable" button. ## Create OAuth Consent Screen + 1. Navigate to the API & Services Dashboard: -Open the Google Cloud Console. -Select your project. + Open the Google Cloud Console. + Select your project. -3. Open the API & Services Dashboard: +2. Open the API & Services Dashboard: In the left navigation pane, click on "APIs & Services" and then click on "Credentials." @@ -225,22 +224,23 @@ Click on "Create Credentials" and choose "OAuth consent screen." Fill in the required details for your OAuth consent screen, such as product name, user support email, and developer contact information. 5. Save and Continue: -Save the consent screen configuration. - + Save the consent screen configuration. ## Create OAuth Client ID Credentials + 1. Navigate to the API & Services Dashboard: -In the "Credentials" page, click on "Create Credentials" and choose "OAuth client ID." -Configure OAuth Client ID: -Select the application type and -Enter a name for your client ID. -Configure the authorized redirect URIs. + In the "Credentials" page, click on "Create Credentials" and choose "OAuth client ID." + Configure OAuth Client ID: + Select the application type and + Enter a name for your client ID. + Configure the authorized redirect URIs. 2. Save Credentials: Click "Create" to generate your OAuth client ID and client secret. ## Set Environment Variables + After obtaining the OAuth client ID and client secret,set the environment variables in your application to use these credentials. Ex: @@ -249,7 +249,6 @@ process.env.GOOGLE_CLIENT_ID = 'your-client-id'; process.env.GOOGLE_CLIENT_SECRET = 'your-client-secret'; process.env.GOOGLE_REDIRECT_URL = 'your-redirect-uri'; - We appreciate your interest in ScholarX. Happy contributing! If you have any questions or need assistance, please don't hesitate to reach out to us. ## Setting up LinkedIn Authentication @@ -259,6 +258,7 @@ We appreciate your interest in ScholarX. Happy contributing! If you have any que 2. Navigate to https://developer.linkedin.com/ 3. Select "Create App": + - Add App name. - Search for the LinkedIn page that was previously created. - Upload an image as a Logo. @@ -270,6 +270,14 @@ We appreciate your interest in ScholarX. Happy contributing! If you have any que 6. Copy Client Id and Client Secret from the Auth Section. -6. In setting section verify the LinkedIn Page and generate URL. +7. In setting section verify the LinkedIn Page and generate URL. + +8. Verify it from your account. -7. Verify it from your account. +## Create dummy data + +1. Run the seeding script: + + ```bash + npm run seed + ``` diff --git a/src/controllers/admin/emailTemplate.controller.ts b/src/controllers/admin/emailTemplate.controller.ts deleted file mode 100644 index 200e7dcd..00000000 --- a/src/controllers/admin/emailTemplate.controller.ts +++ /dev/null @@ -1,80 +0,0 @@ -import type { Request, Response } from 'express' -import type EmailTemplate from '../../entities/emailTemplate.entity' -import type Profile from '../../entities/profile.entity' -import { ProfileTypes } from '../../enums' -import { - createEmailTemplate, - deleteEmailTemplateById, - getEmailTemplateById -} from '../../services/admin/emailTemplate.service' -import type { ApiResponse } from '../../types' - -export const addEmailTemplate = async ( - req: Request, - res: Response -): Promise> => { - try { - const user = req.user as Profile - const { subject, content } = req.body - - if (user.type !== ProfileTypes.ADMIN) { - return res.status(403).json({ message: 'Only Admins are allowed' }) - } - - if (!subject || !content) { - return res.status(400).json({ - error: 'Subject, content and state are required fields' - }) - } - const { emailTemplate, statusCode, message } = await createEmailTemplate( - subject, - content - ) - return res.status(statusCode).json({ emailTemplate, message }) - } catch (err) { - console.error('Error executing query', err) - return res.status(500).json({ error: err }) - } -} - -export const getEmailTemplate = async ( - req: Request, - res: Response -): Promise> => { - try { - const user = req.user as Profile - const templateId = req.params.mentorId - - if (user.type !== ProfileTypes.ADMIN) { - return res.status(403).json({ message: 'Only Admins are allowed' }) - } - - const { emailTemplate, statusCode, message } = await getEmailTemplateById( - templateId - ) - return res.status(statusCode).json({ emailTemplate, message }) - } catch (err) { - console.error('Error executing query', err) - return res.status(500).json({ error: err }) - } -} - -export const deleteEmailTemplate = async ( - req: Request, - res: Response -): Promise> => { - try { - const user = req.user as Profile - const templateId = req.params.templateId - - if (user.type !== ProfileTypes.ADMIN) { - return res.status(403).json({ message: 'Only Admins are allowed' }) - } - - const { statusCode, message } = await deleteEmailTemplateById(templateId) - return res.status(statusCode).json({ message }) - } catch (err) { - console.error('Error executing query', err) - return res.status(500).json({ error: err }) - } -} diff --git a/src/controllers/admin/platform.controller.ts b/src/controllers/admin/platform.controller.ts deleted file mode 100644 index 43cfe5fd..00000000 --- a/src/controllers/admin/platform.controller.ts +++ /dev/null @@ -1,70 +0,0 @@ -import type { Request, Response } from 'express' -import type { ApiResponse } from '../../types' -import type Platform from '../../entities/platform.entity' -import type Profile from '../../entities/profile.entity' -import { ProfileTypes } from '../../enums' -import { - createPlatform, - getPlatformDetails, - updatePlatformDetails -} from '../../services/admin/platform.service' - -export const addPlatform = async ( - req: Request, - res: Response -): Promise> => { - try { - const user = req.user as Profile - - if (user.type !== ProfileTypes.ADMIN) { - return res.status(403).json({ message: 'Only Admins are allowed' }) - } - - const { platform, statusCode, message } = await createPlatform(req.body) - return res.status(statusCode).json({ platform, message }) - } catch (err) { - console.error('Error executing query', err) - return res.status(500).json({ error: err }) - } -} - -export const getPlatform = async ( - req: Request, - res: Response -): Promise> => { - try { - const user = req.user as Profile - - if (user.type !== ProfileTypes.ADMIN) { - return res.status(403).json({ message: 'Only Admins are allowed' }) - } - - const { platform, statusCode, message } = await getPlatformDetails() - return res.status(statusCode).json({ platform, message }) - } catch (err) { - console.error('Error executing query', err) - return res.status(500).json({ error: err }) - } -} - -export const updatePlatform = async ( - req: Request, - res: Response -): Promise> => { - try { - const user = req.user as Profile - - if (user.type !== ProfileTypes.ADMIN) { - return res.status(403).json({ message: 'Only Admins are allowed' }) - } - - const { platform, statusCode, message } = await updatePlatformDetails( - req.body - ) - - return res.status(statusCode).json({ platform, message }) - } catch (err) { - console.error('Error executing query', err) - return res.status(500).json({ error: err }) - } -} diff --git a/src/entities/emailTemplate.entity.ts b/src/entities/emailTemplate.entity.ts deleted file mode 100644 index 080344f2..00000000 --- a/src/entities/emailTemplate.entity.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Column, Entity } from 'typeorm' -import BaseEntity from './baseEntity' - -@Entity('emailTemplate') -class EmailTemplate extends BaseEntity { - @Column({ type: 'varchar', length: 255 }) - subject: string - - @Column({ type: 'varchar', length: 655 }) - content: string - - constructor(subject: string, content: string) { - super() - this.subject = subject - this.content = content - } -} - -export default EmailTemplate diff --git a/src/entities/platform.entity.ts b/src/entities/platform.entity.ts deleted file mode 100644 index 79d694c4..00000000 --- a/src/entities/platform.entity.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Column, Entity } from 'typeorm' -import BaseEntity from './baseEntity' - -@Entity('platform') -class Platform extends BaseEntity { - @Column() - description: string - - @Column({ type: 'json' }) - mentor_questions: JSON - - @Column() - image_url: string - - @Column() - landing_page_url: string - - @Column({ type: 'varchar', length: 255 }) - title: string - - constructor( - description: string, - mentor_questions: JSON, - image_url: string, - landing_page_url: string, - title: string - ) { - super() - this.description = description - this.mentor_questions = mentor_questions - this.image_url = image_url - this.landing_page_url = landing_page_url - this.title = title - } -} - -export default Platform diff --git a/src/routes/admin/admin.route.ts b/src/routes/admin/admin.route.ts index 818ffc08..868fbdca 100644 --- a/src/routes/admin/admin.route.ts +++ b/src/routes/admin/admin.route.ts @@ -2,8 +2,6 @@ import express from 'express' import userRouter from './user/user.route' import mentorRouter from './mentor/mentor.route' import categoryRouter from './category/category.route' -import platformRouter from './platform/platform.route' -import emailTemplateRouter from './email/emailTemplate.route' import menteeRouter from './mentee/mentee.route' const adminRouter = express() @@ -12,7 +10,5 @@ adminRouter.use('/users', userRouter) adminRouter.use('/mentors', mentorRouter) adminRouter.use('/mentees', menteeRouter) adminRouter.use('/categories', categoryRouter) -adminRouter.use('/platform', platformRouter) -adminRouter.use('/emailTemplate', emailTemplateRouter) export default adminRouter diff --git a/src/routes/admin/email/emailTemplate.route.ts b/src/routes/admin/email/emailTemplate.route.ts deleted file mode 100644 index 0ab7ecf9..00000000 --- a/src/routes/admin/email/emailTemplate.route.ts +++ /dev/null @@ -1,15 +0,0 @@ -import express from 'express' -import { - addEmailTemplate, - deleteEmailTemplate, - getEmailTemplate -} from '../../../controllers/admin/emailTemplate.controller' -import { requireAuth } from '../../../controllers/auth.controller' - -const emailTemplateRouter = express.Router() - -emailTemplateRouter.post('/', requireAuth, addEmailTemplate) -emailTemplateRouter.get('/:templateId', requireAuth, getEmailTemplate) -emailTemplateRouter.delete('/:templateId', requireAuth, deleteEmailTemplate) - -export default emailTemplateRouter diff --git a/src/routes/admin/platform/platform.route.ts b/src/routes/admin/platform/platform.route.ts deleted file mode 100644 index eaf2ce23..00000000 --- a/src/routes/admin/platform/platform.route.ts +++ /dev/null @@ -1,15 +0,0 @@ -import express from 'express' -import { requireAuth } from '../../../controllers/auth.controller' -import { - addPlatform, - getPlatform, - updatePlatform -} from '../../../controllers/admin/platform.controller' - -const platformRouter = express.Router() - -platformRouter.post('/', requireAuth, addPlatform) -platformRouter.get('/', requireAuth, getPlatform) -platformRouter.put('/', requireAuth, updatePlatform) - -export default platformRouter diff --git a/src/scripts/seed-db.ts b/src/scripts/seed-db.ts index d5f85563..6a8ec338 100644 --- a/src/scripts/seed-db.ts +++ b/src/scripts/seed-db.ts @@ -2,10 +2,8 @@ import { faker } from '@faker-js/faker' import { dataSource } from '../configs/dbConfig' import Category from '../entities/category.entity' import Email from '../entities/email.entity' -import EmailTemplate from '../entities/emailTemplate.entity' import Mentee from '../entities/mentee.entity' import Mentor from '../entities/mentor.entity' -import Platform from '../entities/platform.entity' import Profile from '../entities/profile.entity' import { ApplicationStatus, EmailStatusTypes, ProfileTypes } from '../enums' @@ -15,18 +13,14 @@ export const seedDatabaseService = async (): Promise => { const profileRepository = dataSource.getRepository(Profile) const categoryRepository = dataSource.getRepository(Category) const emailRepository = dataSource.getRepository(Email) - const emailTemplateRepository = dataSource.getRepository(EmailTemplate) const menteeRepository = dataSource.getRepository(Mentee) const mentorRepository = dataSource.getRepository(Mentor) - const platformRepository = dataSource.getRepository(Platform) await menteeRepository.remove(await menteeRepository.find()) await mentorRepository.remove(await mentorRepository.find()) await profileRepository.remove(await profileRepository.find()) - await platformRepository.remove(await platformRepository.find()) await categoryRepository.remove(await categoryRepository.find()) await emailRepository.remove(await emailRepository.find()) - await emailTemplateRepository.remove(await emailTemplateRepository.find()) const genProfiles = faker.helpers.multiple(createRandomProfile, { count: 100 @@ -44,26 +38,12 @@ export const seedDatabaseService = async (): Promise => { } }, { - count: 100 + count: 30 } ) await emailRepository.save(genEmails) - const genEmailTemplates = faker.helpers.multiple( - () => { - return { - subject: faker.lorem.sentence(), - content: faker.lorem.paragraph() - } - }, - { - count: 100 - } - ) - - await emailTemplateRepository.save(genEmailTemplates) - const genCategories = faker.helpers.multiple( () => { return { @@ -71,39 +51,18 @@ export const seedDatabaseService = async (): Promise => { } }, { - count: 100 + count: 8 } ) const categories = await categoryRepository.save(genCategories) - const genPlatforms = faker.helpers.multiple( - () => { - return { - description: faker.lorem.sentence(), - mentor_questions: { - name: faker.lorem.word(), - email: faker.internet.email() - } as unknown as JSON, - image_url: faker.image.url(), - landing_page_url: faker.internet.url(), - title: faker.lorem.word() - } - }, - { - count: 100 - } - ) - - await platformRepository.save(genPlatforms) - const genMentors = ( categories: Category[], profiles: Profile[] ): Mentor[] => { - const firstTenProfiles = profiles.slice(0, 10) - - return firstTenProfiles.map((profile, index) => { - const category = categories[index] + return profiles.slice(0, 40).map((profile) => { + const category = + categories[faker.number.int({ min: 0, max: categories.length - 1 })] return createMentor(category, profile) }) } @@ -111,16 +70,28 @@ export const seedDatabaseService = async (): Promise => { const mentors = await mentorRepository.save(mentorsEntities) const genMentees = (mentors: Mentor[], profiles: Profile[]): Mentee[] => { - const lastProfilesWithoutFirstTen = profiles.slice(10, profiles.length) - - return lastProfilesWithoutFirstTen.map((profile, index) => { + return profiles.slice(40, profiles.length).map((profile) => { const mentor = mentors[faker.number.int({ min: 0, max: mentors.length - 1 })] return new Mentee( faker.helpers.enumValue(ApplicationStatus), { - name: faker.lorem.word(), - email: faker.internet.email() + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + email: faker.internet.email(), + contactNo: faker.phone.number(), + profilePic: faker.image.avatar(), + cv: faker.internet.url(), + isUndergrad: true, + consentGiven: true, + graduatedYear: faker.number.int({ + min: 1980, + max: new Date().getFullYear() + }), + university: faker.company.name() + ' University', + yearOfStudy: faker.number.int({ min: 1, max: 4 }), + course: faker.person.jobType(), + submission: faker.internet.url() }, profile, mentor @@ -145,7 +116,7 @@ const createRandomProfile = (): Partial => { first_name: faker.person.firstName(), last_name: faker.person.lastName(), image_url: faker.image.avatar(), - type: faker.helpers.enumValue(ProfileTypes), + type: ProfileTypes.DEFAULT, password: '12345' } @@ -157,7 +128,29 @@ const createMentor = (category: Category, profile: Profile): Mentor => { state: faker.helpers.enumValue(ApplicationStatus), category: category, application: { - name: faker.lorem.word(), + firstName: faker.person.firstName(), + lastName: faker.person.firstName(), + contactNo: faker.phone.number(), + country: faker.location.country(), + position: faker.person.jobTitle(), + expertise: faker.lorem.words({ min: 1, max: 3 }), + bio: faker.person.bio(), + isPastMentor: true, + reasonToMentor: null, + motivation: null, + cv: null, + menteeExpectations: faker.lorem.paragraphs({ min: 1, max: 2 }), + mentoringPhilosophy: faker.lorem.paragraphs({ min: 1, max: 2 }), + noOfMentees: faker.number.int({ min: 1, max: 10 }), + canCommit: true, + mentoredYear: faker.number.int({ + min: 2019, + max: new Date().getFullYear() + }), + category: category.uuid, + institution: faker.company.name(), + linkedin: faker.internet.url(), + website: faker.internet.url(), email: faker.internet.email() }, availability: faker.datatype.boolean(), diff --git a/src/services/admin/emailTemplate.service.test.ts b/src/services/admin/emailTemplate.service.test.ts deleted file mode 100644 index 3ea65b8a..00000000 --- a/src/services/admin/emailTemplate.service.test.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { dataSource } from '../../configs/dbConfig' -import { - createEmailTemplate, - deleteEmailTemplateById, - getEmailTemplateById -} from './emailTemplate.service' - -jest.mock('../../configs/dbConfig', () => ({ - dataSource: { - getRepository: jest.fn() - } -})) - -describe('Email Template Service', () => { - describe('createEmailTemplate', () => { - it('should create an email template successfully', async () => { - const subject = 'Test Subject' - const content = 'Test Content' - - const mockEmailTemplateRepository = { - save: jest.fn().mockResolvedValue({ - uuid: 'mock-uuid', - subject, - content, - created_at: new Date(), - updated_at: new Date(), - updateTimestamps: jest.fn(), - generateUuid: jest.fn() - } as const) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - const result = await createEmailTemplate(subject, content) - - expect(result.statusCode).toBe(201) - expect(result.emailTemplate?.subject).toBe(subject) - expect(result.emailTemplate?.content).toBe(content) - expect(result.message).toBe('Email Template created successfully') - }) - - it('should handle error during email template creation', async () => { - const subject = 'Test Subject' - const content = 'Test Content' - - const mockEmailTemplateRepository = { - save: jest.fn().mockRejectedValue(new Error('Test repository error')) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - await expect(createEmailTemplate(subject, content)).rejects.toThrowError( - 'Error creating Email Template' - ) - }) - }) - - describe('getEmailTemplateById', () => { - it('should get an email template by ID successfully', async () => { - const templateId = 'mock-uuid' - - const mockEmailTemplate = { - uuid: templateId, - subject: 'Test Subject', - content: 'Test Content', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps: jest.fn(), - generateUuid: jest.fn() - } as const - - const mockEmailTemplateRepository = { - findOne: jest.fn().mockResolvedValue(mockEmailTemplate) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - const result = await getEmailTemplateById(templateId) - - expect(result.statusCode).toBe(200) - expect(result.emailTemplate?.uuid).toBe(templateId) - expect(result.emailTemplate?.subject).toBe(mockEmailTemplate.subject) - expect(result.emailTemplate?.content).toBe(mockEmailTemplate.content) - expect(result.message).toBe('Email template found') - }) - - it('should handle email template not found', async () => { - const templateId = 'nonexistent-uuid' - - const mockEmailTemplateRepository = { - findOne: jest.fn().mockResolvedValue(null) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - const result = await getEmailTemplateById(templateId) - - expect(result.statusCode).toBe(404) - expect(result.message).toBe('Email template not found') - }) - - it('should handle error during email template retrieval', async () => { - const templateId = 'mock-uuid' - - const mockEmailTemplateRepository = { - findOne: jest.fn().mockRejectedValue(new Error('Test repository error')) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - await expect(getEmailTemplateById(templateId)).rejects.toThrowError( - 'Error getting email template' - ) - }) - }) - - describe('deleteEmailTemplateById', () => { - it('should delete an email template by ID successfully', async () => { - const templateId = 'mock-uuid' - - const mockEmailTemplateRepository = { - findOne: jest.fn().mockResolvedValue({ - uuid: templateId, - subject: 'Test Subject', - content: 'Test Content', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps: jest.fn(), - generateUuid: jest.fn() - }), - remove: jest.fn().mockResolvedValue({ - uuid: templateId, - subject: 'Test Subject', - content: 'Test Content', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps: jest.fn(), - generateUuid: jest.fn() - }) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - const result = await deleteEmailTemplateById(templateId) - - expect(result.statusCode).toBe(200) - expect(result.message).toBe('Email template deleted successfully') - }) - - it('should handle email template not found during deletion', async () => { - const templateId = 'nonexistent-uuid' - - const mockEmailTemplateRepository = { - findOne: jest.fn().mockResolvedValue(null) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - const result = await deleteEmailTemplateById(templateId) - - expect(result.statusCode).toBe(404) - expect(result.message).toBe('Email template not found') - }) - - it('should handle error during email template deletion', async () => { - const templateId = 'mock-uuid' - - const mockEmailTemplateRepository = { - findOne: jest.fn().mockResolvedValue({ - uuid: templateId, - subject: 'Test Subject', - content: 'Test Content', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps: jest.fn(), - generateUuid: jest.fn() - }), - remove: jest.fn().mockRejectedValue(new Error('Test repository error')) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockEmailTemplateRepository - ) - - await expect(deleteEmailTemplateById(templateId)).rejects.toThrowError( - 'Error deleting email template' - ) - }) - }) -}) diff --git a/src/services/admin/emailTemplate.service.ts b/src/services/admin/emailTemplate.service.ts deleted file mode 100644 index d14d5524..00000000 --- a/src/services/admin/emailTemplate.service.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { dataSource } from '../../configs/dbConfig' -import EmailTemplate from '../../entities/emailTemplate.entity' - -export const createEmailTemplate = async ( - subject: string, - content: string -): Promise<{ - statusCode: number - emailTemplate?: EmailTemplate | null - message: string -}> => { - try { - const emailTemplateRepositroy = dataSource.getRepository(EmailTemplate) - - const newEmailTemplate = new EmailTemplate(subject, content) - - const savedEmailTemplate = await emailTemplateRepositroy.save( - newEmailTemplate - ) - - return { - statusCode: 201, - emailTemplate: savedEmailTemplate, - message: 'Email Template created successfully' - } - } catch (err) { - console.error('Error creating Email Template', err) - throw new Error('Error creating Email Template') - } -} - -export const getEmailTemplateById = async ( - templateId: string -): Promise<{ - statusCode: number - emailTemplate?: EmailTemplate | null - message: string -}> => { - try { - const emailRepository = dataSource.getRepository(EmailTemplate) - - const emailTemplate = await emailRepository.findOne({ - where: { uuid: templateId }, - select: ['uuid', 'content', 'subject'] - }) - - if (!emailTemplate) { - return { - statusCode: 404, - message: 'Email template not found' - } - } - - return { - statusCode: 200, - emailTemplate, - message: 'Email template found' - } - } catch (err) { - console.error('Error getting email template', err) - throw new Error('Error getting email template') - } -} - -export const deleteEmailTemplateById = async ( - templateId: string -): Promise<{ - statusCode: number - message: string -}> => { - try { - const emailRepository = dataSource.getRepository(EmailTemplate) - - const emailTemplate = await emailRepository.findOne({ - where: { uuid: templateId } - }) - - if (!emailTemplate) { - return { - statusCode: 404, - message: 'Email template not found' - } - } - - await emailRepository.remove(emailTemplate) - - return { - statusCode: 200, - message: 'Email template deleted successfully' - } - } catch (err) { - console.error('Error deleting email template', err) - throw new Error('Error deleting email template') - } -} diff --git a/src/services/admin/platform.service.test.ts b/src/services/admin/platform.service.test.ts deleted file mode 100644 index f00595fe..00000000 --- a/src/services/admin/platform.service.test.ts +++ /dev/null @@ -1,199 +0,0 @@ -import { - createPlatform, - getPlatformDetails, - updatePlatformDetails -} from './platform.service' -import { dataSource } from '../../configs/dbConfig' -import type Platform from '../../entities/platform.entity' -import { v4 as uuidv4 } from 'uuid' - -jest.mock('../../configs/dbConfig', () => ({ - dataSource: { - getRepository: jest.fn() - } -})) - -describe('Platform Service', () => { - describe('createPlatform', () => { - it('should create a platform successfully', async () => { - const mockPlatform: Platform = { - uuid: 'mock-uuid', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps() { - this.updated_at = new Date() - if (!this.uuid) { - this.created_at = new Date() - } - }, - generateUuid: async function () { - if (!this.uuid) { - this.uuid = uuidv4() - } - }, - description: 'Mock Platform Description', - mentor_questions: {} as unknown as JSON, - image_url: 'https://example.com/mock-image.jpg', - landing_page_url: 'https://example.com/mock-landing-page', - title: 'Mock Platform Title' - } - - const mockPlatformRepository = { - save: jest.fn().mockResolvedValue(mockPlatform) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - const result = await createPlatform(mockPlatform) - - expect(result.statusCode).toBe(201) - expect(result.platform).toEqual(mockPlatform) - expect(result.message).toBe('Platform created successfully ') - }) - - it('should handle error during platform creation', async () => { - const mockPlatformRepository = { - save: jest.fn().mockRejectedValue(new Error('Test repository error')) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - await expect( - createPlatform({} as unknown as Platform) - ).rejects.toThrowError('Error creating Platform') - }) - }) - - describe('getPlatformDetails', () => { - it('should get platform details successfully', async () => { - const mockPlatform: Platform = { - uuid: 'mock-uuid', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps() { - this.updated_at = new Date() - if (!this.uuid) { - this.created_at = new Date() - } - }, - generateUuid: async function () { - if (!this.uuid) { - this.uuid = uuidv4() - } - }, - description: 'Mock Platform Description', - mentor_questions: {} as unknown as JSON, - image_url: 'https://example.com/mock-image.jpg', - landing_page_url: 'https://example.com/mock-landing-page', - title: 'Mock Platform Title' - } - const mockPlatforms: Platform[] = [mockPlatform] - - const mockPlatformRepository = { - find: jest.fn().mockResolvedValue(mockPlatforms) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - const result = await getPlatformDetails() - - expect(result.statusCode).toBe(200) - expect(result.platform).toEqual(mockPlatforms) - expect(result.message).toBe('Get Platform details successfully') - }) - - it('should handle error during platform details retrieval', async () => { - const mockPlatformRepository = { - find: jest.fn().mockRejectedValue(new Error('Test repository error')) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - await expect(getPlatformDetails()).rejects.toThrowError( - 'Error creating Platform' - ) - }) - }) - - describe('updatePlatformDetails', () => { - it('should update platform details successfully', async () => { - const mockPlatform: Platform = { - uuid: 'mock-uuid', - created_at: new Date(), - updated_at: new Date(), - updateTimestamps() { - this.updated_at = new Date() - if (!this.uuid) { - this.created_at = new Date() - } - }, - generateUuid: async function () { - if (!this.uuid) { - this.uuid = uuidv4() - } - }, - description: 'Mock Platform Description', - mentor_questions: {} as unknown as JSON, - image_url: 'https://example.com/mock-image.jpg', - landing_page_url: 'https://example.com/mock-landing-page', - title: 'Mock Platform Title' - } - - const mockPlatformRepository = { - update: jest.fn().mockResolvedValue({ affected: 1 }), - findOne: jest.fn().mockResolvedValue(mockPlatform) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - const result = await updatePlatformDetails({ - uuid: 'mock-uuid' - } as unknown as Platform) - - expect(result.statusCode).toBe(200) - expect(result.platform).toEqual(mockPlatform) - expect(result.message).toBe('Platform updated successfully') - }) - - it('should handle platform not found during update', async () => { - const mockPlatformRepository = { - update: jest.fn().mockResolvedValue({ affected: 0 }) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - const result = await updatePlatformDetails({ - uuid: 'nonexistent-uuid' - } as unknown as Platform) - - expect(result.statusCode).toBe(404) - expect(result.message).toBe('Platform not found') - }) - - it('should handle error during platform update', async () => { - const mockPlatformRepository = { - update: jest.fn().mockRejectedValue(new Error('Test repository error')) - } - - ;(dataSource.getRepository as jest.Mock).mockReturnValueOnce( - mockPlatformRepository - ) - - await expect( - updatePlatformDetails({} as unknown as Platform) - ).rejects.toThrowError('Error updating platform') - }) - }) -}) diff --git a/src/services/admin/platform.service.ts b/src/services/admin/platform.service.ts deleted file mode 100644 index 1c3f8314..00000000 --- a/src/services/admin/platform.service.ts +++ /dev/null @@ -1,105 +0,0 @@ -import Platform from '../../entities/platform.entity' -import { dataSource } from '../../configs/dbConfig' - -export const createPlatform = async ({ - description, - mentor_questions, - image_url, - landing_page_url, - title -}: Platform): Promise<{ - statusCode: number - platform?: Platform | null - message: string -}> => { - try { - const platformRepository = dataSource.getRepository(Platform) - - const newPlatform = new Platform( - description, - mentor_questions, - image_url, - landing_page_url, - title - ) - - const savedPlatform = await platformRepository.save(newPlatform) - - return { - statusCode: 201, - platform: savedPlatform, - message: 'Platform created successfully ' - } - } catch (err) { - console.error('Error creating Platform', err) - throw new Error('Error creating Platform') - } -} - -export const getPlatformDetails = async (): Promise<{ - statusCode: number - platform?: Platform[] | null - message: string -}> => { - try { - const platformRepository = dataSource.getRepository(Platform) - - const platform = await platformRepository.find() - - return { - statusCode: 200, - platform, - message: 'Get Platform details successfully' - } - } catch (err) { - console.error('Error creating Platform', err) - throw new Error('Error creating Platform') - } -} - -export const updatePlatformDetails = async ({ - uuid, - description, - mentor_questions, - image_url, - landing_page_url, - title -}: Platform): Promise<{ - statusCode: number - platform?: Platform | null - message: string -}> => { - try { - const platformRepository = dataSource.getRepository(Platform) - - const updateData = { - description, - mentor_questions, - image_url, - landing_page_url, - title - } - - const result = await platformRepository.update({ uuid }, updateData) - - if (result.affected === 0) { - return { - statusCode: 404, - message: 'Platform not found' - } - } - - const updatedPlatform = await platformRepository.findOne({ - where: { uuid } - }) - - return { - statusCode: 200, - platform: updatedPlatform, - message: 'Platform updated successfully' - } - } catch (err) { - console.error('Error updateing platform', err) - throw new Error('Error updating platform') - } -}