diff --git a/.github/workflows/deploy_frontend.yml b/.github/workflows/deploy_frontend.yml
new file mode 100644
index 00000000..e090378e
--- /dev/null
+++ b/.github/workflows/deploy_frontend.yml
@@ -0,0 +1,42 @@
+name: Frontend Deployment
+on:
+ workflow_dispatch
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout backend
+ uses: actions/checkout@v2
+ with:
+ ref: deployment
+ path: backend
+ - name: Checkout frontend
+ uses: actions/checkout@v2
+ with:
+ repository: sef-global/scholarx-frontend
+ ref: master
+ path: frontend
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v2
+ with:
+ node-version: ${{ matrix.node-version }}
+ - name: Install dependencies and Build Frontend
+ run: |
+ cd frontend
+ npm ci
+ npm run build
+ - name: Copy static files
+ run: |
+ cp frontend/dist/bundle.js backend/src/main/resources/static/
+ cp frontend/dist/index.html backend/src/main/resources/static/
+ - name: Create Pull Request
+ uses: peter-evans/create-pull-request@v3.12.1
+ with:
+ path: backend
+ commit-message: '[Bot] Deploy the latest frontend'
+ title: '[Bot] Deploy the latest frontend'
+ body: |
+ Update report
+ - Auto-generated by [create-pull-request][1]
+ - Please add the new features/bug fixes list before merging
+ [1]: https://github.com/peter-evans/create-pull-request
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..344d4eb4
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,28 @@
+# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
+# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
+
+name: Java CI with Maven
+
+on:
+ push:
+ branches: [ development ]
+ pull_request:
+ branches: [ development ]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 1.8
+ uses: actions/setup-java@v2
+ with:
+ java-version: '8'
+ distribution: 'adopt'
+ cache: maven
+ - name: Configure build
+ run: cp src/main/resources/application.yml.example src/main/resources/application.yml
+ - name: Build and Run Tests with Maven
+ run: mvn clean install
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 62be52cd..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: java
-install:
- - git clone https://github.com/sef-global/scholarx-frontend
- - cd scholarx-frontend
- - git checkout master
- - npm install
- - npm run build
- - cd ../
-before_script:
- - mkdir -p src/main/resources/static
- - cp -r scholarx-frontend/dist/. src/main/resources/static/
- - sudo rm -R scholarx-frontend
- - cp src/main/resources/application.yml.example src/main/resources/application.yml
-script:
- - mvn clean install
-deploy:
- provider: heroku
- api_key: $HEROKU_API_KEY
- app: sef-scholarx
- on:
- repo: sef-global/scholarx
- branch: master
- skip_cleanup: true
diff --git a/README.md b/README.md
index a476a261..f76a59fd 100644
--- a/README.md
+++ b/README.md
@@ -2,40 +2,88 @@
Backend of the ScholarX project
-### Setting up the project for development
+## Setting up the project for development
-**Prerequisites**
+### Prerequisites
* Java
* Maven
-* MySQL
+* PostgreSQL
* Linkedin Social Login App
* Gmail Account with an App Password
-**Setup Linkedin Social Login App**
+### Setup Linkedin Social Login App
1. Create a new Linkedin App ([help?](https://docs.ultimatemember.com/article/142-social-login-linkedin-app-setup))
2. Click on `Auth` tab and add `http://localhost:8080/login/oauth2/code/linkedin` as an authorised redirect URL
3. Make Sure you have properly added the `Sign in with Linkedin product` under products tab
-**Setup a gmail account with an app password**
+### Setup a gmail account with an app password
1. Create a new gmail account if you don't have one already
2. Enable Two Factor Authorisation
-3. Generate a new `App Password` ([help?](https://support.google.com/mail/answer/185833?hl=en-GB))
+3. Generate a new `App Password` ([help?](https://support.google.com/mail/answer/185833?hl=en-GB))
-**Steps**
+### Run Locally
1. Fork and clone the repository
-```
+```shell
git clone https://github.com//scholarx
```
2. Open the cloned repo, Find and open the `application.yml` file
-3. Replace the `client-id` and `client-secret` with the values from the above linkedin social app
-
-4. Replace the mail username and password values with the generated `App Password` and the corresponding gmail address
-
-5. Replace the datasource dummy values with your local mysql server instance credentials
-
-6. Run the application
+3. Replace the `${client-id}` and `${client-secret}` with the values from the above linkedin social app
+example:
+```yaml
+ linkedin:
+ client-id: 324780jdsfg2u4
+ client-secret: MsdfsdfggsqPFh
+ client-authentication-method: post
+ authorization-grant-type: authorization_code
+```
+
+4. Replace the mail `username` and `password` values with the generated `App Password` and the corresponding gmail address
+example:
+```yaml
+ mail:
+ host: smtp.gmail.com
+ port: 587
+ username: samplemail@gmail.com
+ password: jhdfklsdjjadskt
+ properties:
+```
+5. Replace the datasource dummy values with your local mysql server instance credentials
+example:
+```yaml
+ datasource:
+ url: jdbc:postgresql://localhost:5432/scholarx_DB?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
+ username: rootuser
+ password: rootpassword
+ platform: postgres
```
+
+6. Run the application
+```shell
mvn spring-boot:run
```
+
+### Configuring a MySQL Database (Optional)
+
+1. Add the `mysql-connector-java` dependency to the `pom.xml` file.
+```xml
+
+ mysql
+ mysql-connector-java
+ runtime
+
+```
+
+2. Replace the `spring.jpa` and `spring.datasource` configurations in `application.yml` with the following configuration.
+```yaml
+ jpa:
+ database: postgresql
+ hibernate:
+ ddl-auto: update
+ datasource:
+ url: jdbc:postgresql://${DB_URL}/${DB_NAME}?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
+ username: ${DB_USER_NAME}
+ password: ${DB_USER_PASSWORD}
+ platform: postgres
+```
diff --git a/pom.xml b/pom.xml
index 3bdd5078..f0061dbf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
@@ -19,58 +19,57 @@
spring-boot-starter-webflux
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-actuator
-
-
- org.springframework.boot
- spring-boot-starter-validation
-
-
- org.springframework.boot
- spring-boot-starter-security
-
-
- org.springframework.boot
- spring-boot-starter-data-jpa
-
-
- org.springframework.boot
- spring-boot-starter-mail
- 2.3.10.RELEASE
-
-
- org.springframework.boot
- spring-boot-starter-tomcat
- provided
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
- org.thymeleaf
- thymeleaf-spring5
-
-
- nz.net.ultraq.thymeleaf
- thymeleaf-layout-dialect
-
-
- mysql
- mysql-connector-java
- runtime
-
-
- javax.servlet
- servlet-api
- 2.5
- provided
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-mail
+ 2.3.10.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+ provided
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.thymeleaf
+ thymeleaf-spring5
+
+
+ nz.net.ultraq.thymeleaf
+ thymeleaf-layout-dialect
+
+
+ org.postgresql
+ postgresql
+
+
+ javax.servlet
+ servlet-api
+ 2.5
+ provided
org.springframework.boot
@@ -90,7 +89,12 @@
org.springframework.security
spring-security-core
- 5.3.10.RELEASE
+ 5.5.7
+
+
+ org.springframework.security
+ spring-security-test
+ 5.3.3.RELEASE
@@ -99,45 +103,45 @@
4.5.13
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.junit.vintage
- junit-vintage-engine
-
-
- com.vaadin.external.google
- android-json
-
-
-
-
- io.springfox
- springfox-swagger2
- ${swagger.version}
-
-
- io.springfox
- springfox-swagger-ui
- ${swagger.version}
-
-
- io.springfox
- springfox-bean-validators
- ${swagger.version}
-
-
- commons-lang
- commons-lang
- 2.6
-
-
- org.projectlombok
- lombok
- true
-
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+ com.vaadin.external.google
+ android-json
+
+
+
+
+ io.springfox
+ springfox-swagger2
+ ${swagger.version}
+
+
+ io.springfox
+ springfox-swagger-ui
+ ${swagger.version}
+
+
+ io.springfox
+ springfox-bean-validators
+ ${swagger.version}
+
+
+ commons-lang
+ commons-lang
+ 2.6
+
+
+ org.projectlombok
+ lombok
+ true
+
@@ -158,6 +162,6 @@
- 2.9.2
-
+ 2.9.2
+
diff --git a/pull_request_template.md b/pull_request_template.md
index 2ec6c588..d392da9f 100644
--- a/pull_request_template.md
+++ b/pull_request_template.md
@@ -10,11 +10,6 @@ The purpose of this PR is to fix #
### Screenshots
-
-### Preview Link
-
-
-https://pr-{PR_NUMBER}-sef-site.surge.sh/
## Checklist
- [x] This PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.
diff --git a/src/main/java/org/sefglobal/scholarx/config/SecurityConfig.java b/src/main/java/org/sefglobal/scholarx/config/SecurityConfig.java
index eac48093..ca3b84bf 100644
--- a/src/main/java/org/sefglobal/scholarx/config/SecurityConfig.java
+++ b/src/main/java/org/sefglobal/scholarx/config/SecurityConfig.java
@@ -56,6 +56,8 @@ protected void configure(HttpSecurity http) throws Exception {
.permitAll()
.antMatchers("/api/programs/*/mentors")
.permitAll()
+ .antMatchers("/api/mentors/*")
+ .permitAll()
.antMatchers("/api/**")
.authenticated()
.anyRequest()
diff --git a/src/main/java/org/sefglobal/scholarx/controller/AuthUserController.java b/src/main/java/org/sefglobal/scholarx/controller/AuthUserController.java
index 11bf982e..7e52c9e2 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/AuthUserController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/AuthUserController.java
@@ -65,15 +65,4 @@ public List getMentees(
Profile profile = (Profile) authentication.getPrincipal();
return introspectionService.getMentees(id, profile.getId(), menteeStates);
}
-
- @PutMapping("/mentor/{id}/confirmation")
- @ResponseStatus(HttpStatus.OK)
- public Mentee confirmMentor(
- @PathVariable long id,
- Authentication authentication
- )
- throws ResourceNotFoundException, BadRequestException {
- Profile profile = (Profile) authentication.getPrincipal();
- return introspectionService.confirmMentor(id, profile.getId());
- }
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/MenteeController.java b/src/main/java/org/sefglobal/scholarx/controller/MenteeController.java
index 9d8fe734..1d8efa6f 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/MenteeController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/MenteeController.java
@@ -1,14 +1,23 @@
package org.sefglobal.scholarx.controller;
+import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.exception.UnauthorizedException;
+import org.sefglobal.scholarx.model.Comment;
import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.service.CommentService;
import org.sefglobal.scholarx.service.MenteeService;
import org.springframework.http.HttpStatus;
+import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
@@ -19,20 +28,64 @@
public class MenteeController {
private final MenteeService menteeService;
+ private final CommentService commentService;
- public MenteeController(MenteeService menteeService) {
+ public MenteeController(MenteeService menteeService,CommentService commentService) {
this.menteeService = menteeService;
+ this.commentService = commentService;
+ }
+
+ @PostMapping("/{id}/comments")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Comment addComment(
+ Authentication authentication,
+ @Valid @RequestBody Comment comment,
+ @PathVariable long id)
+ throws ResourceNotFoundException, UnauthorizedException {
+ Profile profile = (Profile) authentication.getPrincipal();
+ return commentService.addMenteeComment(id,profile.getId(), comment);
+ }
+
+ @GetMapping("/{id}/comments")
+ @ResponseStatus(HttpStatus.OK)
+ public List getMenteesComments(
+ Authentication authentication,
+ @PathVariable long id
+ )
+ throws ResourceNotFoundException, BadRequestException, UnauthorizedException {
+ Profile profile = (Profile) authentication.getPrincipal();
+ return commentService.getAllMenteeComments(id,profile.getId());
+ }
+
+ @PutMapping("/comment/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ public Comment updateComment(@PathVariable long id,
+ Authentication authentication,
+ @Valid @RequestBody Comment comment)
+ throws ResourceNotFoundException, BadRequestException, UnauthorizedException {
+ Profile profile = (Profile) authentication.getPrincipal();
+ return commentService.updateComment(id, profile.getId(), comment);
+ }
+
+ @DeleteMapping("/comment/{id}")
+ @ResponseStatus(HttpStatus.NO_CONTENT)
+ public void deleteMenteeComment(@PathVariable long id,Authentication authentication)
+ throws ResourceNotFoundException, UnauthorizedException {
+ Profile profile = (Profile) authentication.getPrincipal();
+ commentService.deleteComment(id, profile.getId());
}
@PutMapping("/{id}/state")
@ResponseStatus(HttpStatus.OK)
public Mentee approveOrRejectMentee(@PathVariable long id,
+ Authentication authentication,
@Valid @RequestBody Map payload)
- throws ResourceNotFoundException, BadRequestException {
+ throws ResourceNotFoundException, BadRequestException, UnauthorizedException {
+ Profile profile = (Profile) authentication.getPrincipal();
if (!payload.containsKey("isApproved")) {
String msg = "Error, Value cannot be null.";
throw new BadRequestException(msg);
}
- return menteeService.approveOrRejectMentee(id, payload.get("isApproved"));
+ return menteeService.approveOrRejectMentee(id, profile.getId(), payload.get("isApproved"));
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/MentorController.java b/src/main/java/org/sefglobal/scholarx/controller/MentorController.java
index 17183ec8..d0f13312 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/MentorController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/MentorController.java
@@ -67,27 +67,4 @@ public List getMenteesOfMentor(
throws ResourceNotFoundException, BadRequestException {
return mentorService.getAllMenteesOfMentor(id, state);
}
-
- @PutMapping("/{id}/mentee")
- @ResponseStatus(HttpStatus.OK)
- public Mentee updateMenteeData(
- @PathVariable long id,
- Authentication authentication,
- @Valid @RequestBody Mentee mentee
- )
- throws ResourceNotFoundException, BadRequestException {
- Profile profile = (Profile) authentication.getPrincipal();
- return mentorService.updateMenteeData(profile.getId(), id, mentee);
- }
-
- @GetMapping("/{id}/mentee")
- @ResponseStatus(HttpStatus.OK)
- public Mentee getLoggedInMentee(
- @PathVariable long id,
- Authentication authentication
- )
- throws NoContentException {
- Profile profile = (Profile) authentication.getPrincipal();
- return mentorService.getLoggedInMentee(id, profile.getId());
- }
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/ProgramController.java b/src/main/java/org/sefglobal/scholarx/controller/ProgramController.java
index cf8022ff..5a32faba 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/ProgramController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/ProgramController.java
@@ -9,7 +9,6 @@
import org.sefglobal.scholarx.service.ProgramService;
import org.sefglobal.scholarx.util.EnrolmentState;
import org.sefglobal.scholarx.util.ProgramState;
-import org.sefglobal.scholarx.util.QuestionCategory;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
@@ -60,11 +59,23 @@ public List getAllMentorsByProgramId(
public Mentor applyAsMentor(
@PathVariable long id,
Authentication authentication,
- @Valid @RequestBody List responses
+ @Valid @RequestBody Mentor mentor
)
throws ResourceNotFoundException, BadRequestException {
Profile profile = (Profile) authentication.getPrincipal();
- return programService.applyAsMentor(id, profile.getId(), responses);
+ return programService.applyAsMentor(id, profile.getId(), mentor);
+ }
+
+ @PutMapping("/{id}/mentor")
+ @ResponseStatus(HttpStatus.OK)
+ public Mentor updateMentorApplication(
+ @PathVariable long id,
+ Authentication authentication,
+ @Valid @RequestBody Mentor mentor
+ )
+ throws ResourceNotFoundException, BadRequestException {
+ Profile profile = (Profile) authentication.getPrincipal();
+ return programService.updateMentorApplication(id, profile.getId(), mentor);
}
@GetMapping("/{id}/mentor")
@@ -80,16 +91,14 @@ public Mentor getLoggedInMentor(
@GetMapping("/{id}/mentee/mentors")
@ResponseStatus(HttpStatus.OK)
- public List getAppliedMentors(
+ public Mentor getAppliedMentor(
@PathVariable long id,
- @RequestParam(required = false) List menteeStates,
Authentication authentication
)
throws NoContentException {
Profile profile = (Profile) authentication.getPrincipal();
- return programService.getAppliedMentorsOfMentee(
+ return programService.getAppliedMentorOfMentee(
id,
- menteeStates,
profile.getId()
);
}
@@ -105,36 +114,26 @@ public Mentor getSelectedMentor(
return programService.getSelectedMentor(id, profile.getId());
}
- @GetMapping("/{id}/questions/{category}")
+ @PutMapping("/{id}/mentee")
@ResponseStatus(HttpStatus.OK)
- public List getQuestions(@PathVariable long id,
- @PathVariable QuestionCategory category) throws ResourceNotFoundException {
- return programService.getQuestions(id, category);
- }
-
- @GetMapping("/{id}/responses/mentor")
- @ResponseStatus(HttpStatus.OK)
- public List getMentorResponses(
- @PathVariable long id,
- Authentication authentication,
- @RequestParam(required = false) Long mentorId
+ public Mentee updateMenteeData(
+ @PathVariable long id,
+ Authentication authentication,
+ @Valid @RequestBody Mentee mentee
)
- throws ResourceNotFoundException {
- if (mentorId != null) {
- return programService.getMentorResponses(mentorId);
- }
+ throws ResourceNotFoundException, BadRequestException {
Profile profile = (Profile) authentication.getPrincipal();
- return programService.getMentorResponses(id, profile.getId());
+ return programService.updateMenteeData(profile.getId(), id, mentee);
}
- @PutMapping("/{id}/responses/mentor")
- public List editMentorResponses(
+ @GetMapping("/{id}/mentee")
+ @ResponseStatus(HttpStatus.OK)
+ public Mentee getLoggedInMentee(
@PathVariable long id,
- Authentication authentication,
- @RequestBody List responses
+ Authentication authentication
)
- throws ResourceNotFoundException, BadRequestException {
+ throws NoContentException {
Profile profile = (Profile) authentication.getPrincipal();
- return programService.editMentorResponses(id, profile.getId(), responses);
+ return programService.getLoggedInMentee(id, profile.getId());
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/admin/MenteeController.java b/src/main/java/org/sefglobal/scholarx/controller/admin/MenteeController.java
index 1e1a5b5c..68d55adf 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/admin/MenteeController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/admin/MenteeController.java
@@ -1,13 +1,15 @@
package org.sefglobal.scholarx.controller.admin;
+import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.model.Mentee;
import org.sefglobal.scholarx.service.MenteeService;
+import org.sefglobal.scholarx.util.EnrolmentState;
import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseStatus;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Map;
@RestController("MenteeAdminController")
@RequestMapping("/api/admin/mentees")
@@ -25,4 +27,19 @@ public void deleteMentee(@PathVariable long id)
throws ResourceNotFoundException {
menteeService.deleteMentee(id);
}
+
+ @PutMapping("/{id}/assign")
+ @ResponseStatus(HttpStatus.OK)
+ public Mentee updateAssignedMentor(@PathVariable long id,
+ @Valid @RequestBody Map payload)
+ throws ResourceNotFoundException, BadRequestException {
+ return menteeService.updateAssignedMentor(id, payload.get("mentorId"));
+ }
+
+ @PutMapping("/{id}/state")
+ public Mentee changeState(@PathVariable long id,
+ @Valid @RequestBody Map payload)
+ throws ResourceNotFoundException, BadRequestException {
+ return menteeService.changeState(id, payload.get("state"));
+ }
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/admin/MentorController.java b/src/main/java/org/sefglobal/scholarx/controller/admin/MentorController.java
index 030e77e1..fb97f21b 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/admin/MentorController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/admin/MentorController.java
@@ -2,6 +2,8 @@
import java.util.Map;
import javax.validation.Valid;
+
+import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
import org.sefglobal.scholarx.model.Mentor;
import org.sefglobal.scholarx.service.MentorService;
@@ -28,7 +30,7 @@ public MentorController(MentorService mentorService) {
@ResponseStatus(HttpStatus.OK)
public Mentor updateState(@PathVariable long id,
@Valid @RequestBody Map payload)
- throws ResourceNotFoundException {
+ throws ResourceNotFoundException, BadRequestException {
return mentorService.updateState(id, payload.get("state"));
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/admin/ProgramController.java b/src/main/java/org/sefglobal/scholarx/controller/admin/ProgramController.java
index 7404cf06..b81653b1 100644
--- a/src/main/java/org/sefglobal/scholarx/controller/admin/ProgramController.java
+++ b/src/main/java/org/sefglobal/scholarx/controller/admin/ProgramController.java
@@ -3,15 +3,13 @@
import java.util.List;
import javax.validation.Valid;
-import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.model.BulkEmailDto;
import org.sefglobal.scholarx.model.Mentee;
import org.sefglobal.scholarx.model.Mentor;
import org.sefglobal.scholarx.model.Program;
-import org.sefglobal.scholarx.model.Question;
import org.sefglobal.scholarx.service.ProgramService;
import org.sefglobal.scholarx.util.EnrolmentState;
-import org.sefglobal.scholarx.util.QuestionCategory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -73,12 +71,18 @@ public List getAllMenteesByProgramId(@PathVariable long id)
return programService.getAllMenteesByProgramId(id);
}
- @PostMapping("/{id}/questions/{category}")
+ @GetMapping("/{id}/emails")
@ResponseStatus(HttpStatus.OK)
- public List addQuestions(@PathVariable long id,
- @PathVariable QuestionCategory category,
- @RequestBody List questions)
- throws ResourceNotFoundException, BadRequestException {
- return programService.addQuestions(id, category, questions);
+ public List getAllEmailAddresses(@PathVariable long id)
+ throws ResourceNotFoundException {
+ return programService.getEmailsAddresses(id);
+ }
+
+ @PostMapping("/{id}/email")
+ @ResponseStatus(HttpStatus.OK)
+ public void sendBulkEmails(@PathVariable long id,
+ @Valid @RequestBody BulkEmailDto bulkEmailDto)
+ throws ResourceNotFoundException {
+ programService.sendBulkEmails(id, bulkEmailDto);
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/controller/admin/QuestionController.java b/src/main/java/org/sefglobal/scholarx/controller/admin/QuestionController.java
deleted file mode 100644
index fb776403..00000000
--- a/src/main/java/org/sefglobal/scholarx/controller/admin/QuestionController.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.sefglobal.scholarx.controller.admin;
-
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.model.Question;
-import org.sefglobal.scholarx.service.QuestionService;
-import org.springframework.http.HttpStatus;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.List;
-
-@RestController
-@RequestMapping("/api/admin/questions")
-public class QuestionController {
- private final QuestionService questionService;
-
- public QuestionController(QuestionService questionService) {
- this.questionService = questionService;
- }
-
- @PutMapping
- @ResponseStatus(HttpStatus.OK)
- public List editQuestions(@RequestBody List questions)
- throws ResourceNotFoundException, BadRequestException {
- return questionService.editQuestions(questions);
- }
-
- @DeleteMapping("/{id}")
- @ResponseStatus(HttpStatus.NO_CONTENT)
- public void deleteQuestion(@PathVariable long id) throws ResourceNotFoundException, BadRequestException {
- questionService.deleteQuestion(id);
- }
-}
diff --git a/src/main/java/org/sefglobal/scholarx/model/BulkEmailDto.java b/src/main/java/org/sefglobal/scholarx/model/BulkEmailDto.java
new file mode 100644
index 00000000..c9b39d27
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/model/BulkEmailDto.java
@@ -0,0 +1,44 @@
+package org.sefglobal.scholarx.model;
+
+import org.sefglobal.scholarx.util.MailGroup;
+
+import java.util.List;
+
+public class BulkEmailDto {
+ private String subject;
+ private String message;
+ private List mailGroups;
+ private List additionalEmails;
+
+ public String getSubject() {
+ return subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public List getMailGroups() {
+ return mailGroups;
+ }
+
+ public void setMailGroups(List mailGroups) {
+ this.mailGroups = mailGroups;
+ }
+
+ public List getAdditionalEmails() {
+ return additionalEmails;
+ }
+
+ public void setAdditionalEmails(List additionalEmails) {
+ this.additionalEmails = additionalEmails;
+ }
+}
diff --git a/src/main/java/org/sefglobal/scholarx/model/Comment.java b/src/main/java/org/sefglobal/scholarx/model/Comment.java
new file mode 100644
index 00000000..4e22b976
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/model/Comment.java
@@ -0,0 +1,43 @@
+package org.sefglobal.scholarx.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.ManyToOne;
+
+@Entity
+@Table(name = "comment")
+public class Comment extends BaseScholarxModel {
+ @ManyToOne
+ private Mentee mentee;
+
+ @Column
+ private String comment;
+
+ @ManyToOne
+ private Profile commented_by;
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+
+ public Profile getCommented_by() {
+ return commented_by;
+ }
+
+ public void setCommented_by(Profile commented_by) {
+ this.commented_by = commented_by;
+ }
+
+ public Mentee getMentee() {
+ return mentee;
+ }
+
+ public void setMentee(Mentee mentee) {
+ this.mentee = mentee;
+ }
+}
diff --git a/src/main/java/org/sefglobal/scholarx/model/EnrolledUser.java b/src/main/java/org/sefglobal/scholarx/model/EnrolledUser.java
index ffe12036..50dbadfe 100644
--- a/src/main/java/org/sefglobal/scholarx/model/EnrolledUser.java
+++ b/src/main/java/org/sefglobal/scholarx/model/EnrolledUser.java
@@ -17,7 +17,7 @@ public abstract class EnrolledUser extends BaseScholarxModel {
private Profile profile;
@Enumerated(EnumType.STRING)
- @Column(length = 10, nullable = false)
+ @Column(length = 20, nullable = false)
private EnrolmentState state;
@ManyToOne(optional = false)
diff --git a/src/main/java/org/sefglobal/scholarx/model/Mentee.java b/src/main/java/org/sefglobal/scholarx/model/Mentee.java
index ba7d59f0..67a322d2 100644
--- a/src/main/java/org/sefglobal/scholarx/model/Mentee.java
+++ b/src/main/java/org/sefglobal/scholarx/model/Mentee.java
@@ -15,29 +15,114 @@ public class Mentee extends EnrolledUser {
public Mentee() {
}
- public Mentee(String submissionUrl) {
- this.submissionUrl = submissionUrl;
- }
+ @Column
+ private String university;
+
+ @Column
+ private String course;
+
+ @Column
+ private String year;
+
+ @Column(columnDefinition = "TEXT")
+ private String intent;
+
+ @Column(columnDefinition = "TEXT")
+ private String reasonForChoice;
+
+ @Column(columnDefinition = "TEXT")
+ private String resumeUrl;
+
+ @Column(columnDefinition = "TEXT")
+ private String achievements;
@ManyToOne(optional = false)
- private Mentor mentor;
+ private Mentor appliedMentor;
+
+ @ManyToOne
+ private Mentor assignedMentor;
+
+ @ManyToOne
+ private Mentor rejectedBy;
+
+ public Mentor getAppliedMentor() {
+ return appliedMentor;
+ }
+
+ public void setAppliedMentor(Mentor appliedMentor) {
+ this.appliedMentor = appliedMentor;
+ }
+
+ public Mentor getAssignedMentor() {
+ return assignedMentor;
+ }
+
+ public void setAssignedMentor(Mentor assignedMentor) {
+ this.assignedMentor = assignedMentor;
+ }
+
+ public String getUniversity() {
+ return university;
+ }
+
+ public void setUniversity(String university) {
+ this.university = university;
+ }
- @Column(nullable = false)
- private String submissionUrl;
+ public String getCourse() {
+ return course;
+ }
+
+ public void setCourse(String course) {
+ this.course = course;
+ }
+
+ public String getYear() {
+ return year;
+ }
+
+ public void setYear(String year) {
+ this.year = year;
+ }
+
+ public String getIntent() {
+ return intent;
+ }
+
+ public void setIntent(String intent) {
+ this.intent = intent;
+ }
+
+ public String getReasonForChoice() {
+ return reasonForChoice;
+ }
+
+ public void setReasonForChoice(String reasonForChoice) {
+ this.reasonForChoice = reasonForChoice;
+ }
+
+
+ public Mentor getRejectedBy() {
+ return rejectedBy;
+ }
+
+ public void setRejectedBy(Mentor rejectedBy) {
+ this.rejectedBy = rejectedBy;
+ }
- public Mentor getMentor() {
- return mentor;
+ public String getResumeUrl() {
+ return resumeUrl;
}
- public void setMentor(Mentor mentor) {
- this.mentor = mentor;
+ public void setResumeUrl(String resumeUrl) {
+ this.resumeUrl = resumeUrl;
}
- public String getSubmissionUrl() {
- return submissionUrl;
+ public String getAchievements() {
+ return achievements;
}
- public void setSubmissionUrl(String submissionUrl) {
- this.submissionUrl = submissionUrl;
+ public void setAchievements(String achievements) {
+ this.achievements = achievements;
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/model/Mentor.java b/src/main/java/org/sefglobal/scholarx/model/Mentor.java
index d873d7eb..2480c84e 100644
--- a/src/main/java/org/sefglobal/scholarx/model/Mentor.java
+++ b/src/main/java/org/sefglobal/scholarx/model/Mentor.java
@@ -1,32 +1,120 @@
package org.sefglobal.scholarx.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import org.sefglobal.scholarx.util.MentorCategory;
-import javax.persistence.Entity;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
+import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "mentor")
-@JsonIgnoreProperties({"createdAt", "updatedAt", "mentees"})
+@JsonIgnoreProperties({"createdAt", "updatedAt", "assignedMentees", "appliedMentees", "rejectedMentees"})
public class Mentor extends EnrolledUser {
- @OneToMany(mappedBy = "mentor")
- private List mentorResponses;
-
public Mentor() {
}
- @OneToMany(mappedBy = "mentor")
- private List mentees = new ArrayList<>();
+ @Enumerated(EnumType.STRING)
+ @Column(nullable = false)
+ private MentorCategory category;
+
+ @Column
+ private String expertise;
+
+ @Column
+ private String institution;
+
+ @Column
+ private String position;
+
+ @Column(columnDefinition = "TEXT")
+ private String bio;
+
+ @Column
+ private int slots;
+
+ @Column
+ private int noOfAssignedMentees;
+
+ @OneToMany(mappedBy = "assignedMentor")
+ private List assignedMentees = new ArrayList<>();
+
+ @OneToMany(mappedBy = "appliedMentor")
+ private List appliedMentees = new ArrayList<>();
+
+ @OneToMany(mappedBy = "rejectedBy")
+ private List rejectedMentees = new ArrayList<>();
+
+ public MentorCategory getCategory() {
+ return category;
+ }
+
+ public void setCategory(MentorCategory category) {
+ this.category = category;
+ }
+
+ public String getExpertise() {
+ return expertise;
+ }
+
+ public void setExpertise(String expertise) {
+ this.expertise = expertise;
+ }
+
+ public String getInstitution() {
+ return institution;
+ }
+
+ public void setInstitution(String institution) {
+ this.institution = institution;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public String getBio() {
+ return bio;
+ }
+
+ public void setBio(String bio) {
+ this.bio = bio;
+ }
+
+ public int getSlots() {
+ return slots;
+ }
+
+ public void setSlots(int slots) {
+ this.slots = slots;
+ }
+
+ public List getAssignedMentees() {
+ return assignedMentees;
+ }
+
+ public void setAssignedMentees(List assignedMentees) {
+ this.assignedMentees = assignedMentees;
+ }
+
+ public List getAppliedMentees() {
+ return appliedMentees;
+ }
+
+ public void setAppliedMentees(List appliedMentees) {
+ this.appliedMentees = appliedMentees;
+ }
- public List getMentees() {
- return mentees;
+ public int getNoOfAssignedMentees() {
+ return noOfAssignedMentees;
}
- public void setMentees(List mentees) {
- this.mentees = mentees;
+ public void setNoOfAssignedMentees(int noOfAssignedMentees) {
+ this.noOfAssignedMentees = noOfAssignedMentees;
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/model/MentorResponse.java b/src/main/java/org/sefglobal/scholarx/model/MentorResponse.java
deleted file mode 100644
index b26d50fd..00000000
--- a/src/main/java/org/sefglobal/scholarx/model/MentorResponse.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.sefglobal.scholarx.model;
-
-import javax.persistence.*;
-import java.io.Serializable;
-
-@Entity
-@Table(name = "mentor_response")
-public class MentorResponse implements Serializable {
-
- @EmbeddedId
- MentorResponseId id;
-
- @ManyToOne(cascade = CascadeType.ALL)
- @MapsId("questionId")
- @JoinColumn(name = "question_id")
- private Question question;
-
- @ManyToOne(cascade = CascadeType.ALL)
- @MapsId("mentorId")
- @JoinColumn(name = "mentor_id")
- private Mentor mentor;
-
- @Column(nullable = false, columnDefinition = "TEXT")
- private String response;
-
- public MentorResponse() {}
-
- public MentorResponse(Question question, Mentor mentor, String response) {
- this.id = new MentorResponseId(question.getId(), mentor.getId());
- this.question = question;
- this.mentor = mentor;
- this.response = response;
- }
-
- public MentorResponseId getId() {
- return id;
- }
-
- public void setId(MentorResponseId id) {
- this.id = id;
- }
-
- public Question getQuestion() {
- return question;
- }
-
- public void setQuestion(Question question) {
- this.question = question;
- }
-
- public Mentor getMentor() {
- return mentor;
- }
-
- public void setMentor(Mentor mentor) {
- this.mentor = mentor;
- }
-
- public String getResponse() {
- return response;
- }
-
- public void setResponse(String response) {
- this.response = response;
- }
-}
diff --git a/src/main/java/org/sefglobal/scholarx/model/MentorResponseId.java b/src/main/java/org/sefglobal/scholarx/model/MentorResponseId.java
deleted file mode 100644
index 50db94c8..00000000
--- a/src/main/java/org/sefglobal/scholarx/model/MentorResponseId.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.sefglobal.scholarx.model;
-
-import javax.persistence.Column;
-import javax.persistence.Embeddable;
-import java.io.Serializable;
-import java.util.Objects;
-
-@Embeddable
-public class MentorResponseId implements Serializable {
- @Column(name = "question_id")
- private long questionId;
- @Column(name = "mentor_id")
- private long mentorId;
-
- public MentorResponseId() {}
-
- public MentorResponseId(long questionId, long mentorId) {
- this.questionId = questionId;
- this.mentorId = mentorId;
- }
-
- public void setQuestionId(long questionId) {
- this.questionId = questionId;
- }
-
- public long getQuestionId() {
- return questionId;
- }
-
- public void setMentorId(long mentorId) {
- this.mentorId = mentorId;
- }
-
- public long getMentorId() {
- return mentorId;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(questionId, mentorId);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
- if (obj == null || getClass() != obj.getClass()) return false;
- MentorResponseId id = (MentorResponseId) obj;
- return id.mentorId == this.mentorId && id.questionId == this.questionId;
- }
-}
diff --git a/src/main/java/org/sefglobal/scholarx/model/Program.java b/src/main/java/org/sefglobal/scholarx/model/Program.java
index 64a3776c..84b042f2 100644
--- a/src/main/java/org/sefglobal/scholarx/model/Program.java
+++ b/src/main/java/org/sefglobal/scholarx/model/Program.java
@@ -24,7 +24,7 @@ public class Program extends BaseScholarxModel {
@Column
private String headline;
- @Column
+ @Column(columnDefinition="TEXT")
private String imageUrl;
@Column
@@ -32,12 +32,9 @@ public class Program extends BaseScholarxModel {
@JsonIgnore
@Enumerated(EnumType.STRING)
- @Column(length = 20, nullable = false)
+ @Column(length = 25, nullable = false)
private ProgramState state;
- @OneToMany(mappedBy = "program")
- private List questions;
-
@OneToMany(mappedBy = "program")
private List enrolledUsers = new ArrayList<>();
diff --git a/src/main/java/org/sefglobal/scholarx/model/Question.java b/src/main/java/org/sefglobal/scholarx/model/Question.java
deleted file mode 100644
index 21eb6e71..00000000
--- a/src/main/java/org/sefglobal/scholarx/model/Question.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.sefglobal.scholarx.model;
-
-import org.sefglobal.scholarx.util.QuestionCategory;
-
-import javax.persistence.*;
-import java.util.List;
-
-@Entity
-@Table(name = "question")
-public class Question extends BaseScholarxModel{
-
- @Column(nullable = false, columnDefinition = "TEXT")
- private String question;
-
- @Column(nullable = false)
- private QuestionCategory category;
-
- @ManyToOne
- @JoinColumn(name = "program_id")
- private Program program;
-
- @OneToMany(mappedBy = "question")
- private List mentorResponses;
-
- public Question() {}
-
- public Question(String question, QuestionCategory category, Program program) {
- this.question = question;
- this.category = category;
- this.program = program;
- }
-
- public String getQuestion() {
- return question;
- }
-
- public void setQuestion(String question) {
- this.question = question;
- }
-
- public QuestionCategory getCategory() {
- return category;
- }
-
- public void setCategory(QuestionCategory category) {
- this.category = category;
- }
-
- public Program getProgram() {
- return program;
- }
-
- public void setProgram(Program program) {
- this.program = program;
- }
-}
diff --git a/src/main/java/org/sefglobal/scholarx/model/SentEmail.java b/src/main/java/org/sefglobal/scholarx/model/SentEmail.java
new file mode 100644
index 00000000..85c0bdca
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/model/SentEmail.java
@@ -0,0 +1,77 @@
+package org.sefglobal.scholarx.model;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import javax.persistence.ManyToOne;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import org.sefglobal.scholarx.util.ProgramState;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+
+@Entity
+@Table(name = "email")
+@JsonIgnoreProperties({"createdAt"})
+public class SentEmail extends BaseScholarxModel {
+ @Column
+ private String email;
+
+ @Column(columnDefinition = "TEXT")
+ private String message;
+
+ @ManyToOne
+ private Program program;
+
+ @ManyToOne
+ private Profile receiver;
+
+ @Enumerated(EnumType.STRING)
+ @Column
+ private ProgramState state;
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public ProgramState getstate() {
+ return state;
+ }
+ public void setState(ProgramState state) {
+ this.state = state;
+ }
+
+ public Program getProgramId() {
+ return program;
+ }
+
+ public void setProgramId(Program program) {
+ this.program = program;
+ }
+
+ public void setReceiver(Profile receiver) {
+ this.receiver = receiver;
+ }
+
+ public Profile getReceiver() {
+ return receiver;
+ }
+
+}
+
+
+
+
+
+
diff --git a/src/main/java/org/sefglobal/scholarx/repository/CommentRepository.java b/src/main/java/org/sefglobal/scholarx/repository/CommentRepository.java
new file mode 100644
index 00000000..a3f39f08
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/repository/CommentRepository.java
@@ -0,0 +1,12 @@
+package org.sefglobal.scholarx.repository;
+
+import org.sefglobal.scholarx.model.Comment;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface CommentRepository extends JpaRepository {
+ List findAllByMenteeId(long id);
+}
diff --git a/src/main/java/org/sefglobal/scholarx/repository/EmailRepository.java b/src/main/java/org/sefglobal/scholarx/repository/EmailRepository.java
new file mode 100644
index 00000000..211f3361
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/repository/EmailRepository.java
@@ -0,0 +1,11 @@
+package org.sefglobal.scholarx.repository;
+
+import org.sefglobal.scholarx.model.SentEmail;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import java.util.List;
+
+@Repository
+public interface EmailRepository extends JpaRepository {
+ List findAllByProgram(long id);
+}
diff --git a/src/main/java/org/sefglobal/scholarx/repository/MenteeRepository.java b/src/main/java/org/sefglobal/scholarx/repository/MenteeRepository.java
index 3335377a..11bd794b 100644
--- a/src/main/java/org/sefglobal/scholarx/repository/MenteeRepository.java
+++ b/src/main/java/org/sefglobal/scholarx/repository/MenteeRepository.java
@@ -15,17 +15,15 @@
@Transactional
public interface MenteeRepository extends JpaRepository {
- List findAllByMentorIdAndState(long id, EnrolmentState state);
+ List findAllByAssignedMentorIdAndState(long id, EnrolmentState state);
- List findAllByMentorIdAndStateIn(long id, List states);
-
- List findAllByProgramIdAndProfileId(long programId, long profileId);
+ List findAllByAssignedMentorIdAndStateIn(long id, List states);
List findAllByProgramIdAndProfileIdAndState(long programId, long profileId, EnrolmentState state);
- List findAllByProgramIdAndProfileIdAndStateIn(long programId, long profileId, List states);
+ Optional findByProfileIdAndAppliedMentorId(long profileId, long mentorId);
- Optional findByProfileIdAndMentorId(long profileId, long mentorId);
+ Optional findByProgramIdAndProfileId(long programId, long profileId);
List findAllByProfileId(long profileId);
@@ -33,6 +31,8 @@ public interface MenteeRepository extends JpaRepository {
List findAllByProgramIdAndState(long programId, EnrolmentState state);
+ List findAllByProgramIdAndStateIn(long programId, List states);
+
@Modifying
@Query(
value = "DELETE " +
diff --git a/src/main/java/org/sefglobal/scholarx/repository/MentorResponseRepository.java b/src/main/java/org/sefglobal/scholarx/repository/MentorResponseRepository.java
deleted file mode 100644
index 68f53d0d..00000000
--- a/src/main/java/org/sefglobal/scholarx/repository/MentorResponseRepository.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.sefglobal.scholarx.repository;
-
-import org.sefglobal.scholarx.model.MentorResponse;
-import org.sefglobal.scholarx.model.MentorResponseId;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.List;
-
-public interface MentorResponseRepository extends JpaRepository {
- List getAllByMentorId(long mentorId);
-}
diff --git a/src/main/java/org/sefglobal/scholarx/repository/ProfileRepository.java b/src/main/java/org/sefglobal/scholarx/repository/ProfileRepository.java
index f40eb49c..89f854fd 100644
--- a/src/main/java/org/sefglobal/scholarx/repository/ProfileRepository.java
+++ b/src/main/java/org/sefglobal/scholarx/repository/ProfileRepository.java
@@ -8,7 +8,7 @@
@Repository
public interface ProfileRepository extends JpaRepository {
- Optional findByEmail(String email);
+ Optional findByUid(String uid);
Boolean existsByUid(String uid);
Boolean existsByEmail(String email);
}
diff --git a/src/main/java/org/sefglobal/scholarx/repository/QuestionRepository.java b/src/main/java/org/sefglobal/scholarx/repository/QuestionRepository.java
deleted file mode 100644
index 001064a4..00000000
--- a/src/main/java/org/sefglobal/scholarx/repository/QuestionRepository.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.sefglobal.scholarx.repository;
-
-import org.sefglobal.scholarx.model.Program;
-import org.sefglobal.scholarx.model.Question;
-import org.sefglobal.scholarx.util.QuestionCategory;
-import org.springframework.data.jpa.repository.JpaRepository;
-
-import java.util.List;
-
-public interface QuestionRepository extends JpaRepository {
- List getAllByCategoryAndProgramId(QuestionCategory category, long programId);
-}
diff --git a/src/main/java/org/sefglobal/scholarx/service/CommentService.java b/src/main/java/org/sefglobal/scholarx/service/CommentService.java
new file mode 100644
index 00000000..6f920912
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/service/CommentService.java
@@ -0,0 +1,113 @@
+package org.sefglobal.scholarx.service;
+
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.exception.UnauthorizedException;
+import org.sefglobal.scholarx.model.Comment;
+import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.repository.CommentRepository;
+import org.sefglobal.scholarx.repository.MenteeRepository;
+import org.sefglobal.scholarx.repository.ProfileRepository;
+import org.sefglobal.scholarx.util.ProfileType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class CommentService {
+ private final static Logger log = LoggerFactory.getLogger(CommentService.class);
+ private final CommentRepository commentRepository;
+ private final ProfileRepository profileRepository;
+ private final MenteeRepository menteeRepository;
+
+ public CommentService(ProfileRepository profileRepository,MenteeRepository menteeRepository,
+ CommentRepository commentRepository){
+ this.commentRepository = commentRepository;
+ this.profileRepository = profileRepository;
+ this.menteeRepository = menteeRepository;
+ }
+
+ public List getAllMenteeComments(long menteeId, long profileId)
+ throws ResourceNotFoundException, UnauthorizedException {
+ Optional optionalMentee = menteeRepository.findById(menteeId);
+ Optional optionalProfile = profileRepository.findById(profileId);
+
+ if (!optionalMentee.isPresent()) {
+ String msg = "Error, Mentee by id: " + menteeId + " doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ } else if (!(optionalProfile.get().getType().equals(ProfileType.ADMIN) ||
+ optionalMentee.get().getAssignedMentor().getProfile().getId() == profileId)) {
+ String msg = "Error, User by id: " + profileId + " is not allowed access.";
+ log.error(msg);
+ throw new UnauthorizedException(msg);
+ }
+
+ return commentRepository.findAllByMenteeId(menteeId);
+ }
+
+ public Comment addMenteeComment(long menteeId, long profileId, Comment menteeComment)
+ throws ResourceNotFoundException, UnauthorizedException {
+ Optional optionalProfile = profileRepository.findById(profileId);
+ Optional optionalMentee = menteeRepository.findById(menteeId);
+
+ if (!optionalMentee.isPresent()) {
+ String msg = "Error, Mentee by id: " + menteeId + " doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
+
+ if (!optionalProfile.isPresent()) {
+ String msg = "Error, User by id: " + profileId + " doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ } else if (!(optionalProfile.get().getType().equals(ProfileType.ADMIN) ||
+ optionalMentee.get().getAssignedMentor().getProfile().getId() == profileId)) {
+ String msg = "Error, User by id: " + profileId + " is not allowed access.";
+ log.error(msg);
+ throw new UnauthorizedException(msg);
+ }
+
+ Comment comment = new Comment();
+ comment.setCommented_by(optionalProfile.get());
+ comment.setComment(menteeComment.getComment());
+ comment.setMentee(optionalMentee.get());
+ return commentRepository.save(comment);
+ }
+
+ public Comment updateComment(long id, long profileId, Comment menteeComment)
+ throws ResourceNotFoundException, UnauthorizedException {
+ Optional optionalComment = commentRepository.findById(id);
+ if (!optionalComment.isPresent()) {
+ String msg = "Error, Comment with id: " + id + " cannot be updated. " +
+ "Comment doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ } else if (optionalComment.get().getCommented_by().getId() != profileId) {
+ String msg = "Error, User by id: " + profileId + " is not allowed access.";
+ log.error(msg);
+ throw new UnauthorizedException(msg);
+ }
+ optionalComment.get().setComment(menteeComment.getComment());
+ return commentRepository.save(optionalComment.get());
+ }
+
+ public void deleteComment(long id, long profileId)
+ throws ResourceNotFoundException, UnauthorizedException {
+ Optional optionalComment = commentRepository.findById(id);
+ if (!optionalComment.isPresent()) {
+ String msg = "Error, Comment with id: " + id + " cannot be deleted. " +
+ "Comment doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ } else if (optionalComment.get().getCommented_by().getId() != profileId) {
+ String msg = "Error, User by id: " + profileId + " is not allowed access.";
+ log.error(msg);
+ throw new UnauthorizedException(msg);
+ }
+ commentRepository.deleteById(id);
+ }
+}
diff --git a/src/main/java/org/sefglobal/scholarx/service/IntrospectionService.java b/src/main/java/org/sefglobal/scholarx/service/IntrospectionService.java
index d21c8c1b..9e9ea18d 100644
--- a/src/main/java/org/sefglobal/scholarx/service/IntrospectionService.java
+++ b/src/main/java/org/sefglobal/scholarx/service/IntrospectionService.java
@@ -142,7 +142,7 @@ public List getMentoringPrograms(long id, EnrolmentState mentorState)
* @param profileId which is the id of the {@link Profile}
* @param menteeStates which is the list of states that {@link Mentee} objects should be
* filtered from
- * @return {@link List} of {@link Mentee} objects
+ * @return {@link List} of {@link Mentee} objects of a {@link Mentor}
*
* @throws ResourceNotFoundException if the user doesn't exist
* @throws NoContentException if {@link Mentor} objects doesn't exist
@@ -160,10 +160,10 @@ public List getMentees(long programId, long profileId,
throw new ResourceNotFoundException(msg);
}
if (menteeStates == null || menteeStates.isEmpty()) {
- mentees = optionalMentor.get().getMentees();
+ mentees = optionalMentor.get().getAssignedMentees();
} else {
mentees = menteeRepository
- .findAllByMentorIdAndStateIn(optionalMentor.get().getId(), menteeStates);
+ .findAllByAssignedMentorIdAndStateIn(optionalMentor.get().getId(), menteeStates);
}
if (mentees.isEmpty()) {
@@ -174,43 +174,4 @@ public List getMentees(long programId, long profileId,
}
return mentees;
}
-
- /**
- * Confirm a {@link Mentor} for a specific {@link Mentee}
- *
- * @param mentorId which is the id of the confirmed {@link Mentor}
- * @param profileId which is the id of the {@link Profile}
- * @return the updated {@link Mentee}
- *
- * @throws ResourceNotFoundException is thrown if the {@link Mentor} doesn't exist
- * @throws BadRequestException is thrown if the {@link Mentee} is not approved
- */
- public Mentee confirmMentor(long mentorId, long profileId)
- throws ResourceNotFoundException, BadRequestException {
- Optional optionalMentor = mentorRepository.findById(mentorId);
- if (!optionalMentor.isPresent()) {
- String msg = "Error, Mentor by id: " + mentorId + " doesn't exist.";
- log.error(msg);
- throw new ResourceNotFoundException(msg);
- }
-
- Optional optionalMentee = menteeRepository.findByProfileIdAndMentorId(profileId, mentorId);
- if (!optionalMentee.isPresent()) {
- String msg = "Error, User with id: " + profileId + " haven't applied for " +
- "mentor by id: " + mentorId + ".";
- log.error(msg);
- throw new BadRequestException(msg);
- }
-
- if (!optionalMentee.get().getState().equals(EnrolmentState.APPROVED)) {
- String msg = "Error, User with id: " + profileId + " is not approved " +
- "by the mentor by id: " + mentorId + ".";
- log.error(msg);
- throw new BadRequestException(msg);
- }
-
- long programId = optionalMentor.get().getProgram().getId();
- menteeRepository.removeAllByProgramIdAndProfileIdAndMentorIdNot(programId, profileId, mentorId);
- return optionalMentee.get();
- }
}
diff --git a/src/main/java/org/sefglobal/scholarx/service/MenteeService.java b/src/main/java/org/sefglobal/scholarx/service/MenteeService.java
index a3c5b851..75923373 100644
--- a/src/main/java/org/sefglobal/scholarx/service/MenteeService.java
+++ b/src/main/java/org/sefglobal/scholarx/service/MenteeService.java
@@ -2,9 +2,14 @@
import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.exception.UnauthorizedException;
import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Mentor;
+import org.sefglobal.scholarx.model.Program;
import org.sefglobal.scholarx.repository.MenteeRepository;
+import org.sefglobal.scholarx.repository.MentorRepository;
import org.sefglobal.scholarx.util.EnrolmentState;
+import org.sefglobal.scholarx.util.ProgramState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@@ -16,9 +21,11 @@ public class MenteeService {
private final static Logger log = LoggerFactory.getLogger(MenteeService.class);
private final MenteeRepository menteeRepository;
-
- public MenteeService(MenteeRepository menteeRepository) {
+ private final MentorRepository mentorRepository;
+
+ public MenteeService(MenteeRepository menteeRepository, MentorRepository mentorRepository) {
this.menteeRepository = menteeRepository;
+ this.mentorRepository = mentorRepository;
}
/**
@@ -43,15 +50,17 @@ public void deleteMentee(long id)
* Update a {@link EnrolmentState} of a {@link Mentee} to Approved or Rejected
*
* @param menteeId which is the {@link Mentee} to be updated
+ * @param profileId which is the profile identifier of the requesting user
* @param isApproved which states whether the {@link Mentee} to be approved or rejected
* @return the updated {@link Mentee}
*
* @throws ResourceNotFoundException is thrown if the {@link Mentee} doesn't exist
+ * @throws UnauthorizedException is thrown if the requesting user is not the assigned mentor
* @throws BadRequestException is thrown if the {@link Mentee} is removed
* @throws BadRequestException is thrown if the {@link Boolean} is null
*/
- public Mentee approveOrRejectMentee(long menteeId, Boolean isApproved)
- throws ResourceNotFoundException, BadRequestException {
+ public Mentee approveOrRejectMentee(long menteeId, long profileId, Boolean isApproved)
+ throws ResourceNotFoundException, BadRequestException, UnauthorizedException {
if (null == isApproved){
String msg = "Error, Value cannot be null.";
log.error(msg);
@@ -64,6 +73,14 @@ public Mentee approveOrRejectMentee(long menteeId, Boolean isApproved)
log.error(msg);
throw new ResourceNotFoundException(msg);
}
+ long assignedMentorProfileId = optionalMentee.get().getAssignedMentor().getProfile().getId();
+ if (assignedMentorProfileId != profileId) {
+ String msg = "Error, Mentee cannot be approved/rejected. " +
+ "Mentee with id: " + menteeId + " is not a mentee " +
+ "of mentor with profile id: " + profileId + ".";
+ log.error(msg);
+ throw new UnauthorizedException(msg);
+ }
if (EnrolmentState.REMOVED.equals(optionalMentee.get().getState())) {
String msg = "Error, Mentee cannot be approved/rejected. " +
"Mentee with id: " + menteeId + " is removed.";
@@ -71,7 +88,109 @@ public Mentee approveOrRejectMentee(long menteeId, Boolean isApproved)
throw new BadRequestException(msg);
}
+ Mentor mentor = optionalMentee.get().getAssignedMentor();
+ if (isApproved) {
+ mentor.setNoOfAssignedMentees(mentor.getNoOfAssignedMentees() + 1);
+ } else if (optionalMentee.get().getState().equals(EnrolmentState.ASSIGNED)) {
+ optionalMentee.get().setRejectedBy(mentor);
+ } else if (optionalMentee.get().getState().equals(EnrolmentState.APPROVED)) {
+ optionalMentee.get().setRejectedBy(mentor);
+ mentor.setNoOfAssignedMentees(mentor.getNoOfAssignedMentees() - 1);
+ }
+
optionalMentee.get().setState(isApproved?EnrolmentState.APPROVED:EnrolmentState.REJECTED);
return menteeRepository.save(optionalMentee.get());
}
+
+ /**
+ * Update a assigned {@link Mentor} of a {@link Mentee}
+ *
+ * @param menteeId which is the {@link Mentee} to be updated
+ * @param mentorId which is the id of assigned {@link Mentor}
+ * @return the updated {@link Mentee}
+
+ * @throws ResourceNotFoundException is thrown if the {@link Mentee} doesn't exist
+ * @throws ResourceNotFoundException is thrown if the {@link Mentor} doesn't exist
+ * @throws BadRequestException is thrown if the {@link Mentor} id is not given
+ * @throws BadRequestException is thrown if the {@link Program} is not in a valid state
+ */
+ public Mentee updateAssignedMentor(long menteeId, Long mentorId)
+ throws ResourceNotFoundException, BadRequestException {
+ if (null == mentorId) {
+ String msg = "Error, Value cannot be null.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+
+ Optional optionalMentee = menteeRepository.findById(menteeId);
+ if (!optionalMentee.isPresent()) {
+ String msg = "Error, Mentee cannot be updated. " +
+ "Mentee with id: " + menteeId + " doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
+
+ Optional optionalMentor = mentorRepository.findById(mentorId);
+ if (!optionalMentor.isPresent()) {
+ String msg = "Error, Mentee cannot be updated. " +
+ "Mentor with id: " + mentorId + " doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
+
+ ProgramState programState = optionalMentee.get().getProgram().getState();
+ if (programState.equals(ProgramState.ADMIN_MENTEE_FILTRATION) || programState.equals(ProgramState.WILDCARD)) {
+ optionalMentee.get().setState(EnrolmentState.ASSIGNED);
+ } else {
+ String msg = "Error, Mentee cannot be updated. " +
+ "Program is not in a valid state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+
+ Mentor previouslyAssignedMentor = optionalMentee.get().getAssignedMentor();
+ if (previouslyAssignedMentor != null) {
+ previouslyAssignedMentor.setNoOfAssignedMentees(previouslyAssignedMentor.getNoOfAssignedMentees() - 1);
+ }
+
+ optionalMentor.get().setNoOfAssignedMentees(optionalMentor.get().getNoOfAssignedMentees() + 1);
+ optionalMentee.get().setAssignedMentor(optionalMentor.get());
+ return menteeRepository.save(optionalMentee.get());
+ }
+
+ public Mentee changeState(long menteeId, EnrolmentState enrolmentState)
+ throws ResourceNotFoundException, BadRequestException {
+ Optional optionalMentee = menteeRepository.findById(menteeId);
+ if (!optionalMentee.isPresent()) {
+ String msg = "Error, Mentee cannot be updated. " +
+ "Mentee with id "+ menteeId +" doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
+ ProgramState state = optionalMentee.get().getProgram().getState();
+ if (!ProgramState.ADMIN_MENTEE_FILTRATION.equals(state) && !ProgramState.WILDCARD.equals(state)){
+ String msg = "Error, Mentee cannot be updated. " +
+ "The program is not in a valid state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+ if (EnrolmentState.REJECTED.equals(enrolmentState) || EnrolmentState.APPROVED.equals(enrolmentState)
+ || EnrolmentState.ASSIGNED.equals(enrolmentState)){
+ String msg = "Error, Mentee cannot be updated. " +
+ "EnrolmentState: "+ enrolmentState +" is not an applicable state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+
+
+ if(optionalMentee.get().getState().equals(EnrolmentState.ASSIGNED)){
+ Mentor assignedMentor = optionalMentee.get().getAssignedMentor();
+ assignedMentor.setNoOfAssignedMentees(assignedMentor.getNoOfAssignedMentees() - 1);
+ optionalMentee.get().setAssignedMentor(null);
+ mentorRepository.save(assignedMentor);
+ }
+
+ optionalMentee.get().setState(enrolmentState);
+ return menteeRepository.save(optionalMentee.get());
+ }
}
diff --git a/src/main/java/org/sefglobal/scholarx/service/MentorService.java b/src/main/java/org/sefglobal/scholarx/service/MentorService.java
index 1f7a56f3..8653a461 100644
--- a/src/main/java/org/sefglobal/scholarx/service/MentorService.java
+++ b/src/main/java/org/sefglobal/scholarx/service/MentorService.java
@@ -1,17 +1,22 @@
package org.sefglobal.scholarx.service;
+import com.google.common.collect.ImmutableList;
import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.NoContentException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
import org.sefglobal.scholarx.model.Mentee;
import org.sefglobal.scholarx.model.Mentor;
import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.model.Program;
import org.sefglobal.scholarx.repository.MenteeRepository;
import org.sefglobal.scholarx.repository.MentorRepository;
import org.sefglobal.scholarx.repository.ProfileRepository;
import org.sefglobal.scholarx.util.EnrolmentState;
+import org.sefglobal.scholarx.util.ProgramState;
+import org.sefglobal.scholarx.util.ProgramUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@@ -24,6 +29,10 @@ public class MentorService {
private final MentorRepository mentorRepository;
private final MenteeRepository menteeRepository;
private final ProfileRepository profileRepository;
+ private final List validMentorStates = ImmutableList.of(EnrolmentState.APPROVED, EnrolmentState.REJECTED, EnrolmentState.REMOVED);
+
+ @Autowired
+ private ProgramUtil programUtil;
public MentorService(MentorRepository mentorRepository,
MenteeRepository menteeRepository,
@@ -66,11 +75,18 @@ public Mentor getMentorById(long id) throws ResourceNotFoundException {
* @param id which is the {@link Mentor} to be updated
* @param enrolmentState which is the {@link EnrolmentState} of the program to be updated
* @return the updated {@link Mentor}
- *
* @throws ResourceNotFoundException is thrown if the requesting {@link Mentor} doesn't exist
+ * @throws BadRequestException is thrown if the requesting {@link EnrolmentState} is not eligible for a mentor
*/
public Mentor updateState(long id, EnrolmentState enrolmentState)
- throws ResourceNotFoundException {
+ throws ResourceNotFoundException, BadRequestException {
+ if (!validMentorStates.contains(enrolmentState)) {
+ String msg = "Error, Mentor with id: " + id + " cannot be updated. " +
+ enrolmentState + " is not an applicable state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+
Optional optionalMentor = mentorRepository.findById(id);
if (!optionalMentor.isPresent()) {
String msg = "Error, Mentor with id: " + id + " cannot be updated. " +
@@ -94,6 +110,8 @@ public Mentor updateState(long id, EnrolmentState enrolmentState)
* @throws ResourceNotFoundException is thrown if the applying user's {@link Profile} doesn't exist
* @throws BadRequestException is thrown if the applying {@link Mentor} is not in applicable state
* @throws BadRequestException is thrown if the applying user is already a {@link Mentor}
+ * @throws BadRequestException is thrown if the applying user has already applied for the {@link Mentor}
+ * @throws BadRequestException is thrown if the applying program {@link Program} is not in applicable state {@link ProgramState}
*/
public Mentee applyAsMentee(long mentorId, long profileId, Mentee mentee)
throws ResourceNotFoundException, BadRequestException {
@@ -111,6 +129,13 @@ public Mentee applyAsMentee(long mentorId, long profileId, Mentee mentee)
throw new BadRequestException(msg);
}
+ Program program = optionalMentor.get().getProgram();
+ if (!ProgramState.MENTEE_APPLICATION.equals(optionalMentor.get().getProgram().getState())) {
+ String msg = "Error, Unable to apply as a mentee. " +
+ "Program with id: " + program.getId() + " is not in the applicable state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
Optional optionalProfile = profileRepository.findById(profileId);
if (!optionalProfile.isPresent()) {
String msg = "Error, Unable to apply as a mentee. " +
@@ -120,7 +145,7 @@ public Mentee applyAsMentee(long mentorId, long profileId, Mentee mentee)
}
Optional alreadyRegisteredMentor = mentorRepository
- .findByProfileIdAndProgramId(profileId, optionalMentor.get().getProgram().getId());
+ .findByProfileIdAndProgramId(profileId, program.getId());
if (alreadyRegisteredMentor.isPresent() &&
alreadyRegisteredMentor.get().getState().equals(EnrolmentState.APPROVED)) {
String msg = "Error, Unable to apply as a mentee. " +
@@ -129,15 +154,41 @@ public Mentee applyAsMentee(long mentorId, long profileId, Mentee mentee)
throw new BadRequestException(msg);
}
+ Optional alreadyAppliedMentee = menteeRepository.findByProgramIdAndProfileId(program.getId(), profileId);
+ if (alreadyAppliedMentee.isPresent()) {
+ String msg = "Error, Unable to apply as a mentee. " +
+ "Profile with id: " + profileId + " has already applied for this program.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+
mentee.setProfile(optionalProfile.get());
- mentee.setProgram(optionalMentor.get().getProgram());
- mentee.setMentor(optionalMentor.get());
+ mentee.setProgram(program);
+ mentee.setAppliedMentor(optionalMentor.get());
+ mentee.setCourse(mentee.getCourse());
+ mentee.setUniversity(mentee.getUniversity());
+ mentee.setYear(mentee.getYear());
+ mentee.setIntent(mentee.getIntent());
+ mentee.setReasonForChoice(mentee.getReasonForChoice());
+ mentee.setResumeUrl(mentee.getResumeUrl());
+ mentee.setAchievements(mentee.getAchievements());
mentee.setState(EnrolmentState.PENDING);
- return menteeRepository.save(mentee);
+ Mentee savedMenteeEntity = menteeRepository.save(mentee);
+
+ Thread thread = new Thread(() -> {
+ try {
+ programUtil.sendConfirmationEmails(profileId, Optional.of(program));
+ } catch (Exception exception) {
+ log.error("Email service error: ", exception);
+ }
+ });
+ thread.start();
+
+ return savedMenteeEntity;
}
/**
- * Retrieves all the {@link Mentee} objects of a {@link Mentor}
+ * Retrieves all the Assigned {@link Mentee} objects of a {@link Mentor}
*
* @param mentorId which is the Mentor id of the {@link Mentor}
* @param state which is the state of the {@link Mentee} objects to be filtered
@@ -160,65 +211,8 @@ public List getAllMenteesOfMentor(long mentorId, Optional optionalMentee = menteeRepository.findByProfileIdAndMentorId(profileId, mentorId);
- if (!optionalMentee.isPresent()) {
- String msg = "Error, Mentee by profile id: " + profileId + " and " +
- "mentor id: " + mentorId + " cannot be updated. " +
- "Mentee doesn't exist.";
- log.error(msg);
- throw new ResourceNotFoundException(msg);
- }
-
- Mentee existingMentee = optionalMentee.get();
- if (!mentee.getSubmissionUrl().isEmpty()) {
- if (EnrolmentState.PENDING.equals(existingMentee.getState())) {
- existingMentee.setSubmissionUrl(mentee.getSubmissionUrl());
- } else {
- String msg = "Error, Application cannot be updated. " +
- "Mentee is not in a valid state.";
- log.error(msg);
- throw new BadRequestException(msg);
- }
- }
- return menteeRepository.save(existingMentee);
- }
-
- /**
- * Retrieves the {@link Mentee} of a user if the user is a mentee
- *
- * @param mentorId which is the id of the {@link Mentor}
- * @param profileId which is the id of the {@link Profile}
- * @return {@link Mentee}
- *
- * @throws NoContentException if the user hasn't applied for {@link Mentor}
- */
- public Mentee getLoggedInMentee(long mentorId, long profileId)
- throws NoContentException {
- Optional optionalMentee = menteeRepository.findByProfileIdAndMentorId(profileId, mentorId);
- if (!optionalMentee.isPresent()) {
- String msg = "Error, User by profile id: " + profileId + " hasn't applied for " +
- "mentor with id: " + mentorId + ".";
- log.error(msg);
- throw new NoContentException(msg);
+ return optionalMentor.get().getAssignedMentees();
}
- return optionalMentee.get();
+ return menteeRepository.findAllByAssignedMentorIdAndState(mentorId,state.get());
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/service/ProfileService.java b/src/main/java/org/sefglobal/scholarx/service/ProfileService.java
index 549a43f6..6391a8a1 100644
--- a/src/main/java/org/sefglobal/scholarx/service/ProfileService.java
+++ b/src/main/java/org/sefglobal/scholarx/service/ProfileService.java
@@ -31,11 +31,12 @@ public Profile processUserRegistration(Map attributes)
} else if (StringUtils.isEmpty(oAuth2UserInfo.getEmail())) {
throw new OAuth2AuthenticationProcessingException("Email not found from OAuth2 provider");
}
- Optional profile = profileRepository.findByEmail(oAuth2UserInfo.getEmail());
+ Optional profile = profileRepository.findByUid(oAuth2UserInfo.getUuid());
if (profile.isPresent()) {
profile.get().setFirstName(oAuth2UserInfo.getFirstName());
profile.get().setLastName(oAuth2UserInfo.getLastName());
profile.get().setImageUrl(oAuth2UserInfo.getImageUrl());
+ profile.get().setEmail(oAuth2UserInfo.getEmail());
return profileRepository.save(profile.get());
} else {
return createProfile(oAuth2UserInfo);
diff --git a/src/main/java/org/sefglobal/scholarx/service/ProgramService.java b/src/main/java/org/sefglobal/scholarx/service/ProgramService.java
index 57ec015e..b01c69b7 100644
--- a/src/main/java/org/sefglobal/scholarx/service/ProgramService.java
+++ b/src/main/java/org/sefglobal/scholarx/service/ProgramService.java
@@ -1,5 +1,6 @@
package org.sefglobal.scholarx.service;
+import com.google.common.collect.ImmutableList;
import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.NoContentException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
@@ -11,7 +12,13 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.util.*;
+import javax.mail.MessagingException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
@Service
public class ProgramService {
@@ -20,24 +27,21 @@ public class ProgramService {
private final ProfileRepository profileRepository;
private final MentorRepository mentorRepository;
private final MenteeRepository menteeRepository;
- private final QuestionRepository questionRepository;
- private final MentorResponseRepository mentorResponseRepository;
@Autowired
private ProgramUtil programUtil;
+ @Autowired
+ private EmailService emailService;
+
public ProgramService(ProgramRepository programRepository,
ProfileRepository profileRepository,
MentorRepository mentorRepository,
- MenteeRepository menteeRepository,
- QuestionRepository questionRepository,
- MentorResponseRepository mentorResponseRepository) {
+ MenteeRepository menteeRepository) {
this.programRepository = programRepository;
this.profileRepository = profileRepository;
this.mentorRepository = mentorRepository;
this.menteeRepository = menteeRepository;
- this.questionRepository = questionRepository;
- this.mentorResponseRepository = mentorResponseRepository;
}
/**
@@ -122,23 +126,68 @@ public Program updateProgram(long id, Program program) throws ResourceNotFoundEx
*/
public Program updateState(long id) throws ResourceNotFoundException {
Optional program = programRepository.findById(id);
+ if (!program.isPresent()) {
+ String msg = "Error, Program with id: " + id + " cannot be updated. " +
+ "Program doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
final ProgramState nextState = program.get().getState().next();
+
+ switch (nextState) {
+ case MENTEE_APPLICATION:
+ List mentors = mentorRepository.findAllByProgramIdAndState(id, EnrolmentState.PENDING);
+ for (Mentor mentor : mentors) {
+ mentor.setState(EnrolmentState.REJECTED);
+ }
+ break;
+
+ case MENTEE_SELECTION:
+ List mentorList = mentorRepository.findAllByProgramId(id);
+ for (Mentor mentor: mentorList) {
+ mentor.setNoOfAssignedMentees(0);
+ }
+ break;
+
+ case WILDCARD:
+ List mentees = menteeRepository.findAllByProgramIdAndStateIn(
+ id, ImmutableList.of(EnrolmentState.ASSIGNED, EnrolmentState.REJECTED));
+ for (Mentee mentee : mentees) {
+ mentee.setState(EnrolmentState.REJECTED);
+ mentee.setRejectedBy(mentee.getAssignedMentor());
+ mentee.setAssignedMentor(null);
+ }
+ break;
+
+ case ONGOING:
+ List approvedMentees = menteeRepository.findAllByProgramIdAndState(id, EnrolmentState.ASSIGNED);
+ for (Mentee mentee : approvedMentees) {
+ mentee.setState(EnrolmentState.APPROVED);
+ }
+ List ignoredMentees = menteeRepository.
+ findAllByProgramIdAndStateIn(id, ImmutableList.of(EnrolmentState.POOL, EnrolmentState.PENDING, EnrolmentState.REJECTED));
+ for (Mentee mentee : ignoredMentees) {
+ mentee.setState(EnrolmentState.FAILED_FROM_WILDCARD);
+ }
+ break;
+ }
+
Thread thread = new Thread(() -> {
try {
switch (nextState) {
case MENTEE_APPLICATION:
programUtil.sendMenteeApplicationEmails(id, program);
break;
+ case ADMIN_MENTEE_FILTRATION:
+ programUtil.sendMenteeFiltrationEmails(id, program);
+ break;
case MENTEE_SELECTION:
programUtil.sendMenteeSelectionEmails(id, program);
break;
case ONGOING:
programUtil.sendOnGoingEmails(id, program);
break;
- case MENTOR_CONFIRMATION:
- programUtil.sendMentorConfirmationEmails(id, program);
- break;
}
} catch (Exception exception) {
log.error("Email service error: ", exception);
@@ -146,22 +195,6 @@ public Program updateState(long id) throws ResourceNotFoundException {
});
thread.start();
- if (!program.isPresent()) {
- String msg = "Error, Program with id: " + id + " cannot be updated. " +
- "Program doesn't exist.";
- log.error(msg);
- throw new ResourceNotFoundException(msg);
- }
-
- if (ProgramState.ONGOING.equals(nextState)) {
- List approvedMenteeList = menteeRepository.findAllByProgramIdAndState(id, EnrolmentState.APPROVED);
- for (Mentee mentee : approvedMenteeList) {
- long profileId = mentee.getProfile().getId();
- if (menteeRepository.findAllByProgramIdAndProfileIdAndState(id, profileId, EnrolmentState.APPROVED).size() != 1) {
- menteeRepository.removeAllByProgramIdAndProfileId(id, profileId);
- }
- }
- }
program.get().setState(nextState);
return programRepository.save(program.get());
}
@@ -230,19 +263,20 @@ public List getAllMenteesByProgramId(long id)
}
/**
- * Create new {@link Mentor} and Record new {@link MentorResponse} list
+ * Create new {@link Mentor}
*
* @param programId which is the program id for the requesting {@link Program}
* @param profileId which is the profile id of the applying user's {@link Profile}
- * @param responses which holds the responses to be added
+ * @param mentor which holds the mentor details
* @return the created {@link Mentor}
*
* @throws ResourceNotFoundException is thrown if the applying {@link Program} doesn't exist
* @throws ResourceNotFoundException is thrown if the applying user's {@link Profile} doesn't exist
* @throws BadRequestException is thrown if the applying {@link Program} is
* not in the applicable {@link ProgramState}
+ * @throws BadRequestException is thrown if the applying user has already applied for the {@link Program}
*/
- public Mentor applyAsMentor(long programId, long profileId, List responses)
+ public Mentor applyAsMentor(long programId, long profileId, Mentor mentor)
throws ResourceNotFoundException, BadRequestException {
Optional optionalProgram = programRepository.findById(programId);
if (!optionalProgram.isPresent()) {
@@ -266,122 +300,94 @@ public Mentor applyAsMentor(long programId, long profileId, List
throw new ResourceNotFoundException(msg);
}
- Mentor mentor = new Mentor();
- mentor.setProfile(optionalProfile.get());
- mentor.setProgram(optionalProgram.get());
- mentor.setState(EnrolmentState.PENDING);
- Mentor savedMentor = mentorRepository.save(mentor);
- List processedResponses = new ArrayList<>();
- for (MentorResponse r: responses) {
- Question question = questionRepository.getOne(r.getQuestion().getId());
- MentorResponse updatedResponse = new MentorResponse(question, savedMentor, r.getResponse());
- processedResponses.add(updatedResponse);
- }
- try {
- mentorResponseRepository.saveAll(processedResponses);
- } catch (Exception e) {
- mentorRepository.delete(savedMentor);
- throw e;
+ Optional duplicateMentor = mentorRepository.findByProfileIdAndProgramId(profileId, programId);
+ if (duplicateMentor.isPresent()) {
+ String msg = "Error, Unable to apply as a mentor. " +
+ "Profile with id: " + profileId + " has already applied as a mentor for the selected program.";
+ log.error(msg);
+ throw new BadRequestException(msg);
}
- return savedMentor;
+
+ Mentor savedMentor = new Mentor();
+ savedMentor.setProfile(optionalProfile.get());
+ savedMentor.setProgram(optionalProgram.get());
+ savedMentor.setCategory(mentor.getCategory());
+ savedMentor.setBio(mentor.getBio());
+ savedMentor.setExpertise(mentor.getExpertise());
+ savedMentor.setInstitution(mentor.getInstitution());
+ savedMentor.setPosition(mentor.getPosition());
+ savedMentor.setSlots(mentor.getSlots());
+ savedMentor.setState(EnrolmentState.PENDING);
+ Mentor savedMentorEntity = mentorRepository.save(savedMentor);
+
+ Thread thread = new Thread(() -> {
+ try {
+ programUtil.sendConfirmationEmails(profileId, optionalProgram);
+ } catch (Exception exception) {
+ log.error("Email service error: ", exception);
+ }
+ });
+ thread.start();
+
+ return savedMentorEntity;
}
/**
- * Retrieves the {@link Mentor} of a user if the user is a mentor
+ * Update a {@link Mentor}
*
- * @param programId which is the id of the {@link Program}
- * @param profileId which is the id of the {@link Profile}
- * @return {@link Mentor}
+ * @param programId which is the program id for the mentor's {@link Program}
+ * @param profileId which is the profile id of the mentor's {@link Profile}
+ * @param mentor which holds the mentor details
+ * @return the updated {@link Mentor}
*
- * @throws ResourceNotFoundException if the requesting {@link Mentor} doesn't exist
+ * @throws ResourceNotFoundException is thrown if the mentor doesn't exist
+ * @throws BadRequestException is thrown if the {@link Program} is not in the applicable {@link ProgramState}
*/
- public Mentor getLoggedInMentor(long programId, long profileId)
- throws ResourceNotFoundException {
+ public Mentor updateMentorApplication(long programId, long profileId, Mentor mentor)
+ throws ResourceNotFoundException, BadRequestException {
Optional optionalMentor = mentorRepository.findByProfileIdAndProgramId(profileId, programId);
if (!optionalMentor.isPresent()) {
- String msg = "Error, Mentor by profile id: " + profileId + " and " +
- "program id: " + programId + " doesn't exist.";
+ String msg = "Error, Unable to update mentor application. " +
+ "Mentor with profile id: " + profileId + " doesn't exist.";
log.error(msg);
throw new ResourceNotFoundException(msg);
}
- return optionalMentor.get();
- }
- /**
- * Retrieves the {@link MentorResponse} List of a {@link Mentor}
- *
- * @param programId which is the Id of the {@link Program}
- * @param profileId which is the profile Id of the {@link Mentor}
- * @return {@link MentorResponse} list
- * @throws ResourceNotFoundException if a mentor doesn't exist by the given programId and profileId
- */
- public List getMentorResponses(long programId, long profileId) throws ResourceNotFoundException {
- Optional mentor = mentorRepository.findByProfileIdAndProgramId(profileId, programId);
- if (!mentor.isPresent()) {
- String msg = "Error, Mentor by profile id: " + profileId + " and " +
- "program id: " + programId + " cannot be found. " +
- "Mentor doesn't exist.";
+ if (!ProgramState.MENTOR_APPLICATION.equals(optionalMentor.get().getProgram().getState())) {
+ String msg = "Error, Unable to update mentor application. " +
+ "Program with id: " + programId + " is not in the valid state.";
log.error(msg);
- throw new ResourceNotFoundException(msg);
+ throw new BadRequestException(msg);
}
- return mentorResponseRepository.getAllByMentorId(mentor.get().getId());
- }
- /**
- * Retrives the {@link MentorResponse} List of a {@link Mentor}
- *
- * @param mentorId which is the id of the {@link Mentor}
- * @return {@link MentorResponse} list
- * @throws ResourceNotFoundException if a mentor doesn't exist by the given mentorId
- */
- public List getMentorResponses(long mentorId) throws ResourceNotFoundException {
- Optional mentor = mentorRepository.findById(mentorId);
- if (!mentor.isPresent()) {
- String msg = "Error, Mentor by mentor id: " + mentorId + " cannot be found. " +
- "Mentor doesn't exist.";
- log.error(msg);
- throw new ResourceNotFoundException(msg);
- }
- return mentorResponseRepository.getAllByMentorId(mentor.get().getId());
+ optionalMentor.get().setCategory(mentor.getCategory());
+ optionalMentor.get().setBio(mentor.getBio());
+ optionalMentor.get().setExpertise(mentor.getExpertise());
+ optionalMentor.get().setInstitution(mentor.getInstitution());
+ optionalMentor.get().setPosition(mentor.getPosition());
+ optionalMentor.get().setSlots(mentor.getSlots());
+ return mentorRepository.save(optionalMentor.get());
}
/**
- * Update the application question responses of a {@link Mentor}
+ * Retrieves the {@link Mentor} of a user if the user is a mentor
*
- * @param programId which is the id of the program
- * @param profileId which is the profile id of the {@link Mentor}
- * @param mentorResponses list of {@link MentorResponse}s to be updated
- * @return the updated list of {@link MentorResponse}
- * @throws ResourceNotFoundException if a mentor doesn't exist by the given profileId and programId
- * @throws BadRequestException is thrown if the {@link Program} is not in the valid {@link ProgramState}
+ * @param programId which is the id of the {@link Program}
+ * @param profileId which is the id of the {@link Profile}
+ * @return {@link Mentor}
+ *
+ * @throws ResourceNotFoundException if the requesting {@link Mentor} doesn't exist
*/
- public List editMentorResponses(long programId,
- long profileId,
- List mentorResponses)
- throws ResourceNotFoundException, BadRequestException {
- Optional mentor = mentorRepository.findByProfileIdAndProgramId(profileId, programId);
- if (!mentor.isPresent()) {
+ public Mentor getLoggedInMentor(long programId, long profileId)
+ throws ResourceNotFoundException {
+ Optional optionalMentor = mentorRepository.findByProfileIdAndProgramId(profileId, programId);
+ if (!optionalMentor.isPresent()) {
String msg = "Error, Mentor by profile id: " + profileId + " and " +
- "program id: " + programId + " cannot be found. " +
- "Mentor doesn't exist.";
+ "program id: " + programId + " doesn't exist.";
log.error(msg);
throw new ResourceNotFoundException(msg);
}
-
- if (!ProgramState.MENTOR_APPLICATION.equals(mentor.get().getProgram().getState())) {
- String msg = "Error, Unable to edit mentor application. " +
- "Program with id: " + programId + " is not in the valid state.";
- log.error(msg);
- throw new BadRequestException(msg);
- }
-
- List updatedMentorResponses = new ArrayList<>();
- for (MentorResponse response: mentorResponses) {
- MentorResponse queriedResponse = mentorResponseRepository.getOne(response.getId());
- queriedResponse.setResponse(response.getResponse());
- updatedMentorResponses.add(queriedResponse);
- }
- return mentorResponseRepository.saveAll(updatedMentorResponses);
+ return optionalMentor.get();
}
/**
@@ -389,31 +395,22 @@ public List editMentorResponses(long programId,
*
* @param programId which is the id of the {@link Program}
* @param profileId which is the profile id of the {@link Mentee}
- * @param menteeStates which is the list of states that {@link Mentee} objects should be
- * filtered from
- * @return {@link List} of {@link Mentor} objects
+ * @return {@link Mentor} object
*
* @throws NoContentException if the user hasn't applied for {@link Mentor} objects
*/
- public List getAppliedMentorsOfMentee(long programId, List menteeStates, long profileId)
+ public Mentor getAppliedMentorOfMentee(long programId, long profileId)
throws NoContentException {
- List menteeList;
- if (menteeStates == null || menteeStates.isEmpty()) {
- menteeList = menteeRepository.findAllByProgramIdAndProfileId(programId, profileId);
- } else {
- menteeList = menteeRepository.findAllByProgramIdAndProfileIdAndStateIn(programId, profileId, menteeStates);
- }
- if (menteeList.isEmpty()) {
+ Optional mentee = menteeRepository.findByProgramIdAndProfileId(programId, profileId);
+
+ if (!mentee.isPresent()) {
String msg = "Error, Mentee by program id: " + programId + " and " +
"profile id: " + profileId + " doesn't exist.";
log.error(msg);
throw new NoContentException(msg);
}
- List mentorList = new ArrayList<>();
- for (Mentee mentee : menteeList) {
- mentorList.add(mentee.getMentor());
- }
- return mentorList;
+
+ return mentee.get().getAppliedMentor();
}
/**
@@ -427,18 +424,16 @@ public List getAppliedMentorsOfMentee(long programId, List menteeList = menteeRepository
- .findAllByProgramIdAndProfileId(programId, profileId);
- if (menteeList.isEmpty()) {
+ Optional optionalMentee = menteeRepository
+ .findByProgramIdAndProfileId(programId, profileId);
+ if (!optionalMentee.isPresent()) {
String msg = "Error, Mentee by program id: " + programId + " and " +
"profile id: " + profileId + " doesn't exist.";
log.error(msg);
throw new ResourceNotFoundException(msg);
}
- for (Mentee mentee : menteeList) {
- if (EnrolmentState.APPROVED.equals(mentee.getState())) {
- return mentee.getMentor();
- }
+ if (EnrolmentState.APPROVED.equals(optionalMentee.get().getState())) {
+ return optionalMentee.get().getAssignedMentor();
}
String msg = "Error, Mentee is not approved by any mentor yet.";
@@ -447,54 +442,163 @@ public Mentor getSelectedMentor(long programId, long profileId)
}
/**
- * Retrieves the {@link Question} list for a given {@link Program} and a {@link QuestionCategory}
+ * Update the application of a {@link Mentee}
*
- * @param programId which is the if of the {@link Program}
- * @param category which is the identifier of if the required set of questions are mentor ones or mentee ones
- * @return {@link Question} Object list
- * @throws ResourceNotFoundException if the {@link Program} doesn't exist
+ * @param profileId which is the Profile id of the {@link Mentee} to be updated
+ * @param programId which is the Program id of the {@link Mentee} to be updated
+ * @param mentee with the application of the mentee to be updated
+ * @return the updated {@link Mentee}
+ *
+ * @throws ResourceNotFoundException is thrown if the {@link Mentee} doesn't exist
+ * @throws ResourceNotFoundException is thrown if the {@link Mentor} doesn't exist
+ * @throws BadRequestException if the {@link Mentor} is not in the valid state
+ * @throws BadRequestException if the {@link Mentee} is not in the valid state
+ * @throws BadRequestException is thrown if the applying program {@link Program} is not in applicable state {@link ProgramState}
*/
- public List getQuestions(long programId, QuestionCategory category) throws ResourceNotFoundException {
- Optional program = programRepository.findById(programId);
- if (!program.isPresent()) {
- String msg = "Error, Program by id: " + programId + " doesn't exist.";
+ public Mentee updateMenteeData(long profileId, long programId, Mentee mentee)
+ throws ResourceNotFoundException, BadRequestException {
+ Optional optionalMentee = menteeRepository.findByProgramIdAndProfileId(programId, profileId);
+ if (!optionalMentee.isPresent()) {
+ String msg = "Error, Mentee by profile id: " + profileId + " and " +
+ "program id: " + programId + " cannot be updated. " +
+ "Mentee doesn't exist.";
log.error(msg);
throw new ResourceNotFoundException(msg);
}
- return questionRepository.getAllByCategoryAndProgramId(category, program.get().getId());
+ if (!ProgramState.MENTEE_APPLICATION.equals(optionalMentee.get().getProgram().getState())) {
+ String msg = "Error, Unable to update mentee application. " +
+ "Program with id: " + programId + " is not in the valid state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+ Optional optionalMentor = mentorRepository.findById(mentee.getAppliedMentor().getId());
+ if (!optionalMentor.isPresent()) {
+ String msg = "Error, Mentee by profile id: " + profileId + " and " +
+ "program id: " + programId + " cannot be updated. " +
+ "Applied Mentor doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
+ if (!EnrolmentState.APPROVED.equals(optionalMentor.get().getState())) {
+ String msg = "Error, Unable to apply as a mentee. " +
+ "Mentor is not in the applicable state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+
+ Mentee existingMentee = optionalMentee.get();
+ if (EnrolmentState.PENDING.equals(existingMentee.getState())) {
+ existingMentee.setAppliedMentor(optionalMentor.get());
+ existingMentee.setIntent(mentee.getIntent());
+ existingMentee.setUniversity(mentee.getUniversity());
+ existingMentee.setYear(mentee.getYear());
+ existingMentee.setReasonForChoice(mentee.getReasonForChoice());
+ existingMentee.setResumeUrl(mentee.getResumeUrl());
+ existingMentee.setAchievements(mentee.getAchievements());
+ } else {
+ String msg = "Error, Application cannot be updated. " +
+ "Mentee is not in a valid state.";
+ log.error(msg);
+ throw new BadRequestException(msg);
+ }
+ return menteeRepository.save(existingMentee);
}
/**
- *Adds new {@link Question} objects to the {@link Program} mentor/mentee application forms
+ * Retrieves the {@link Mentee} of a user if the user is a mentee
*
* @param programId which is the id of the {@link Program}
- * @param category which is the identifier of whether the question is a {@link Mentor} one or a {@link Mentee} one
- * @param questions which is the list of questions
- * @return {@link Question} Object list
+ * @param profileId which is the id of the {@link Profile}
+ * @return {@link Mentee}
+ * @throws NoContentException if the user hasn't applied for {@link Program}
+ */
+ public Mentee getLoggedInMentee(long programId, long profileId)
+ throws NoContentException {
+ Optional optionalMentee = menteeRepository.findByProgramIdAndProfileId(programId, profileId);
+ if (!optionalMentee.isPresent()) {
+ String msg = "Error, User by profile id: " + profileId + " hasn't applied for " +
+ "program with id: " + programId + ".";
+ log.error(msg);
+ throw new NoContentException(msg);
+ }
+ return optionalMentee.get();
+ }
+
+ /**
+ * Retrieves all the emails from {@link EnrolledUser}
+ *
+ * @param programId which is the id of the {@link Program}
+ * @return {@link List}
* @throws ResourceNotFoundException if the {@link Program} doesn't exist
- * @throws BadRequestException if the {@link Program} is not in valid state
*/
- public List addQuestions(long programId, QuestionCategory category, List questions)
- throws ResourceNotFoundException, BadRequestException {
+ public List getEmailsAddresses(long programId)
+ throws ResourceNotFoundException {
Optional program = programRepository.findById(programId);
if (!program.isPresent()) {
String msg = "Error, Program by id: " + programId + " doesn't exist.";
log.error(msg);
throw new ResourceNotFoundException(msg);
}
- if (!ProgramState.CREATED.equals(program.get().getState())) {
- String msg = "Error, Unable to add question. " +
- "Program with id: " + programId + " is not in the valid state.";
- log.error(msg);
- throw new BadRequestException(msg);
+ List enrolledUsers = program.get().getEnrolledUsers();
+ List emails = new ArrayList();
+
+ for(EnrolledUser user: enrolledUsers) {
+ emails.add(user.getProfile().getEmail());
}
+ return emails;
+ }
- List processedQuestions = new ArrayList<>();
- for (Question q: questions) {
- q.setProgram(program.get());
- q.setCategory(category);
- processedQuestions.add(q);
+ /**
+ * Sends bulk emails to the recipients in {@link BulkEmailDto}
+ *
+ * @param programId which is the id of the {@link Program}
+ * @param bulkEmailDto which contains the recipients and the message
+ * @throws ResourceNotFoundException if the program doesn't exist
+ */
+ public void sendBulkEmails(long programId, BulkEmailDto bulkEmailDto)
+ throws ResourceNotFoundException {
+ Optional optionalProgram = programRepository.findById(programId);
+ if (!optionalProgram.isPresent()) {
+ String msg = "Error, Program with id: " + programId + " doesn't exist.";
+ log.error(msg);
+ throw new ResourceNotFoundException(msg);
+ }
+ Set emails = new HashSet<>();
+ for (MailGroup mailGroup : bulkEmailDto.getMailGroups()) {
+ if (mailGroup.equals(MailGroup.ALL)){
+ optionalProgram.get().getEnrolledUsers()
+ .forEach(user -> emails.add(user.getProfile().getEmail()));
+ } else if (mailGroup.equals(MailGroup.ALL_MENTORS)){
+ mentorRepository.findAllByProgramId(programId)
+ .forEach(mentor -> emails.add(mentor.getProfile().getEmail()));
+ } else if (mailGroup.equals(MailGroup.ALL_MENTEES)){
+ menteeRepository.findAllByProgramId(programId)
+ .forEach(mentee -> emails.add(mentee.getProfile().getEmail()));
+ } else if (mailGroup.equals(MailGroup.APPROVED_MENTORS)){
+ mentorRepository.findAllByProgramIdAndState(programId, EnrolmentState.APPROVED)
+ .forEach(mentor -> emails.add(mentor.getProfile().getEmail()));
+ } else if (mailGroup.equals(MailGroup.REJECTED_MENTORS)){
+ mentorRepository.findAllByProgramIdAndState(programId, EnrolmentState.REJECTED)
+ .forEach(mentor -> emails.add(mentor.getProfile().getEmail()));
+ } else if (mailGroup.equals(MailGroup.APPROVED_MENTEES)) {
+ menteeRepository.findAllByProgramIdAndState(programId, EnrolmentState.APPROVED)
+ .forEach(mentee -> emails.add(mentee.getProfile().getEmail()));
+ } else if (mailGroup.equals(MailGroup.DISCARDED_MENTEES)) {
+ menteeRepository.findAllByProgramIdAndStateIn(programId, ImmutableList.of(EnrolmentState.DISCARDED, EnrolmentState.FAILED_FROM_WILDCARD))
+ .forEach(mentee -> emails.add(mentee.getProfile().getEmail()));
+ }
}
- return questionRepository.saveAll(processedQuestions);
+
+ emails.addAll(bulkEmailDto.getAdditionalEmails());
+ Thread thread = new Thread(() -> {
+ for (String email : emails) {
+ try {
+ emailService.sendEmail(email, bulkEmailDto.getSubject(), bulkEmailDto.getMessage(), true);
+ } catch (MessagingException | IOException exception) {
+ log.error("Email service error: ", exception);
+ }
+ }
+ });
+ thread.start();
}
}
diff --git a/src/main/java/org/sefglobal/scholarx/service/QuestionService.java b/src/main/java/org/sefglobal/scholarx/service/QuestionService.java
deleted file mode 100644
index d06455a1..00000000
--- a/src/main/java/org/sefglobal/scholarx/service/QuestionService.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.sefglobal.scholarx.service;
-
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.model.Question;
-import org.sefglobal.scholarx.repository.QuestionRepository;
-import org.sefglobal.scholarx.util.ProgramState;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-@Service
-public class QuestionService {
- private final Logger log = LoggerFactory.getLogger(QuestionService.class);
- private final QuestionRepository questionRepository;
-
- public QuestionService(QuestionRepository questionRepository) {
- this.questionRepository = questionRepository;
- }
-
- /**
- * Updates existing {@link Question} records by a given set of {@link Question}
- *
- * @param questions the set of {@link Question} that needs to be updated
- * @return List of updated {@link Question}
- * @throws ResourceNotFoundException if a given {@link Question} doesn't exist on the database
- * @throws BadRequestException if the Program is not in the valid state
- */
- public List editQuestions(List questions) throws ResourceNotFoundException, BadRequestException {
- List updatedQuestions = new ArrayList<>();
- for(Question q: questions) {
- Optional question = questionRepository.findById(q.getId());
- if (!question.isPresent()) {
- String msg = "Error, question by id:" + q.getId() + " doesn't exist.";
- log.error(msg);
- throw new ResourceNotFoundException(msg);
- }
- if (!ProgramState.CREATED.equals(question.get().getProgram().getState())) {
- String msg = "Error, Unable to edit question by id:" + q.getId() + ". " +
- "Program is not in the valid state.";
- log.error(msg);
- throw new BadRequestException(msg);
- }
- question.get().setQuestion(q.getQuestion());
- updatedQuestions.add(question.get());
- }
- return questionRepository.saveAll(updatedQuestions);
- }
-
- /**
- * Deletes existing {@link Question} records by a given {@link Question} id
- *
- * @param id which is the id of the {@link Question} that needs to be deleted
- * @throws ResourceNotFoundException if a {@link Question} by the given id doesn't exist
- * @throws BadRequestException if the Program is not in the valid state
- */
- public void deleteQuestion(long id) throws ResourceNotFoundException, BadRequestException {
- Optional question = questionRepository.findById(id);
- if (!question.isPresent()) {
- String msg = "Error, question by id:" + id + " doesn't exist.";
- log.error(msg);
- throw new ResourceNotFoundException(msg);
- }
- if (!ProgramState.CREATED.equals(question.get().getProgram().getState())) {
- String msg = "Error, Unable to delete question. " +
- "Program is not in the valid state.";
- log.error(msg);
- throw new BadRequestException(msg);
- }
-
- questionRepository.delete(question.get());
- }
-}
diff --git a/src/main/java/org/sefglobal/scholarx/util/EnrolmentState.java b/src/main/java/org/sefglobal/scholarx/util/EnrolmentState.java
index 854d6653..92808b30 100644
--- a/src/main/java/org/sefglobal/scholarx/util/EnrolmentState.java
+++ b/src/main/java/org/sefglobal/scholarx/util/EnrolmentState.java
@@ -2,8 +2,12 @@
public enum EnrolmentState {
PENDING,
+ POOL,
+ ASSIGNED,
APPROVED,
+ DISCARDED,
REJECTED,
+ FAILED_FROM_WILDCARD,
REMOVED;
public boolean isHigherThanOrEqual(EnrolmentState state){
diff --git a/src/main/java/org/sefglobal/scholarx/util/MailGroup.java b/src/main/java/org/sefglobal/scholarx/util/MailGroup.java
new file mode 100644
index 00000000..62614723
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/util/MailGroup.java
@@ -0,0 +1,11 @@
+package org.sefglobal.scholarx.util;
+
+public enum MailGroup {
+ ALL,
+ ALL_MENTORS,
+ ALL_MENTEES,
+ APPROVED_MENTORS,
+ REJECTED_MENTORS,
+ APPROVED_MENTEES,
+ DISCARDED_MENTEES,
+}
diff --git a/src/main/java/org/sefglobal/scholarx/util/MentorCategory.java b/src/main/java/org/sefglobal/scholarx/util/MentorCategory.java
new file mode 100644
index 00000000..a8b57215
--- /dev/null
+++ b/src/main/java/org/sefglobal/scholarx/util/MentorCategory.java
@@ -0,0 +1,10 @@
+package org.sefglobal.scholarx.util;
+
+public enum MentorCategory {
+ ENGINEERING,
+ LIFE_SCIENCES,
+ COMPUTER_SCIENCE,
+ DATASCIENCE_AND_AI,
+ PHYSICAL_SCIENCE,
+ OTHER
+}
diff --git a/src/main/java/org/sefglobal/scholarx/util/ProgramState.java b/src/main/java/org/sefglobal/scholarx/util/ProgramState.java
index a892e009..a07b1fbe 100644
--- a/src/main/java/org/sefglobal/scholarx/util/ProgramState.java
+++ b/src/main/java/org/sefglobal/scholarx/util/ProgramState.java
@@ -5,8 +5,9 @@ public enum ProgramState {
MENTOR_APPLICATION,
MENTOR_SELECTION,
MENTEE_APPLICATION,
+ ADMIN_MENTEE_FILTRATION,
MENTEE_SELECTION,
- MENTOR_CONFIRMATION,
+ WILDCARD,
ONGOING,
COMPLETED,
REMOVED;
diff --git a/src/main/java/org/sefglobal/scholarx/util/ProgramUtil.java b/src/main/java/org/sefglobal/scholarx/util/ProgramUtil.java
index 7ef64adb..b952b974 100644
--- a/src/main/java/org/sefglobal/scholarx/util/ProgramUtil.java
+++ b/src/main/java/org/sefglobal/scholarx/util/ProgramUtil.java
@@ -2,13 +2,19 @@
import org.sefglobal.scholarx.model.Mentee;
import org.sefglobal.scholarx.model.Mentor;
+import org.sefglobal.scholarx.model.Profile;
import org.sefglobal.scholarx.model.Program;
+import org.sefglobal.scholarx.model.SentEmail;
+import org.sefglobal.scholarx.repository.EmailRepository;
import org.sefglobal.scholarx.repository.MenteeRepository;
import org.sefglobal.scholarx.repository.MentorRepository;
+import org.sefglobal.scholarx.repository.ProfileRepository;
import org.sefglobal.scholarx.service.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.mail.MessagingException;
import java.io.IOException;
@@ -16,12 +22,22 @@
@Component
public class ProgramUtil {
+ private static final Logger log=LoggerFactory.getLogger(ProgramUtil.class);
+ private final EmailRepository emailRepository;
+
+ public ProgramUtil(EmailRepository emailRepository){
+ this.emailRepository = emailRepository;
+ }
+
@Autowired
MentorRepository mentorRepository;
@Autowired
MenteeRepository menteeRepository;
+ @Autowired
+ ProfileRepository profileRepository;
+
@Autowired
private EmailService emailService;
@@ -45,6 +61,14 @@ public void sendMenteeApplicationEmails(long id, Optional program) thro
emailService.sendEmail(mentor.getProfile().getEmail(), StringUtils.capitalize(mentor.getState().name()), message, false);
+ SentEmail email = new SentEmail();
+ email.setEmail(mentor.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentor.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
+
} else if (mentor.getState().name().equals("REJECTED")) {
message = "Dear " + mentor.getProfile().getFirstName() + ",
" +
@@ -57,24 +81,20 @@ public void sendMenteeApplicationEmails(long id, Optional program) thro
emailService.sendEmail(mentor.getProfile().getEmail(), StringUtils.capitalize(mentor.getState().name()), message, false);
+ SentEmail email = new SentEmail();
+ email.setEmail(mentor.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentor.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
+
}
}
}
- public void sendMenteeSelectionEmails(long id, Optional program) throws IOException, MessagingException {
- List approvedMentors = mentorRepository.findAllByProgramIdAndState(id, EnrolmentState.APPROVED);
+ public void sendMenteeFiltrationEmails(long id, Optional program) throws MessagingException, IOException {
List mentees = getMenteesWithoutDuplicatesByProgramId(id);
-
- // Notify mentors
- for (Mentor mentor : approvedMentors) {
-
- String message = "Dear " + mentor.getProfile().getFirstName() + ",
" +
- "You have student applications waiting to be reviewed. You can approve or reject your mentees " +
- "by visiting the ScholarX dashboard.";
-
- emailService.sendEmail(mentor.getProfile().getEmail(), program.get().getTitle(), message, true);
- }
-
// Notify mentees
for (Mentee mentee : mentees) {
String message = "Dear " + mentee.getProfile().getFirstName() + ",
" +
@@ -85,33 +105,154 @@ public void sendMenteeSelectionEmails(long id, Optional program) throws
"for any clarifications.";
emailService.sendEmail(mentee.getProfile().getEmail(), program.get().getTitle(), message, false);
+
+ SentEmail email = new SentEmail();
+ email.setEmail(mentee.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentee.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
+ }
+ }
+
+ public void sendMenteeSelectionEmails(long id, Optional program) throws IOException, MessagingException {
+ List approvedMentors = mentorRepository.findAllByProgramIdAndState(id, EnrolmentState.APPROVED);
+ // Notify mentors
+ for (Mentor mentor : approvedMentors) {
+
+ String message = "Dear " + mentor.getProfile().getFirstName() + ",
" +
+
+ "It is with much pleasure we inform you that we have completed the first round of mentor-mentee matching.
" +
+ "There are a few points that we would like to share with you with regard to the mentee applications.
"+
+ ""+
+ "- The minimum word limit for each question of the application was introduced halfway through the application"+
+ "period in order to enhance competitiveness. Due to this reason, the applications which were received at the earliest"+
+ " stage might contain relatively short answers.
"+
+ "- Mentor-mentee matching process consists of two rounds.
"+
+ "- Some mentors have received an excess number of applications and we have selected potential mentees for those mentors"+
+ "after a filtering process. We kindly request you to go through these applications and select the mentees of your choice"+
+ "and decline the mentees who are not commendable enough before 28th April 11.59 p.m (IST), so that we can replace them during"+
+ "the second round of matching.
"+
+ "- Some mentors have received less than the number of available slots or none, owing to facts such as lack of compatibility"+
+ "of subject areas, more mentors representing the same subject area etc. We will be choosing the potential mentees for those mentors"+
+ "as well during the second round of matching.
"+
+ "We appreciate your enthusiasm in being a part of this journey and kindly request your cooperation in completing this matching process as well.
"+
+ "If you have any further queries please don't hesitate to contact us at"+
+ "sustainableedufoundation@gmail.com";
+
+ emailService.sendEmail(mentor.getProfile().getEmail(), program.get().getTitle(), message, true);
+
+ SentEmail email = new SentEmail();
+ email.setEmail(mentor.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentor.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
}
}
public void sendOnGoingEmails(long id, Optional program) throws IOException, MessagingException {
List approvedMentors = mentorRepository.findAllByProgramIdAndState(id, EnrolmentState.APPROVED);
+ List approvedMentees = menteeRepository.findAllByProgramIdAndState(id, EnrolmentState.APPROVED);
+ List discardedMentees = menteeRepository.findAllByProgramIdAndState(id, EnrolmentState.FAILED_FROM_WILDCARD);
for (Mentor mentor : approvedMentors) {
String message = "Dear " + mentor.getProfile().getFirstName() + ",
" +
- "Congratulations!
Students have accepted you as their mentor. " +
+ "Congratulations!
Your list of students is now finalised. " +
"You can check your mentees and their contact details by visiting the ScholarX dashboard. " +
"Please make the first contact with them as we have instructed them to wait for your email.";
+
+ String logMsg = "Email sent to mentor " + mentor.getProfile().getFirstName() + " " + mentor.getProfile().getLastName() + " " +
+ "of " + mentor.getProfile().getEmail();
+ log.info(logMsg);
emailService.sendEmail(mentor.getProfile().getEmail(), program.get().getTitle(), message, true);
+
+ SentEmail email = new SentEmail();
+ email.setEmail(mentor.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentor.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
}
- }
- public void sendMentorConfirmationEmails(long id, Optional program) throws IOException, MessagingException {
- List mentees = getMenteesWithoutDuplicatesByProgramId(id);
+ for (Mentee mentee: approvedMentees) {
+ Profile assignedMentor = mentee.getAssignedMentor().getProfile();
+ String message = "Dear " + mentee.getProfile().getFirstName() + ",
" +
+ "Congratulations!
You have been accepted as a mentee to be mentored under " +
+ assignedMentor.getFirstName() + " " + assignedMentor.getLastName() + ".
" +
+ "You can check your mentor and their details by visiting the ScholarX dashboard. " +
+ "Please make sure not to contact your mentor until they do as we have instructed them to " +
+ "make the first contact.
"+
+ "We will be holding an induction session for all successful ScholarX applicants over the coming " +
+ "weeks to take you through next steps of the program and answer any questions you may have about " +
+ "the matching process that was undertaken to enable the mentor-mentee pairing.";
- String message = "You can check your mentor by visiting the dashboard";
+ String logMsg = "Email sent to mentee " + mentee.getProfile().getFirstName() + " " + mentee.getProfile().getLastName() + " " +
+ "of " + mentee.getProfile().getEmail();
- for (Mentee mentee : mentees) {
+ log.info(logMsg);
+
emailService.sendEmail(mentee.getProfile().getEmail(), program.get().getTitle(), message, true);
+
+ SentEmail email = new SentEmail();
+ email.setEmail(mentee.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentee.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
+ }
+
+ for (Mentee mentee: discardedMentees) {
+ String message = "Dear " + mentee.getProfile().getFirstName() + ",
" +
+ "Thank you very much for taking your time to apply for the " + program.get().getTitle() + " program. " +
+ "However, We regret to inform you that your application couldn't make the cut this time." +
+ "We encourage you to try again next year and follow us on our social media channels for " +
+ "future programs. If you have any clarifications, please reach out to us via " +
+ "sustainableedufoundation@gmail.com" +
+ "You can check your application details by visiting the ScholarX dashboard.";
+
+ String logMsg = "Email sent to mentee " + mentee.getProfile().getFirstName() + " " + mentee.getProfile().getLastName() + " " +
+ "of " + mentee.getProfile().getEmail();
+ log.info(logMsg);
+
+ emailService.sendEmail(mentee.getProfile().getEmail(), program.get().getTitle(), message, true);
+
+ SentEmail email = new SentEmail();
+ email.setEmail(mentee.getProfile().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(mentee.getProfile());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
}
}
+ public void sendConfirmationEmails(long profileId, Optional program) throws MessagingException, IOException {
+ Optional profile = profileRepository.findById(profileId);
+ String message = "Dear " + profile.get().getFirstName() + ",
" +
+ "Thank you very much for applying to the " + program.get().getTitle() + " program. Your application has been received. " +
+ "You can view/edit your application by visiting the ScholarX dashboard. " +
+ "Reach out to us via " +
+ "sustainableedufoundation@gmail.com " +
+ "for any clarifications.";
+
+ emailService.sendEmail(profile.get().getEmail(), program.get().getTitle(), message, true);
+
+ SentEmail email = new SentEmail();
+ email.setEmail(profile.get().getEmail());
+ email.setMessage(message);
+ email.setProgramId(program.get());
+ email.setReceiver(profile.get());
+ email.setState(program.get().getState());
+ emailRepository.save(email);
+ }
+
/**
* Removes mentee duplicates
*/
diff --git a/src/main/java/org/sefglobal/scholarx/util/QuestionCategory.java b/src/main/java/org/sefglobal/scholarx/util/QuestionCategory.java
deleted file mode 100644
index b63f76c7..00000000
--- a/src/main/java/org/sefglobal/scholarx/util/QuestionCategory.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package org.sefglobal.scholarx.util;
-
-public enum QuestionCategory {
- MENTEE,
- MENTOR;
-}
diff --git a/src/main/resources/application.yml.example b/src/main/resources/application.yml.example
index caeb9fff..c4fc815e 100644
--- a/src/main/resources/application.yml.example
+++ b/src/main/resources/application.yml.example
@@ -21,15 +21,14 @@ spring:
user-name-attribute: id
email-address-uri: https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))
jpa:
- properties:
- hibernate:
- dialect: org.hibernate.dialect.MySQL5InnoDBDialect
+ database: postgresql
hibernate:
ddl-auto: update
datasource:
- url: jdbc:mysql://${DB_URL}/${DB_NAME}?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
+ url: jdbc:postgresql://${DB_URL}/${DB_NAME}?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: ${DB_USER_NAME}
password: ${DB_USER_PASSWORD}
+ platform: postgres
mail:
host: smtp.gmail.com
port: 587
@@ -43,3 +42,9 @@ spring:
enable: true
jmx:
unique-names: true
+server:
+ servlet:
+ session:
+ cookie:
+ max-age: 2d
+ timeout: 2d
diff --git a/src/main/resources/templates/scholarx.html b/src/main/resources/templates/scholarx.html
index d0cf81b7..05d7d5a0 100644
--- a/src/main/resources/templates/scholarx.html
+++ b/src/main/resources/templates/scholarx.html
@@ -108,10 +108,8 @@
Best regards,
- Dharana Jayawardane,
- Program Manager,
- ScholarX,
- Sustainable Education Foundation
+ ScholarX Team,
+ Sustainable Education Foundation.
View Dashboard
+
+ Join our Slack
+
diff --git a/src/main/test/java/org/sefglobal/scholarx/controller/IntrospectionControllerTest.java b/src/main/test/java/org/sefglobal/scholarx/controller/IntrospectionControllerTest.java
deleted file mode 100644
index 8171e5b3..00000000
--- a/src/main/test/java/org/sefglobal/scholarx/controller/IntrospectionControllerTest.java
+++ /dev/null
@@ -1,177 +0,0 @@
-package org.sefglobal.scholarx.controller;
-
-import org.junit.jupiter.api.Test;
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.NoContentException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.exception.UnauthorizedException;
-import org.sefglobal.scholarx.service.IntrospectionService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.web.servlet.MockMvc;
-
-import javax.servlet.http.Cookie;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.doThrow;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@WebMvcTest(controllers = IntrospectionController.class)
-public class IntrospectionControllerTest {
- @Autowired
- private MockMvc mockMvc;
- @MockBean
- private IntrospectionService introspectionService;
- private final Long programId = 1L;
- private final Long mentorId = 1L;
- private final Cookie profileIdCookie = new Cookie("profileId", "1");
-
- @Test
- void getLoggedInUser_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/me")
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getLoggedInMentor_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(introspectionService)
- .getLoggedInUser(anyLong());
-
- mockMvc.perform(get("/me")
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getLoggedInMentor_withUnsuitableData_thenReturns401() throws Exception {
- doThrow(UnauthorizedException.class)
- .when(introspectionService)
- .getLoggedInUser(anyLong());
-
- mockMvc.perform(get("/me")
- .cookie(profileIdCookie))
- .andExpect(status().isUnauthorized());
- }
-
- @Test
- void getMenteeingPrograms_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/me/programs/mentee")
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getMenteeingPrograms_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(introspectionService)
- .getMenteeingPrograms(anyLong());
-
- mockMvc.perform(get("/me/programs/mentee")
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getMenteeingPrograms_withUnavailableData_thenReturns204() throws Exception {
- doThrow(NoContentException.class)
- .when(introspectionService)
- .getMenteeingPrograms(anyLong());
-
- mockMvc.perform(get("/me/programs/mentee")
- .cookie(profileIdCookie))
- .andExpect(status().isNoContent());
- }
-
- @Test
- void getMentoringPrograms_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/me/programs/mentor")
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getMentoringPrograms_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(introspectionService)
- .getMentoringPrograms(anyLong());
-
- mockMvc.perform(get("/me/programs/mentor")
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getMentoringPrograms_withUnavailableData_thenReturns204() throws Exception {
- doThrow(NoContentException.class)
- .when(introspectionService)
- .getMentoringPrograms(anyLong());
-
- mockMvc.perform(get("/me/programs/mentor")
- .cookie(profileIdCookie))
- .andExpect(status().isNoContent());
- }
-
- @Test
- void getMentees_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/me/programs/{id}/mentees", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getMentees_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(introspectionService)
- .getMentees(anyLong(), anyLong(), any());
-
- mockMvc.perform(get("/me/programs/{id}/mentees", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getMentees_withUnavailableData_thenReturns204() throws Exception {
- doThrow(NoContentException.class)
- .when(introspectionService)
- .getMentees(anyLong(), anyLong(), any());
-
- mockMvc.perform(get("/me/programs/{id}/mentees", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isNoContent());
- }
-
- @Test
- void confirmMentor_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(put("/me/mentor/{mentorId}/confirmation", mentorId)
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void confirmMentor_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(introspectionService)
- .confirmMentor(anyLong(), anyLong());
-
- mockMvc.perform(put("/me/mentor/{mentorId}/confirmation", mentorId)
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void confirmMentor_withUnsuitableData_thenReturn400() throws Exception {
- doThrow(BadRequestException.class)
- .when(introspectionService)
- .confirmMentor(anyLong(), anyLong());
-
- mockMvc.perform(put("/me/mentor/{mentorId}/confirmation", mentorId)
- .cookie(profileIdCookie))
- .andExpect(status().isBadRequest());
- }
-}
diff --git a/src/main/test/java/org/sefglobal/scholarx/controller/MenteeControllerTest.java b/src/main/test/java/org/sefglobal/scholarx/controller/MenteeControllerTest.java
deleted file mode 100644
index fe110ed1..00000000
--- a/src/main/test/java/org/sefglobal/scholarx/controller/MenteeControllerTest.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.sefglobal.scholarx.controller;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.sefglobal.scholarx.controller.admin.MenteeController;
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.service.MenteeService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.web.servlet.MockMvc;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.doThrow;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@WebMvcTest(controllers = {MenteeController.class, org.sefglobal.scholarx.controller.MenteeController.class})
-public class MenteeControllerTest {
- @Autowired
- private MockMvc mockMvc;
- @Autowired
- private ObjectMapper objectMapper;
- @MockBean
- private MenteeService menteeService;
- private final Long menteeId = 1L;
-
- @Test
- void deleteMentee_withValidData_thenReturns204() throws Exception {
- mockMvc.perform(delete("/admin/mentees/{id}", menteeId))
- .andExpect(status().isNoContent());
- }
-
- @Test
- void deleteMentee_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(menteeService)
- .deleteMentee(anyLong());
-
- mockMvc.perform(delete("/admin/mentees/{id}", menteeId))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void approveOrRejectMentee_withValidData_thenReturns200() throws Exception {
- Map payload = new HashMap<>();
- payload.put("isApproved", true);
- mockMvc.perform(put("/mentees/{menteeId}/state", menteeId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(payload)))
- .andExpect(status().isOk());
- }
-
- @Test
- void approveOrRejectMentee_withUnavailableData_thenReturn404() throws Exception {
- Map payload = new HashMap<>();
- payload.put("isApproved", true);
- doThrow(ResourceNotFoundException.class)
- .when(menteeService)
- .approveOrRejectMentee(anyLong(), anyBoolean());
-
- mockMvc.perform(put("/mentees/{menteeId}/state", menteeId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(payload)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void approveOrRejectMentee_withUnsuitableData_thenReturn400() throws Exception {
- Map payload = new HashMap<>();
- payload.put("isApproved", true);
- doThrow(BadRequestException.class)
- .when(menteeService)
- .approveOrRejectMentee(anyLong(), anyBoolean());
-
- mockMvc.perform(put("/mentees/{menteeId}/state", menteeId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(payload)))
- .andExpect(status().isBadRequest());
- }
-}
diff --git a/src/main/test/java/org/sefglobal/scholarx/controller/MentorControllerTest.java b/src/main/test/java/org/sefglobal/scholarx/controller/MentorControllerTest.java
deleted file mode 100644
index 827f354b..00000000
--- a/src/main/test/java/org/sefglobal/scholarx/controller/MentorControllerTest.java
+++ /dev/null
@@ -1,218 +0,0 @@
-package org.sefglobal.scholarx.controller;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.sefglobal.scholarx.controller.admin.MentorController;
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.NoContentException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.model.Mentee;
-import org.sefglobal.scholarx.service.MentorService;
-import org.sefglobal.scholarx.util.EnrolmentState;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.web.servlet.MockMvc;
-
-import javax.servlet.http.Cookie;
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.*;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@WebMvcTest(controllers = {MentorController.class, org.sefglobal.scholarx.controller.MentorController.class})
-public class MentorControllerTest {
- @Autowired
- private MockMvc mockMvc;
- @Autowired
- private ObjectMapper objectMapper;
- @MockBean
- private MentorService mentorService;
- private final Long mentorId = 1L;
- private final Mentee mentee =
- new Mentee("http://scholarx/SCHOLARX-2020/submission");
- final Cookie profileIdCookie = new Cookie("profileId", "1");
-
- @Test
- void getMentors_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/mentors"))
- .andExpect(status().isOk());
- }
-
- @Test
- void getMentorById_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/mentors/{id}", mentorId))
- .andExpect(status().isOk());
- }
-
- @Test
- void getMentorById_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(mentorService)
- .getMentorById(anyLong());
-
- mockMvc.perform(get("/mentors/{id}", mentorId))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void updateState_withValidData_thenReturns200() throws Exception {
- Map payload = new HashMap<>();
- payload.put("state", EnrolmentState.APPROVED);
- mockMvc.perform(put("/admin/mentors/{id}/state", mentorId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(payload)))
- .andExpect(status().isOk());
- }
-
- @Test
- void updateState_withUnavailableData_thenReturn404() throws Exception {
- Map payload = new HashMap<>();
- payload.put("state", EnrolmentState.APPROVED);
- doThrow(ResourceNotFoundException.class)
- .when(mentorService)
- .updateState(anyLong(), any(EnrolmentState.class));
-
- mockMvc.perform(put("/admin/mentors/{id}/state", mentorId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(payload)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void applyAsMentee_withValidData_thenReturns201() throws Exception {
- mockMvc.perform(post("/mentors/{id}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andExpect(status().isCreated());
- }
-
- @Test
- void applyAsMentee_withValidData_thenReturnsValidResponseBody() throws Exception {
- mockMvc.perform(post("/mentors/{id}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andReturn();
-
- ArgumentCaptor menteeArgumentCaptor = ArgumentCaptor.forClass(Mentee.class);
- verify(mentorService, times(1)).applyAsMentee(anyLong(), anyLong(), menteeArgumentCaptor.capture());
-
- mentee.setState(null);
- String expectedResponse = objectMapper.writeValueAsString(mentee);
- String actualResponse = objectMapper.writeValueAsString(menteeArgumentCaptor.getValue());
- assertThat(actualResponse).isEqualTo(expectedResponse);
- }
-
- @Test
- void applyAsMentee_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(mentorService)
- .applyAsMentee(anyLong(), anyLong(), any(Mentee.class));
-
- mockMvc.perform(post("/mentors/{id}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void applyAsMentee_withUnavailableData_thenReturn400() throws Exception {
- doThrow(BadRequestException.class)
- .when(mentorService)
- .applyAsMentee(anyLong(), anyLong(), any(Mentee.class));
-
- mockMvc.perform(post("/mentors/{id}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andExpect(status().isBadRequest());
- }
-
- @Test
- void getMenteesOfMentor_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/mentors/{mentorId}/mentees", mentorId))
- .andExpect(status().isOk());
- }
-
- @Test
- void getMenteesOfMentor_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(mentorService)
- .getAllMenteesOfMentor(anyLong(), any());
-
- mockMvc.perform(get("/mentors/{mentorId}/mentees", mentorId))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getMenteesOfMentor_withUnsuitableData_thenReturns400() throws Exception {
- doThrow(BadRequestException.class)
- .when(mentorService)
- .getAllMenteesOfMentor(anyLong(), any());
-
- mockMvc.perform(get("/mentors/{mentorId}/mentees", mentorId))
- .andExpect(status().isBadRequest());
- }
-
- @Test
- void updateMenteeData_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(put("/mentors/{mentorId}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andExpect(status().isOk());
- }
-
- @Test
- void updateMenteeData_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(mentorService)
- .updateMenteeData(anyLong(), anyLong(), any(Mentee.class));
-
- mockMvc.perform(put("/mentors/{mentorId}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void updateMenteeData_withUnsuitableData_thenReturn400() throws Exception {
- doThrow(BadRequestException.class)
- .when(mentorService)
- .updateMenteeData(anyLong(), anyLong(), any(Mentee.class));
-
- mockMvc.perform(put("/mentors/{mentorId}/mentee", mentorId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentee)))
- .andExpect(status().isBadRequest());
- }
-
- @Test
- void getLoggedInMentee_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/mentors/{mentorId}/mentee", mentorId)
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getLoggedInMentee_withUnavailableData_thenReturns204() throws Exception {
- doThrow(NoContentException.class)
- .when(mentorService)
- .getLoggedInMentee(anyLong(), anyLong());
-
- mockMvc.perform(get("/mentors/{mentorId}/mentee", mentorId)
- .cookie(profileIdCookie))
- .andExpect(status().isNoContent());
- }
-}
diff --git a/src/main/test/java/org/sefglobal/scholarx/controller/ProgramControllerTest.java b/src/main/test/java/org/sefglobal/scholarx/controller/ProgramControllerTest.java
deleted file mode 100644
index e27ead6f..00000000
--- a/src/main/test/java/org/sefglobal/scholarx/controller/ProgramControllerTest.java
+++ /dev/null
@@ -1,306 +0,0 @@
-package org.sefglobal.scholarx.controller;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.sefglobal.scholarx.controller.admin.ProgramController;
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.NoContentException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.model.Mentor;
-import org.sefglobal.scholarx.model.Program;
-import org.sefglobal.scholarx.service.ProgramService;
-import org.sefglobal.scholarx.util.ProgramState;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.test.web.servlet.MockMvc;
-
-import javax.servlet.http.Cookie;
-
-import java.util.ArrayList;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.*;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@WebMvcTest(controllers = {ProgramController.class, org.sefglobal.scholarx.controller.ProgramController.class})
-public class ProgramControllerTest {
- @Autowired
- private MockMvc mockMvc;
- @Autowired
- private ObjectMapper objectMapper;
- @MockBean
- private ProgramService programService;
- private final Long programId = 1L;
- private final Program program
- = new Program("SCHOLARX-2020",
- "SCHOLARX program of 2020",
- "http://scholarx/images/SCHOLARX-2020",
- "http://scholarx/SCHOLARX-2020/home",
- ProgramState.CREATED);
- private final Mentor mentor
- = new Mentor("Sample application",
- "Sample prerequisites");
- final Cookie profileIdCookie = new Cookie("profileId", "1");
-
- @Test
- void addProgram_withValidData_thenReturns201() throws Exception {
- mockMvc.perform(post("/admin/programs")
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(program)))
- .andExpect(status().isCreated());
- }
-
- @Test
- void addProgram_withValidData_thenReturnsValidResponseBody() throws Exception {
- mockMvc.perform(post("/admin/programs")
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(program)))
- .andReturn();
-
- ArgumentCaptor programCaptor = ArgumentCaptor.forClass(Program.class);
- verify(programService, times(1)).addProgram(programCaptor.capture());
-
- program.setState(null);
- String expectedResponse = objectMapper.writeValueAsString(program);
- String actualResponse = objectMapper.writeValueAsString(programCaptor.getValue());
- assertThat(actualResponse).isEqualTo(expectedResponse);
- }
-
- @Test
- void updateState_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(put("/admin/programs/{id}/state", programId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(program.getState())))
- .andExpect(status().isOk());
- }
-
- @Test
- void updateState_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .updateState(anyLong());
-
- mockMvc.perform(put("/admin/programs/{id}/state", programId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(program.getState())))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void updateProgram_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(put("/admin/programs/{id}", programId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(program)))
- .andExpect(status().isOk());
- }
-
- @Test
- void updateProgram_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .updateProgram(anyLong(), any(Program.class));
-
- mockMvc.perform(put("/admin/programs/{id}", programId)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(program)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void deleteProgram_withValidData_thenReturns204() throws Exception {
- mockMvc.perform(delete("/admin/programs/{id}", programId))
- .andExpect(status().isNoContent());
- }
-
- @Test
- void deleteProgram_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .deleteProgram(anyLong());
-
- mockMvc.perform(delete("/admin/programs/{id}", programId))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getPrograms_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/programs"))
- .andExpect(status().isOk());
- }
-
- @Test
- void getProgramById_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/programs/{id}", programId))
- .andExpect(status().isOk());
- }
-
- @Test
- void getProgramById_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .getProgramById(anyLong());
-
- mockMvc.perform(get("/programs/{id}", programId))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getAllMentorsByProgramId_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/programs/{id}/mentors", programId))
- .andExpect(status().isOk());
- }
-
- @Test
- void getAllMentorsByProgramId_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .getAllMentorsByProgramId(anyLong(), any());
-
- mockMvc.perform(get("/programs/{id}/mentors", programId))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void applyAsMentor_withValidData_thenReturns201() throws Exception {
- mockMvc.perform(post("/programs/{id}/mentor", programId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentor)))
- .andExpect(status().isCreated());
- }
-
- @Test
- void applyAsMentor_withValidData_thenReturnsValidResponseBody() throws Exception {
- mockMvc.perform(post("/programs/{id}/mentor", programId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentor)))
- .andReturn();
-
- ArgumentCaptor mentorArgumentCaptor = ArgumentCaptor.forClass(Mentor.class);
- verify(programService, times(1)).applyAsMentor(anyLong(), anyLong(), mentorArgumentCaptor.capture());
-
- mentor.setState(null);
- String expectedResponse = objectMapper.writeValueAsString(mentor);
- String actualResponse = objectMapper.writeValueAsString(mentorArgumentCaptor.getValue());
- assertThat(actualResponse).isEqualTo(expectedResponse);
- }
-
- @Test
- void applyAsMentor_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .applyAsMentor(anyLong(), anyLong(), any(Mentor.class));
-
- mockMvc.perform(post("/programs/{id}/mentor", programId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentor)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void applyAsMentor_withUnavailableData_thenReturn400() throws Exception {
- doThrow(BadRequestException.class)
- .when(programService)
- .applyAsMentor(anyLong(), anyLong(), any(Mentor.class));
-
- mockMvc.perform(post("/programs/{id}/mentor", programId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentor)))
- .andExpect(status().isBadRequest());
- }
-
- @Test
- void getLoggedInMentor_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/programs/{id}/mentor", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getLoggedInMentor_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .getLoggedInMentor(anyLong(), anyLong());
-
- mockMvc.perform(get("/programs/{id}/mentor", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void updateMentorData_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(put("/programs/{programId}/application", programId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentor)))
- .andExpect(status().isOk());
- }
-
- @Test
- void updateMentorData_withUnavailableData_thenReturn404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .updateMentorData(anyLong(), anyLong(), any(Mentor.class));
-
- mockMvc.perform(put("/programs/{programId}/application", programId)
- .cookie(profileIdCookie)
- .contentType("application/json")
- .content(objectMapper.writeValueAsString(mentor)))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getAppliedMentors_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/programs/{id}/mentee/mentors", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getAppliedMentors_withUnavailableData_thenReturns204() throws Exception {
- doThrow(NoContentException.class)
- .when(programService)
- .getAppliedMentorsOfMentee(anyLong(), any(), anyLong());
-
- mockMvc.perform(get("/programs/{id}/mentee/mentors", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isNoContent());
- }
-
- @Test
- void getSelectedMentor_withValidData_thenReturns200() throws Exception {
- mockMvc.perform(get("/programs/{id}/mentee/mentor", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isOk());
- }
-
- @Test
- void getSelectedMentor_withUnavailableData_thenReturns404() throws Exception {
- doThrow(ResourceNotFoundException.class)
- .when(programService)
- .getSelectedMentor(anyLong(), anyLong());
-
- mockMvc.perform(get("/programs/{id}/mentee/mentor", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isNotFound());
- }
-
- @Test
- void getSelectedMentor_withUnavailableData_thenReturns204() throws Exception {
- doThrow(NoContentException.class)
- .when(programService)
- .getSelectedMentor(anyLong(), anyLong());
-
- mockMvc.perform(get("/programs/{id}/mentee/mentor", programId)
- .cookie(profileIdCookie))
- .andExpect(status().isNoContent());
- }
-}
diff --git a/src/main/test/java/org/sefglobal/scholarx/service/MenteeServiceTest.java b/src/main/test/java/org/sefglobal/scholarx/service/MenteeServiceTest.java
deleted file mode 100644
index 45c6ff6c..00000000
--- a/src/main/test/java/org/sefglobal/scholarx/service/MenteeServiceTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.sefglobal.scholarx.service;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.sefglobal.scholarx.exception.BadRequestException;
-import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.model.Mentee;
-import org.sefglobal.scholarx.model.Mentor;
-import org.sefglobal.scholarx.repository.MenteeRepository;
-import org.sefglobal.scholarx.util.EnrolmentState;
-
-import java.util.Optional;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.catchThrowable;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.Mockito.doReturn;
-
-@ExtendWith(MockitoExtension.class)
-public class MenteeServiceTest {
- @Mock
- private MenteeRepository menteeRepository;
- @InjectMocks
- private MenteeService menteeService;
- private final Long menteeId = 1L;
- private final Mentor mentor =
- new Mentor("Sample application",
- "Sample prerequisites");
-
- @Test
- void deleteMentee_withUnavailableData_thenThrowResourceNotFound() {
- doReturn(Optional.empty())
- .when(menteeRepository)
- .findById(anyLong());
-
- Throwable thrown = catchThrowable(
- () -> menteeService.deleteMentee(menteeId));
- assertThat(thrown)
- .isInstanceOf(ResourceNotFoundException.class)
- .hasMessage("Error, Mentee with id: 1 cannot be deleted. " +
- "Mentee doesn't exist.");
- }
-
- @Test
- void approveOrRejectMentee_withValidData_thenReturnUpdatedData()
- throws ResourceNotFoundException, BadRequestException {
- final Mentee mentee = new Mentee();
- mentee.setState(EnrolmentState.PENDING);
- doReturn(Optional.of(mentee))
- .when(menteeRepository)
- .findById(anyLong());
- doReturn(mentee)
- .when(menteeRepository)
- .save(any(Mentee.class));
-
- Mentee savedMentee = menteeService.approveOrRejectMentee(menteeId, true);
- assertThat(savedMentee).isNotNull();
- assertThat(savedMentee.getState()).isEqualTo(EnrolmentState.APPROVED);
- }
-
- @Test
- void approveOrRejectMentee_withUnavailableData_thenThrowResourceNotFound() {
- doReturn(Optional.empty())
- .when(menteeRepository)
- .findById(anyLong());
-
- Throwable thrown = catchThrowable(
- () -> menteeService.approveOrRejectMentee(menteeId, true));
- assertThat(thrown)
- .isInstanceOf(ResourceNotFoundException.class)
- .hasMessage("Error, Mentee cannot be approved/rejected. " +
- "Mentee with id: 1 doesn't exist.");
- }
-
- @Test
- void approveOrRejectMentee_withUnsuitableData_thenThrowBadRequest() {
- final Mentee mentee = new Mentee();
- mentee.setState(EnrolmentState.REMOVED);
- doReturn(Optional.of(mentee))
- .when(menteeRepository)
- .findById(anyLong());
-
- Throwable thrown = catchThrowable(
- () -> menteeService.approveOrRejectMentee(menteeId, true));
- assertThat(thrown)
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Error, Mentee cannot be approved/rejected. " +
- "Mentee with id: 1 is removed.");
- }
-}
diff --git a/src/test/java/org/sefglobal/scholarx/controller/AuthUserControllerTest.java b/src/test/java/org/sefglobal/scholarx/controller/AuthUserControllerTest.java
new file mode 100644
index 00000000..cb488205
--- /dev/null
+++ b/src/test/java/org/sefglobal/scholarx/controller/AuthUserControllerTest.java
@@ -0,0 +1,137 @@
+package org.sefglobal.scholarx.controller;
+
+import org.junit.jupiter.api.Test;
+import org.sefglobal.scholarx.exception.BadRequestException;
+import org.sefglobal.scholarx.exception.NoContentException;
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.service.IntrospectionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doThrow;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@WebMvcTest(controllers = AuthUserController.class)
+public class AuthUserControllerTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @MockBean
+ private IntrospectionService introspectionService;
+ private final Long programId = 1L;
+ private final Long mentorId = 1L;
+
+ public static Authentication getOauthAuthentication() {
+ Profile profile = new Profile();
+ profile.setId(1);
+ profile.setFirstName("John");
+ profile.setLastName("Doe");
+ return new OAuth2AuthenticationToken(profile, null, "linkedin");
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteeingPrograms_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/me/programs/mentee")
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteeingPrograms_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(introspectionService)
+ .getMenteeingPrograms(anyLong());
+
+ mockMvc.perform(get("/api/me/programs/mentee")
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteeingPrograms_withUnavailableData_thenReturns204() throws Exception {
+ doThrow(NoContentException.class)
+ .when(introspectionService)
+ .getMenteeingPrograms(anyLong());
+
+ mockMvc.perform(get("/api/me/programs/mentee")
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentoringPrograms_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/me/programs/mentor")
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentoringPrograms_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(introspectionService)
+ .getMentoringPrograms(anyLong(), any());
+
+ mockMvc.perform(get("/api/me/programs/mentor")
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentoringPrograms_withUnavailableData_thenReturns204() throws Exception {
+ doThrow(NoContentException.class)
+ .when(introspectionService)
+ .getMentoringPrograms(anyLong(), any());
+
+ mockMvc.perform(get("/api/me/programs/mentor")
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentees_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/me/programs/{id}/mentees", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentees_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(introspectionService)
+ .getMentees(anyLong(), anyLong(), any());
+
+ mockMvc.perform(get("/api/me/programs/{id}/mentees", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentees_withUnavailableData_thenReturns204() throws Exception {
+ doThrow(NoContentException.class)
+ .when(introspectionService)
+ .getMentees(anyLong(), anyLong(), any());
+
+ mockMvc.perform(get("/api/me/programs/{id}/mentees", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+ }
+}
diff --git a/src/test/java/org/sefglobal/scholarx/controller/MenteeControllerTest.java b/src/test/java/org/sefglobal/scholarx/controller/MenteeControllerTest.java
new file mode 100644
index 00000000..66b5ca08
--- /dev/null
+++ b/src/test/java/org/sefglobal/scholarx/controller/MenteeControllerTest.java
@@ -0,0 +1,252 @@
+package org.sefglobal.scholarx.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.sefglobal.scholarx.exception.BadRequestException;
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.exception.UnauthorizedException;
+import org.sefglobal.scholarx.model.Comment;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.service.MenteeService;
+import org.sefglobal.scholarx.service.CommentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@WebMvcTest(controllers = {MenteeController.class, org.sefglobal.scholarx.controller.admin.MenteeController.class})
+public class MenteeControllerTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ObjectMapper objectMapper;
+ @MockBean
+ private MenteeService menteeService;
+ @MockBean
+ private CommentService commentService;
+ private final Long menteeId = 1L;
+ private final Long mentorId = 1L;
+ private final Long commentId = 1L;
+
+ private final Comment comment = new Comment();
+
+
+ public static Authentication getOauthAuthentication() {
+ Profile profile = new Profile();
+ profile.setId(1);
+ profile.setFirstName("John");
+ profile.setLastName("Doe");
+ return new OAuth2AuthenticationToken(profile, null, "linkedin");
+ }
+
+ @Test
+ @WithMockUser(username = "admin", authorities = {"ADMIN"})
+ void deleteMentee_withValidData_thenReturns204() throws Exception {
+ mockMvc.perform(delete("/api/admin/mentees/{id}", menteeId))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", authorities = {"ADMIN"})
+ void deleteMentee_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(menteeService)
+ .deleteMentee(anyLong());
+
+ mockMvc.perform(delete("/api/admin/mentees/{id}", menteeId))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void approveOrRejectMentee_withValidData_thenReturns200() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("isApproved", true);
+ mockMvc.perform(put("/api/mentees/{menteeId}/state", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload))
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void approveOrRejectMentee_withUnavailableData_thenReturn404() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("isApproved", true);
+ doThrow(ResourceNotFoundException.class)
+ .when(menteeService)
+ .approveOrRejectMentee(anyLong(), anyLong(), anyBoolean());
+
+ mockMvc.perform(put("/api/mentees/{menteeId}/state", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload))
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void approveOrRejectMentee_withUnsuitableData_thenReturn403() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("isApproved", true);
+ doThrow(UnauthorizedException.class)
+ .when(menteeService)
+ .approveOrRejectMentee(anyLong(), anyLong(), anyBoolean());
+
+ mockMvc.perform(put("/api/mentees/{menteeId}/state", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload))
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isUnauthorized());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void approveOrRejectMentee_withUnsuitableData_thenReturn400() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("isApproved", true);
+ doThrow(BadRequestException.class)
+ .when(menteeService)
+ .approveOrRejectMentee(anyLong(), anyLong(), anyBoolean());
+
+ mockMvc.perform(put("/api/mentees/{menteeId}/state", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload))
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateAssignedMentor_withValidData_thenReturns200() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("mentorId", mentorId);
+ mockMvc.perform(put("/api/admin/mentees/{menteeId}/assign", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload)))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateAssignedMentor_withUnavailableData_thenReturns404() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("mentorId", mentorId);
+ doThrow(ResourceNotFoundException.class)
+ .when(menteeService)
+ .updateAssignedMentor(anyLong(), anyLong());
+
+ mockMvc.perform(put("/api/admin/mentees/{menteeId}/assign", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload)))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateAssignedMentor_withUnsuitableData_thenReturns400() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("mentorId", mentorId);
+ doThrow(BadRequestException.class)
+ .when(menteeService)
+ .updateAssignedMentor(anyLong(), anyLong());
+
+ mockMvc.perform(put("/api/admin/mentees/{menteeId}/assign", menteeId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload)))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void addComment_withValidData_thenReturn201() throws Exception {
+ mockMvc.perform(post("/api/mentees/{id}/comments",menteeId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(comment)))
+ .andExpect(status().isCreated());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void addComment_withValidData_thenReturnsValidResponseBody() throws Exception {
+ mockMvc.perform(post("/api/mentees/{id}/comments",menteeId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(comment)))
+ .andReturn();
+
+ ArgumentCaptor commentCaptor = ArgumentCaptor.forClass(Comment.class);
+ verify(commentService, times(1)).addMenteeComment(anyLong(),anyLong(),commentCaptor.capture());
+
+ String expectedResponse = objectMapper.writeValueAsString(comment);
+ String actualResponse = objectMapper.writeValueAsString(commentCaptor.getValue());
+ assertThat(actualResponse).isEqualTo(expectedResponse);
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteeComments_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/mentees/{id}/comments",menteeId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteeComments_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(commentService)
+ .getAllMenteeComments(anyLong(),anyLong());
+
+ mockMvc.perform(get("/api/mentees/{id}/comments", menteeId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void deleteMenteeComment_withValidData_thenReturns204() throws Exception {
+ mockMvc.perform(delete("/api/mentees//comment/{id}", commentId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void deleteMenteeComment_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(commentService)
+ .deleteComment(anyLong(),anyLong());
+
+ mockMvc.perform(delete("/api/mentees//comment/{id}", commentId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateComment_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(put("/api/mentees/comment/{id}", commentId)
+ .contentType("application/json")
+ .with(authentication(getOauthAuthentication()))
+ .content(objectMapper.writeValueAsString(comment)))
+ .andExpect(status().isOk());
+ }
+}
diff --git a/src/test/java/org/sefglobal/scholarx/controller/MentorControllerTest.java b/src/test/java/org/sefglobal/scholarx/controller/MentorControllerTest.java
new file mode 100644
index 00000000..058757a2
--- /dev/null
+++ b/src/test/java/org/sefglobal/scholarx/controller/MentorControllerTest.java
@@ -0,0 +1,187 @@
+package org.sefglobal.scholarx.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.sefglobal.scholarx.controller.admin.MentorController;
+import org.sefglobal.scholarx.exception.BadRequestException;
+import org.sefglobal.scholarx.exception.NoContentException;
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.service.MentorService;
+import org.sefglobal.scholarx.util.EnrolmentState;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@WebMvcTest(controllers = {MentorController.class, org.sefglobal.scholarx.controller.MentorController.class})
+public class MentorControllerTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ObjectMapper objectMapper;
+ @MockBean
+ private MentorService mentorService;
+ private final Long mentorId = 1L;
+ private final Mentee mentee = new Mentee();
+
+ public static Authentication getOauthAuthentication() {
+ Profile profile = new Profile();
+ profile.setId(1);
+ profile.setFirstName("John");
+ profile.setLastName("Doe");
+ return new OAuth2AuthenticationToken(profile, null, "linkedin");
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentors_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/mentors"))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentorById_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/mentors/{id}", mentorId))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMentorById_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(mentorService)
+ .getMentorById(anyLong());
+
+ mockMvc.perform(get("/api/mentors/{id}", mentorId))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", authorities = {"ADMIN"})
+ void updateState_withValidData_thenReturns200() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("state", EnrolmentState.APPROVED);
+ mockMvc.perform(put("/api/admin/mentors/{id}/state", mentorId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload)))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", authorities = {"ADMIN"})
+ void updateState_withUnavailableData_thenReturn404() throws Exception {
+ Map payload = new HashMap<>();
+ payload.put("state", EnrolmentState.APPROVED);
+ doThrow(ResourceNotFoundException.class)
+ .when(mentorService)
+ .updateState(anyLong(), any(EnrolmentState.class));
+
+ mockMvc.perform(put("/api/admin/mentors/{id}/state", mentorId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(payload)))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void applyAsMentee_withValidData_thenReturns201() throws Exception {
+ mockMvc.perform(post("/api/mentors/{id}/mentee", mentorId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andExpect(status().isCreated());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void applyAsMentee_withValidData_thenReturnsValidResponseBody() throws Exception {
+ mockMvc.perform(post("/api/mentors/{id}/mentee", mentorId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andReturn();
+
+ ArgumentCaptor menteeArgumentCaptor = ArgumentCaptor.forClass(Mentee.class);
+ verify(mentorService, times(1)).applyAsMentee(anyLong(), anyLong(), menteeArgumentCaptor.capture());
+
+ mentee.setState(null);
+ String expectedResponse = objectMapper.writeValueAsString(mentee);
+ String actualResponse = objectMapper.writeValueAsString(menteeArgumentCaptor.getValue());
+ assertThat(actualResponse).isEqualTo(expectedResponse);
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void applyAsMentee_withUnavailableData_thenReturn404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(mentorService)
+ .applyAsMentee(anyLong(), anyLong(), any(Mentee.class));
+
+ mockMvc.perform(post("/api/mentors/{id}/mentee", mentorId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void applyAsMentee_withUnavailableData_thenReturn400() throws Exception {
+ doThrow(BadRequestException.class)
+ .when(mentorService)
+ .applyAsMentee(anyLong(), anyLong(), any(Mentee.class));
+
+ mockMvc.perform(post("/api/mentors/{id}/mentee", mentorId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteesOfMentor_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/mentors/{mentorId}/mentees", mentorId))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteesOfMentor_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(mentorService)
+ .getAllMenteesOfMentor(anyLong(), any());
+
+ mockMvc.perform(get("/api/mentors/{mentorId}/mentees", mentorId))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getMenteesOfMentor_withUnsuitableData_thenReturns400() throws Exception {
+ doThrow(BadRequestException.class)
+ .when(mentorService)
+ .getAllMenteesOfMentor(anyLong(), any());
+
+ mockMvc.perform(get("/api/mentors/{mentorId}/mentees", mentorId))
+ .andExpect(status().isBadRequest());
+ }
+}
diff --git a/src/test/java/org/sefglobal/scholarx/controller/ProgramControllerTest.java b/src/test/java/org/sefglobal/scholarx/controller/ProgramControllerTest.java
new file mode 100644
index 00000000..642a2923
--- /dev/null
+++ b/src/test/java/org/sefglobal/scholarx/controller/ProgramControllerTest.java
@@ -0,0 +1,379 @@
+package org.sefglobal.scholarx.controller;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.sefglobal.scholarx.controller.admin.ProgramController;
+import org.sefglobal.scholarx.exception.BadRequestException;
+import org.sefglobal.scholarx.exception.NoContentException;
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Mentor;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.model.Program;
+import org.sefglobal.scholarx.service.ProgramService;
+import org.sefglobal.scholarx.util.ProgramState;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.*;
+import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@WebMvcTest(controllers = {ProgramController.class, org.sefglobal.scholarx.controller.ProgramController.class})
+public class ProgramControllerTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ObjectMapper objectMapper;
+ @MockBean
+ private ProgramService programService;
+ private final Long programId = 1L;
+ private final Program program
+ = new Program("SCHOLARX-2020",
+ "SCHOLARX program of 2020",
+ "http://scholarx/images/SCHOLARX-2020",
+ "http://scholarx/SCHOLARX-2020/home",
+ ProgramState.CREATED);
+ private final Mentee mentee = new Mentee();
+
+ public static Authentication getOauthAuthentication() {
+ Profile profile = new Profile();
+ profile.setId(1);
+ profile.setFirstName("John");
+ profile.setLastName("Doe");
+ return new OAuth2AuthenticationToken(profile, null, "linkedin");
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void addProgram_withValidData_thenReturns201() throws Exception {
+ mockMvc.perform(post("/api/admin/programs")
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(program)))
+ .andExpect(status().isCreated());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void addProgram_withValidData_thenReturnsValidResponseBody() throws Exception {
+ mockMvc.perform(post("/api/admin/programs")
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(program)))
+ .andReturn();
+
+ ArgumentCaptor programCaptor = ArgumentCaptor.forClass(Program.class);
+ verify(programService, times(1)).addProgram(programCaptor.capture());
+
+ program.setState(null);
+ String expectedResponse = objectMapper.writeValueAsString(program);
+ String actualResponse = objectMapper.writeValueAsString(programCaptor.getValue());
+ assertThat(actualResponse).isEqualTo(expectedResponse);
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateState_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(put("/api/admin/programs/{id}/state", programId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(program.getState())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateState_withUnavailableData_thenReturn404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .updateState(anyLong());
+
+ mockMvc.perform(put("/api/admin/programs/{id}/state", programId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(program.getState())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateProgram_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(put("/api/admin/programs/{id}", programId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(program)))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void updateProgram_withUnavailableData_thenReturn404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .updateProgram(anyLong(), any(Program.class));
+
+ mockMvc.perform(put("/api/admin/programs/{id}", programId)
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(program)))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void deleteProgram_withValidData_thenReturns204() throws Exception {
+ mockMvc.perform(delete("/api/admin/programs/{id}", programId))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"ADMIN"})
+ void deleteProgram_withUnavailableData_thenReturn404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .deleteProgram(anyLong());
+
+ mockMvc.perform(delete("/api/admin/programs/{id}", programId))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getPrograms_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs"))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getProgramById_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs/{id}", programId))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getProgramById_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .getProgramById(anyLong());
+
+ mockMvc.perform(get("/api/programs/{id}", programId))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getAllMentorsByProgramId_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs/{id}/mentors", programId))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getAllMentorsByProgramId_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .getAllMentorsByProgramId(anyLong(), any());
+
+ mockMvc.perform(get("/api/programs/{id}/mentors", programId))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void applyAsMentor_withValidData_thenReturns201() throws Exception {
+ mockMvc.perform(post("/api/programs/{id}/mentor", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(new Mentor())))
+ .andExpect(status().isCreated());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateMentorApplication_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(put("/api/programs/{id}/mentor", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(new Mentor())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateMentorApplication_withUnavailableData_thenReturn404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .updateMentorApplication(anyLong(), anyLong(), any(Mentor.class));
+
+ mockMvc.perform(put("/api/programs/{id}/mentor", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(new Mentor())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateMentorApplication_withInvalidData_thenReturn400() throws Exception {
+ doThrow(BadRequestException.class)
+ .when(programService)
+ .updateMentorApplication(anyLong(), anyLong(), any(Mentor.class));
+
+ mockMvc.perform(put("/api/programs/{id}/mentor", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(new Mentor())))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getLoggedInMentor_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs/{id}/mentor", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getLoggedInMentor_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .getLoggedInMentor(anyLong(), anyLong());
+
+ mockMvc.perform(get("/api/programs/{id}/mentor", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getAppliedMentors_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs/{id}/mentee/mentors", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getAppliedMentors_withUnavailableData_thenReturns204() throws Exception {
+ doThrow(NoContentException.class)
+ .when(programService)
+ .getAppliedMentorOfMentee(anyLong(), anyLong());
+
+ mockMvc.perform(get("/api/programs/{id}/mentee/mentors", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getSelectedMentor_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs/{id}/mentee/mentor", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getSelectedMentor_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .getSelectedMentor(anyLong(), anyLong());
+
+ mockMvc.perform(get("/api/programs/{id}/mentee/mentor", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getSelectedMentor_withUnavailableData_thenReturns204() throws Exception {
+ doThrow(NoContentException.class)
+ .when(programService)
+ .getSelectedMentor(anyLong(), anyLong());
+
+ mockMvc.perform(get("/api/programs/{id}/mentee/mentor", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getAllMenteesByProgramId_withUnavailableData_thenReturns404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .getAllMenteesByProgramId(anyLong());
+
+ mockMvc.perform(get("/api/programs/{id}/mentees", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateMenteeData_withUnavailableData_thenReturn404() throws Exception {
+ doThrow(ResourceNotFoundException.class)
+ .when(programService)
+ .updateMenteeData(anyLong(), anyLong(), any(Mentee.class));
+
+ mockMvc.perform(put("/api/programs/{programId}/mentee", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andExpect(status().isNotFound());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateMenteeData_withUnsuitableData_thenReturn400() throws Exception {
+ doThrow(BadRequestException.class)
+ .when(programService)
+ .updateMenteeData(anyLong(), anyLong(), any(Mentee.class));
+
+ mockMvc.perform(put("/api/programs/{programId}/mentee", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andExpect(status().isBadRequest());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void updateMenteeData_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(put("/api/programs/{programId}/mentee", programId)
+ .with(authentication(getOauthAuthentication()))
+ .contentType("application/json")
+ .content(objectMapper.writeValueAsString(mentee)))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getLoggedInMentee_withValidData_thenReturns200() throws Exception {
+ mockMvc.perform(get("/api/programs/{programId}/mentee", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isOk());
+ }
+
+ @Test
+ @WithMockUser(username = "user", authorities = {"DEFAULT"})
+ void getLoggedInMentee_withUnavailableData_thenReturns204() throws Exception {
+
+ doThrow(NoContentException.class)
+ .when(programService)
+ .getLoggedInMentee(anyLong(), anyLong());
+
+ mockMvc.perform(get("/api/programs/{programId}/mentee", programId)
+ .with(authentication(getOauthAuthentication())))
+ .andExpect(status().isNoContent());
+
+ }
+}
diff --git a/src/test/java/org/sefglobal/scholarx/service/CommentServiceTest.java b/src/test/java/org/sefglobal/scholarx/service/CommentServiceTest.java
new file mode 100644
index 00000000..2718a94f
--- /dev/null
+++ b/src/test/java/org/sefglobal/scholarx/service/CommentServiceTest.java
@@ -0,0 +1,229 @@
+package org.sefglobal.scholarx.service;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.exception.UnauthorizedException;
+import org.sefglobal.scholarx.model.Comment;
+import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Mentor;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.repository.CommentRepository;
+import org.sefglobal.scholarx.repository.MenteeRepository;
+import org.sefglobal.scholarx.repository.ProfileRepository;
+import org.sefglobal.scholarx.util.ProfileType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.mockito.Mockito.doReturn;
+
+@ExtendWith(MockitoExtension.class)
+class CommentServiceTest {
+ private final Long menteeId = 1L;
+ private final Long profileId = 1L;
+ private final Long commentId = 1L;
+ @Mock
+ private CommentRepository commentRepository;
+ @Mock
+ private ProfileRepository profileRepository;
+ @Mock
+ private MenteeRepository menteeRepository;
+ @InjectMocks
+ private CommentService commentService;
+
+ @Test
+ void getAllMenteeCommentsByMenteeId_withAvailableData_thenReturnDataFromRepository()
+ throws UnauthorizedException, ResourceNotFoundException {
+ Mentee mentee = new Mentee();
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(menteeId);
+ Profile profile = new Profile();
+ profile.setType(ProfileType.ADMIN);
+ doReturn(Optional.of(profile))
+ .when(profileRepository)
+ .findById(profileId);
+ List comments = new ArrayList<>();
+ doReturn(comments).when(commentRepository)
+ .findAllByMenteeId(menteeId);
+ List returnedData = commentService.getAllMenteeComments(menteeId, profileId);
+ assertThat(returnedData).isEqualTo(comments);
+ }
+
+ @Test
+ void getAllMenteeCommentsByMenteeId__withUnavailableMenteeId_thenThrowResourceNotFoundException() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findById(menteeId);
+ Profile profile = new Profile();
+ profile.setType(ProfileType.ADMIN);
+ doReturn(Optional.of(profile))
+ .when(profileRepository)
+ .findById(profileId);
+ Throwable thrown = catchThrowable(
+ () -> commentService.getAllMenteeComments(menteeId, profileId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee by id: 1 doesn't exist.");
+ }
+
+ @Test
+ void getAllMenteeCommentsByMenteeId__withUnavailableProfileId_thenThrowUnauthorizedException() {
+ Mentee mentee = new Mentee();
+ Profile profile = new Profile();
+ profile.setId(2L);
+ Mentor mentor = new Mentor();
+ mentor.setProfile(profile);
+ mentee.setAssignedMentor(mentor);
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(menteeId);
+ profile.setType(ProfileType.DEFAULT);
+ doReturn(Optional.of(profile))
+ .when(profileRepository)
+ .findById(profileId);
+ Throwable thrown = catchThrowable(
+ () -> commentService.getAllMenteeComments(menteeId, profileId));
+ assertThat(thrown)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Error, User by id: 1 is not allowed access.");
+ }
+
+
+ @Test
+ void addMenteeCommentByMenteeIdAndProfileId_withUnavailableMenteeId_thenThrowResourceNotFoundException() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findById(menteeId);
+ Comment comment = new Comment();
+ Throwable thrown = catchThrowable(
+ () -> commentService.addMenteeComment(menteeId, profileId, comment));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee by id: 1 doesn't exist.");
+ }
+
+ @Test
+ void addMenteeCommentByMenteeIdAndProfileId_withUnavailableProfileId_thenThrowResourceNotFoundException() {
+ Mentee mentee = new Mentee();
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(menteeId);
+ doReturn(Optional.empty())
+ .when(profileRepository)
+ .findById(profileId);
+ Comment comment = new Comment();
+ Throwable thrown = catchThrowable(
+ () -> commentService.addMenteeComment(menteeId, profileId, comment));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, User by id: 1 doesn't exist.");
+ }
+
+ @Test
+ void addMenteeCommentByMenteeIdAndProfileId_withUnavailableProfileId_thenThrowUnauthorizedException() {
+ Mentee mentee = new Mentee();
+ Profile profile = new Profile();
+ profile.setId(2L);
+ Mentor mentor = new Mentor();
+ mentor.setProfile(profile);
+ mentee.setAssignedMentor(mentor);
+ Comment comment = new Comment();
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(menteeId);
+ profile.setType(ProfileType.DEFAULT);
+ doReturn(Optional.of(profile))
+ .when(profileRepository)
+ .findById(profileId);
+ Throwable thrown = catchThrowable(
+ () -> commentService.addMenteeComment(menteeId, profileId, comment));
+ assertThat(thrown)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Error, User by id: 1 is not allowed access.");
+ }
+
+ @Test
+ void updateCommentWithCommentId_withValidData_thenReturnUpdatedData()
+ throws UnauthorizedException, ResourceNotFoundException {
+ Mentee mentee = new Mentee();
+ mentee.setId(menteeId);
+ Profile profile = new Profile();
+ profile.setId(profileId);
+ Comment comment = new Comment();
+ comment.setCommented_by(profile);
+ doReturn(Optional.of(comment))
+ .when(commentRepository)
+ .findById(commentId);
+
+ doReturn(comment)
+ .when(commentRepository)
+ .save(comment);
+ Comment updateComment = commentService.updateComment(commentId, profileId, comment);
+ assertThat(updateComment).isNotNull();
+ }
+
+ @Test
+ void updateCommentWithCommentId_withUnAvailableData_thenThrowResourceNotFoundException() {
+ doReturn(Optional.empty())
+ .when(commentRepository)
+ .findById(commentId);
+ Comment comment = new Comment();
+ Throwable thrown = catchThrowable(
+ () -> commentService.updateComment(commentId, profileId, comment));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Comment with id: 1 cannot be updated. Comment doesn't exist.");
+ }
+
+ @Test
+ void updateCommentWithCommentId_withUnAvailableData_thenThrowUnauthorizedException() {
+ Comment comment = new Comment();
+ Profile profile = new Profile();
+ profile.setId(profileId);
+ comment.setCommented_by(profile);
+ doReturn(Optional.of(comment))
+ .when(commentRepository)
+ .findById(commentId);
+ Throwable thrown = catchThrowable(
+ () -> commentService.updateComment(commentId, 2L, comment));
+ assertThat(thrown)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Error, User by id: 2 is not allowed access.");
+ }
+
+ @Test
+ void deleteComment_withUnavailableData_thenThrowResourceNotFound() {
+ doReturn(Optional.empty())
+ .when(commentRepository)
+ .findById(commentId);
+ Throwable thrown = catchThrowable(
+ () -> commentService.deleteComment(commentId, profileId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Comment with id: 1 cannot be deleted. Comment doesn't exist.");
+ }
+
+ @Test
+ void deleteComment_withUnavailableData_thenThrowUnauthorizedException() {
+ Comment comment = new Comment();
+ Profile profile = new Profile();
+ profile.setId(profileId);
+ comment.setCommented_by(profile);
+ doReturn(Optional.of(comment))
+ .when(commentRepository)
+ .findById(commentId);
+ Throwable thrown = catchThrowable(
+ () -> commentService.deleteComment(commentId, 2L));
+ assertThat(thrown)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Error, User by id: 2 is not allowed access.");
+ }
+}
diff --git a/src/main/test/java/org/sefglobal/scholarx/service/IntrospectionServiceTest.java b/src/test/java/org/sefglobal/scholarx/service/IntrospectionServiceTest.java
similarity index 66%
rename from src/main/test/java/org/sefglobal/scholarx/service/IntrospectionServiceTest.java
rename to src/test/java/org/sefglobal/scholarx/service/IntrospectionServiceTest.java
index 5a03c774..895b9bbe 100644
--- a/src/main/test/java/org/sefglobal/scholarx/service/IntrospectionServiceTest.java
+++ b/src/test/java/org/sefglobal/scholarx/service/IntrospectionServiceTest.java
@@ -41,8 +41,7 @@ public class IntrospectionServiceTest {
private final long profileId = 1L;
private final long mentorId = 1L;
private final Mentor mentor = new Mentor();
- private final Mentee mentee =
- new Mentee("http://submission.url/");
+ private final Mentee mentee = new Mentee();
@Test
void getLoggedInUser_withUnavailableData_thenThrowResourceNotFound() {
@@ -58,7 +57,7 @@ void getLoggedInUser_withUnavailableData_thenThrowResourceNotFound() {
}
@Test
- void getLoggedInUser_withUnsuitableData_thenThrowResourceNotFound() {
+ void getLoggedInUser_withUnsuitableData_thenThrowUnauthorized() {
Throwable thrown = catchThrowable(
() -> introspectionService.getLoggedInUser(-1));
assertThat(thrown)
@@ -102,7 +101,7 @@ void getMentoringPrograms_withUnavailableData_thenThrowResourceNotFound() {
.existsById(anyLong());
Throwable thrown = catchThrowable(
- () -> introspectionService.getMentoringPrograms(profileId));
+ () -> introspectionService.getMentoringPrograms(profileId, EnrolmentState.APPROVED));
assertThat(thrown)
.isInstanceOf(ResourceNotFoundException.class)
.hasMessage("Error, Profile with id: 1 doesn't exist.");
@@ -113,12 +112,9 @@ void getMentoringPrograms_withUnavailableData_thenThrowNoContent() {
doReturn(true)
.when(profileRepository)
.existsById(anyLong());
- doReturn(new ArrayList())
- .when(mentorRepository)
- .findAllByProfileId(anyLong());
Throwable thrown = catchThrowable(
- () -> introspectionService.getMentoringPrograms(profileId));
+ () -> introspectionService.getMentoringPrograms(profileId, EnrolmentState.APPROVED));
assertThat(thrown)
.isInstanceOf(NoContentException.class)
.hasMessage("Error, User has not enrolled in any program as a mentor.");
@@ -152,69 +148,4 @@ void getMentees_withUnavailableData_thenThrowNoContent() {
.isInstanceOf(NoContentException.class)
.hasMessage("No mentees exist for the required program: 1 for the profile: 1");
}
-
- @Test
- void confirmMentor_withValidData_thenReturnUpdatedData()
- throws ResourceNotFoundException, BadRequestException {
- mentee.setState(EnrolmentState.APPROVED);
- Program program = new Program();
- program.setId(programId);
- mentor.setProgram(program);
- doReturn(Optional.of(mentor))
- .when(mentorRepository)
- .findById(anyLong());
- doReturn(Optional.of(mentee))
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
-
- Mentee savedMentee = introspectionService.confirmMentor(mentorId, profileId);
- assertThat(savedMentee).isNotNull();
- assertThat(savedMentee.getState()).isEqualTo(EnrolmentState.APPROVED);
- }
-
- @Test
- void confirmMentor_withUnavailableData_thenThrowResourceNotFound() {
- doReturn(Optional.empty())
- .when(mentorRepository)
- .findById(anyLong());
-
- Throwable thrown = catchThrowable(
- () -> introspectionService.confirmMentor(mentorId, profileId));
- assertThat(thrown)
- .isInstanceOf(ResourceNotFoundException.class)
- .hasMessage("Error, Mentor by id: 1 doesn't exist.");
- }
-
- @Test
- void confirmMentor_withUnavailableData_thenThrowBadRequest() {
- doReturn(Optional.of(mentor))
- .when(mentorRepository)
- .findById(anyLong());
- doReturn(Optional.empty())
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
-
- Throwable thrown = catchThrowable(
- () -> introspectionService.confirmMentor(mentorId, profileId));
- assertThat(thrown)
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Error, User with id: 1 haven't applied for mentor by id: 1.");
- }
-
- @Test
- void confirmMentor_withUnsuitableData_thenThrowBadRequest() {
- mentee.setState(EnrolmentState.PENDING);
- doReturn(Optional.of(mentor))
- .when(mentorRepository)
- .findById(anyLong());
- doReturn(Optional.of(mentee))
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
-
- Throwable thrown = catchThrowable(
- () -> introspectionService.confirmMentor(mentorId, profileId));
- assertThat(thrown)
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Error, User with id: 1 is not approved by the mentor by id: 1.");
- }
}
diff --git a/src/test/java/org/sefglobal/scholarx/service/MenteeServiceTest.java b/src/test/java/org/sefglobal/scholarx/service/MenteeServiceTest.java
new file mode 100644
index 00000000..ba00fe0b
--- /dev/null
+++ b/src/test/java/org/sefglobal/scholarx/service/MenteeServiceTest.java
@@ -0,0 +1,207 @@
+package org.sefglobal.scholarx.service;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.sefglobal.scholarx.exception.BadRequestException;
+import org.sefglobal.scholarx.exception.ResourceNotFoundException;
+import org.sefglobal.scholarx.exception.UnauthorizedException;
+import org.sefglobal.scholarx.model.Mentee;
+import org.sefglobal.scholarx.model.Mentor;
+import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.model.Program;
+import org.sefglobal.scholarx.repository.MenteeRepository;
+import org.sefglobal.scholarx.repository.MentorRepository;
+import org.sefglobal.scholarx.util.EnrolmentState;
+import org.sefglobal.scholarx.util.ProgramState;
+
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+
+@ExtendWith(MockitoExtension.class)
+public class MenteeServiceTest {
+ @Mock
+ private MenteeRepository menteeRepository;
+ @Mock
+ private MentorRepository mentorRepository;
+
+ @InjectMocks
+ private MenteeService menteeService;
+ private final Long menteeId = 1L;
+ private final Long profileId = 1L;
+ private final Long mentorId = 1L;
+ private final Mentor mentor = new Mentor();
+
+ @Test
+ void deleteMentee_withUnavailableData_thenThrowResourceNotFound() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.deleteMentee(menteeId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee with id: 1 cannot be deleted. " +
+ "Mentee doesn't exist.");
+ }
+
+ @Test
+ void approveOrRejectMentee_withValidData_thenReturnUpdatedData()
+ throws ResourceNotFoundException, BadRequestException, UnauthorizedException {
+ final Mentee mentee = new Mentee();
+ mentee.setState(EnrolmentState.PENDING);
+ Profile profile = new Profile();
+ profile.setId(profileId);
+ mentor.setProfile(profile);
+ mentee.setAssignedMentor(mentor);
+
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(anyLong());
+ doReturn(mentee)
+ .when(menteeRepository)
+ .save(any(Mentee.class));
+
+ Mentee savedMentee = menteeService.approveOrRejectMentee(menteeId, profileId, true);
+ assertThat(savedMentee).isNotNull();
+ assertThat(savedMentee.getState()).isEqualTo(EnrolmentState.APPROVED);
+ }
+
+ @Test
+ void approveOrRejectMentee_withUnavailableData_thenThrowResourceNotFound() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.approveOrRejectMentee(menteeId, profileId, true));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee cannot be approved/rejected. " +
+ "Mentee with id: 1 doesn't exist.");
+ }
+
+ @Test
+ void approveOrRejectMentee_withUnsuitableData_thenThrowUnauthorized() {
+ final Mentee mentee = new Mentee();
+ mentee.setState(EnrolmentState.PENDING);
+ mentor.setProfile(new Profile());
+ mentee.setAssignedMentor(mentor);
+
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.approveOrRejectMentee(menteeId, profileId, true));
+ assertThat(thrown)
+ .isInstanceOf(UnauthorizedException.class)
+ .hasMessage("Error, Mentee cannot be approved/rejected. " +
+ "Mentee with id: 1 is not a mentee of " +
+ "mentor with profile id: 1.");
+ }
+
+ @Test
+ void approveOrRejectMentee_withUnsuitableData_thenThrowBadRequest() {
+ final Mentee mentee = new Mentee();
+ mentee.setState(EnrolmentState.REMOVED);
+ Profile profile = new Profile();
+ profile.setId(profileId);
+ mentor.setProfile(profile);
+ mentee.setAssignedMentor(mentor);
+
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.approveOrRejectMentee(menteeId, profileId, true));
+ assertThat(thrown)
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Error, Mentee cannot be approved/rejected. " +
+ "Mentee with id: 1 is removed.");
+ }
+
+ @Test
+ void updateAssignedMentor_withValidData_thenReturnUpdatedData()
+ throws ResourceNotFoundException, BadRequestException {
+ final Mentee mentee = new Mentee();
+ final Program program = new Program();
+ program.setState(ProgramState.WILDCARD);
+ mentee.setProgram(program);
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(anyLong());
+ doReturn(Optional.of(mentor))
+ .when(mentorRepository)
+ .findById(anyLong());
+ doReturn(mentee)
+ .when(menteeRepository)
+ .save(any(Mentee.class));
+
+ Mentee savedMentee = menteeService.updateAssignedMentor(menteeId, mentorId);
+ assertThat(savedMentee).isNotNull();
+ }
+
+ @Test
+ void updateAssignedMentor_withUnavailableMentee_thenThrowResourceNotFound() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.updateAssignedMentor(menteeId, mentorId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee cannot be updated. " +
+ "Mentee with id: 1 doesn't exist.");
+ }
+
+ @Test
+ void updateAssignedMentor_withUnavailableMentor_thenThrowResourceNotFound() {
+ final Mentee mentee = new Mentee();
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(anyLong());
+ doReturn(Optional.empty())
+ .when(mentorRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.updateAssignedMentor(menteeId, mentorId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee cannot be updated. " +
+ "Mentor with id: 1 doesn't exist.");
+ }
+
+ @Test
+ void updateAssignedMentor_withUnsuitableData_thenThrowBadRequest() {
+ final Mentee mentee = new Mentee();
+ final Program program = new Program();
+ program.setState(ProgramState.CREATED);
+ mentee.setProgram(program);
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findById(anyLong());
+ doReturn(Optional.of(mentor))
+ .when(mentorRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> menteeService.updateAssignedMentor(menteeId, mentorId));
+ assertThat(thrown)
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Error, Mentee cannot be updated. " +
+ "Program is not in a valid state.");
+
+ }
+}
diff --git a/src/main/test/java/org/sefglobal/scholarx/service/MentorServiceTest.java b/src/test/java/org/sefglobal/scholarx/service/MentorServiceTest.java
similarity index 73%
rename from src/main/test/java/org/sefglobal/scholarx/service/MentorServiceTest.java
rename to src/test/java/org/sefglobal/scholarx/service/MentorServiceTest.java
index 509a08af..7343c6ac 100644
--- a/src/main/test/java/org/sefglobal/scholarx/service/MentorServiceTest.java
+++ b/src/test/java/org/sefglobal/scholarx/service/MentorServiceTest.java
@@ -11,15 +11,18 @@
import org.sefglobal.scholarx.model.Mentee;
import org.sefglobal.scholarx.model.Mentor;
import org.sefglobal.scholarx.model.Profile;
+import org.sefglobal.scholarx.model.Program;
import org.sefglobal.scholarx.repository.MenteeRepository;
import org.sefglobal.scholarx.repository.MentorRepository;
import org.sefglobal.scholarx.repository.ProfileRepository;
import org.sefglobal.scholarx.util.EnrolmentState;
+import org.sefglobal.scholarx.util.ProgramState;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.doReturn;
@@ -39,8 +42,7 @@ public class MentorServiceTest {
private final Long profileId = 1L;
private final Mentor mentor = new Mentor();
private final Profile profile = new Profile();
- private final Mentee mentee =
- new Mentee("http://submission.url/");
+ private final Mentee mentee = new Mentee();
@Test
void getMentorById_withUnavailableData_thenThrowResourceNotFound() {
@@ -57,7 +59,7 @@ void getMentorById_withUnavailableData_thenThrowResourceNotFound() {
@Test
void updateState_withValidData_thenReturnUpdatedData()
- throws ResourceNotFoundException {
+ throws ResourceNotFoundException, BadRequestException {
doReturn(Optional.of(mentor))
.when(mentorRepository)
.findById(anyLong());
@@ -69,23 +71,43 @@ void updateState_withValidData_thenReturnUpdatedData()
assertThat(savedMentor).isNotNull();
}
+ @Test
+ void updateState_withInvalidData_thenThrowsBadRequestException() {
+ Throwable thrown = catchThrowable(
+ () -> mentorService.updateState(mentorId, EnrolmentState.ASSIGNED));
+ assertThat(thrown)
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Error, Mentor with id: 1 cannot be updated. " +
+ "ASSIGNED is not an applicable state.");
+ }
+
@Test
void applyAsMentee_withValidData_thenReturnCreatedData()
throws ResourceNotFoundException, BadRequestException {
final Mentor mentor = new Mentor();
mentor.setState(EnrolmentState.APPROVED);
+ Program program = new Program();
+ program.setState(ProgramState.MENTEE_APPLICATION);
+ mentor.setProgram(program);
+
doReturn(Optional.of(mentor))
.when(mentorRepository)
.findById(anyLong());
doReturn(Optional.of(profile))
.when(profileRepository)
.findById(anyLong());
+ doReturn(Optional.empty())
+ .when(mentorRepository)
+ .findByProfileIdAndProgramId(anyLong(), anyLong());
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
doReturn(mentee)
.when(menteeRepository)
.save(any(Mentee.class));
- Mentee savedMentee = mentorService.applyAsMentee(programId, profileId, mentee);
+ Mentee savedMentee = mentorService.applyAsMentee(mentorId, profileId, mentee);
assertThat(savedMentee).isNotNull();
}
@@ -125,6 +147,10 @@ void applyAsMentee_withUnavailableProfile_thenThrowResourceNotFound() {
final Mentor mentor = new Mentor();
mentor.setState(EnrolmentState.APPROVED);
+ Program program = new Program();
+ program.setState(ProgramState.MENTEE_APPLICATION);
+ mentor.setProgram(program);
+
doReturn(Optional.of(mentor))
.when(mentorRepository)
.findById(anyLong());
@@ -166,63 +192,4 @@ void getAllMenteesOfMentor_withUnsuitableData_thenThrowBadRequest() {
.isInstanceOf(BadRequestException.class)
.hasMessage("Error, Mentor by id: 1 is not an approved mentor.");
}
-
- @Test
- void updateMenteeData_withValidData_thenReturnUpdatedData()
- throws ResourceNotFoundException, BadRequestException {
- mentee.setState(EnrolmentState.PENDING);
- mentee.setMentor(mentor);
- doReturn(Optional.of(mentee))
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
- doReturn(mentee)
- .when(menteeRepository)
- .save(any(Mentee.class));
-
- Mentee savedMentee = mentorService.updateMenteeData(profileId, mentorId, mentee);
- assertThat(savedMentee).isNotNull();
- }
-
- @Test
- void updateMenteeData_withUnavailableData_thenThrowResourceNotFound() {
- doReturn(Optional.empty())
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
-
- Throwable thrown = catchThrowable(
- () -> mentorService.updateMenteeData(profileId, mentorId, mentee));
- assertThat(thrown)
- .isInstanceOf(ResourceNotFoundException.class)
- .hasMessage("Error, Mentee by profile id: 1 and mentor id: 1 cannot be updated. " +
- "Mentee doesn't exist.");
- }
-
- @Test
- void updateMenteeData_withUnsuitableData_thenThrowBadRequest() {
- mentee.setState(EnrolmentState.APPROVED);
- doReturn(Optional.of(mentee))
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
-
- Throwable thrown = catchThrowable(
- () -> mentorService.updateMenteeData(profileId, mentorId, mentee));
- assertThat(thrown)
- .isInstanceOf(BadRequestException.class)
- .hasMessage("Error, Application cannot be updated. " +
- "Mentee is not in a valid state.");
- }
-
- @Test
- void getLoggedInMentee_withUnavailableData_thenThrowNoContent() {
- doReturn(Optional.empty())
- .when(menteeRepository)
- .findByProfileIdAndMentorId(anyLong(), anyLong());
-
- Throwable thrown = catchThrowable(
- () -> mentorService.getLoggedInMentee(mentorId, profileId));
- assertThat(thrown)
- .isInstanceOf(NoContentException.class)
- .hasMessage("Error, User by profile id: 1 " +
- "hasn't applied for mentor with id: 1.");
- }
}
diff --git a/src/main/test/java/org/sefglobal/scholarx/service/ProgramServiceTest.java b/src/test/java/org/sefglobal/scholarx/service/ProgramServiceTest.java
similarity index 61%
rename from src/main/test/java/org/sefglobal/scholarx/service/ProgramServiceTest.java
rename to src/test/java/org/sefglobal/scholarx/service/ProgramServiceTest.java
index 75c6a086..00d16fac 100644
--- a/src/main/test/java/org/sefglobal/scholarx/service/ProgramServiceTest.java
+++ b/src/test/java/org/sefglobal/scholarx/service/ProgramServiceTest.java
@@ -8,14 +8,8 @@
import org.sefglobal.scholarx.exception.BadRequestException;
import org.sefglobal.scholarx.exception.NoContentException;
import org.sefglobal.scholarx.exception.ResourceNotFoundException;
-import org.sefglobal.scholarx.model.Mentee;
-import org.sefglobal.scholarx.model.Mentor;
-import org.sefglobal.scholarx.model.Profile;
-import org.sefglobal.scholarx.model.Program;
-import org.sefglobal.scholarx.repository.MenteeRepository;
-import org.sefglobal.scholarx.repository.MentorRepository;
-import org.sefglobal.scholarx.repository.ProfileRepository;
-import org.sefglobal.scholarx.repository.ProgramRepository;
+import org.sefglobal.scholarx.model.*;
+import org.sefglobal.scholarx.repository.*;
import org.sefglobal.scholarx.util.EnrolmentState;
import org.sefglobal.scholarx.util.ProgramState;
@@ -46,13 +40,12 @@ public class ProgramServiceTest {
private final Long profileId = 1L;
private final Program program =
new Program("SCHOLARX-2020", "SCHOLARX program of 2020",
- "http://scholarx/images/SCHOLARX-2020",
- "http://scholarx/SCHOLARX-2020/home", ProgramState.CREATED);
- private final Mentor mentor =
- new Mentor("Sample application",
- "Sample prerequisites");
- private final Profile profile =
- new Profile();
+ "https://scholarx/images/SCHOLARX-2020",
+ "https://scholarx/SCHOLARX-2020/home", ProgramState.CREATED);
+ private final Mentor mentor = new Mentor();
+ private final Profile profile = new Profile();
+ private final Mentee mentee = new Mentee();
+
@Test
void updateState_withValidData_thenReturnUpdatedData()
@@ -155,8 +148,8 @@ void applyAsMentor_withValidData_thenReturnCreatedData()
throws ResourceNotFoundException, BadRequestException {
final Program program =
new Program("SCHOLARX-2020", "SCHOLARX program of 2020",
- "http://scholarx/images/SCHOLARX-2020",
- "http://scholarx/SCHOLARX-2020/home",
+ "https://scholarx/images/SCHOLARX-2020",
+ "https://scholarx/SCHOLARX-2020/home",
ProgramState.MENTOR_APPLICATION);
doReturn(Optional.of(program))
@@ -205,8 +198,8 @@ void applyAsMentor_withUnsuitableData_thenThrowBadRequest() {
void applyAsMentor_withUnavailableProfile_thenThrowResourceNotFound() {
final Program program =
new Program("SCHOLARX-2020", "SCHOLARX program of 2020",
- "http://scholarx/images/SCHOLARX-2020",
- "http://scholarx/SCHOLARX-2020/home",
+ "https://scholarx/images/SCHOLARX-2020",
+ "https://scholarx/SCHOLARX-2020/home",
ProgramState.MENTOR_APPLICATION);
doReturn(Optional.of(program))
@@ -225,25 +218,15 @@ void applyAsMentor_withUnavailableProfile_thenThrowResourceNotFound() {
}
@Test
- void getLoggedInMentor_withUnavailableData_thenThrowResourceNotFound() {
- doReturn(Optional.empty())
- .when(mentorRepository)
- .findByProfileIdAndProgramId(anyLong(), anyLong());
-
- Throwable thrown = catchThrowable(
- () -> programService.getLoggedInMentor(programId, profileId));
- assertThat(thrown)
- .isInstanceOf(ResourceNotFoundException.class)
- .hasMessage("Error, Mentor by profile id: 1 " +
- "and program id: 1 doesn't exist.");
- }
-
- @Test
- void updateMentorData_withValidData_thenReturnUpdatedData()
+ void updateMentorApplication_withValidData_thenReturnUpdatedData()
throws ResourceNotFoundException, BadRequestException {
- mentor.setState(EnrolmentState.PENDING);
- program.setState(ProgramState.MENTOR_APPLICATION);
+ final Program program =
+ new Program("SCHOLARX-2020", "SCHOLARX program of 2020",
+ "https://scholarx/images/SCHOLARX-2020",
+ "https://scholarx/SCHOLARX-2020/home",
+ ProgramState.MENTOR_APPLICATION);
mentor.setProgram(program);
+
doReturn(Optional.of(mentor))
.when(mentorRepository)
.findByProfileIdAndProgramId(anyLong(), anyLong());
@@ -251,47 +234,67 @@ void updateMentorData_withValidData_thenReturnUpdatedData()
.when(mentorRepository)
.save(any(Mentor.class));
- Mentor savedMentor = programService.updateMentorData(profileId, programId, mentor);
+ Mentor savedMentor = programService.updateMentorApplication(programId, profileId, mentor);
assertThat(savedMentor).isNotNull();
}
@Test
- void updateMentorData_withUnavailableData_thenThrowResourceNotFound() {
+ void updateMentorApplication_withUnavailableData_thenThrowResourceNotFound() {
doReturn(Optional.empty())
.when(mentorRepository)
.findByProfileIdAndProgramId(anyLong(), anyLong());
Throwable thrown = catchThrowable(
- () -> programService.updateMentorData(profileId, programId, mentor));
+ () -> programService.updateMentorApplication(programId, profileId, mentor));
assertThat(thrown)
.isInstanceOf(ResourceNotFoundException.class)
- .hasMessage("Error, Mentor by profile id: 1 and program id: 1 cannot be updated. " +
- "Mentor doesn't exist.");
+ .hasMessage("Error, Unable to update mentor application. " +
+ "Mentor with profile id: 1 doesn't exist.");
}
@Test
- void updateMentorData_withUnsuitableData_thenThrowBadRequest() {
- mentor.setState(EnrolmentState.APPROVED);
+ void updateMentorApplication_withUnsuitableData_thenThrowBadRequest() {
+ final Program program =
+ new Program("SCHOLARX-2020", "SCHOLARX program of 2020",
+ "https://scholarx/images/SCHOLARX-2020",
+ "https://scholarx/SCHOLARX-2020/home",
+ ProgramState.MENTOR_SELECTION);
+ mentor.setProgram(program);
+
doReturn(Optional.of(mentor))
.when(mentorRepository)
.findByProfileIdAndProgramId(anyLong(), anyLong());
Throwable thrown = catchThrowable(
- () -> programService.updateMentorData(profileId, programId, mentor));
+ () -> programService.updateMentorApplication(programId, profileId, mentor));
assertThat(thrown)
.isInstanceOf(BadRequestException.class)
- .hasMessage("Error, Application cannot be updated. " +
- "Mentor is not in a valid state.");
+ .hasMessage("Error, Unable to update mentor application. " +
+ "Program with id: 1 is not in the valid state.");
}
@Test
- void getAppliedMentorsOfMentee_withUnavailableData_thenThrowNoContent() {
- doReturn(new ArrayList<>())
+ void getLoggedInMentor_withUnavailableData_thenThrowResourceNotFound() {
+ doReturn(Optional.empty())
+ .when(mentorRepository)
+ .findByProfileIdAndProgramId(anyLong(), anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> programService.getLoggedInMentor(programId, profileId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentor by profile id: 1 " +
+ "and program id: 1 doesn't exist.");
+ }
+
+ @Test
+ void getAppliedMentorOfMentee_withUnavailableData_thenThrowNoContent() {
+ doReturn(Optional.empty())
.when(menteeRepository)
- .findAllByProgramIdAndProfileId(anyLong(), anyLong());
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
Throwable thrown = catchThrowable(
- () -> programService.getAppliedMentorsOfMentee(programId, new ArrayList<>(), profileId));
+ () -> programService.getAppliedMentorOfMentee(programId, profileId));
assertThat(thrown)
.isInstanceOf(NoContentException.class)
.hasMessage("Error, Mentee by program id: 1 and " +
@@ -300,9 +303,9 @@ void getAppliedMentorsOfMentee_withUnavailableData_thenThrowNoContent() {
@Test
void getSelectedMentorOfMentee_withUnavailableData_thenThrowResourceNotFound() {
- doReturn(new ArrayList<>())
+ doReturn(Optional.empty())
.when(menteeRepository)
- .findAllByProgramIdAndProfileId(anyLong(), anyLong());
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
Throwable thrown = catchThrowable(
() -> programService.getSelectedMentor(programId, profileId));
@@ -314,11 +317,10 @@ void getSelectedMentorOfMentee_withUnavailableData_thenThrowResourceNotFound() {
@Test
void getSelectedMentorOfMentee_withUnavailableData_thenThrowNoContent() {
- List mentees = new ArrayList<>();
- mentees.add(new Mentee("SubmissionURL"));
- doReturn(mentees)
+ Mentee mentee = new Mentee();
+ doReturn(Optional.of(mentee))
.when(menteeRepository)
- .findAllByProgramIdAndProfileId(anyLong(), anyLong());
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
Throwable thrown = catchThrowable(
() -> programService.getSelectedMentor(programId, profileId));
@@ -326,4 +328,111 @@ void getSelectedMentorOfMentee_withUnavailableData_thenThrowNoContent() {
.isInstanceOf(NoContentException.class)
.hasMessage("Error, Mentee is not approved by any mentor yet.");
}
+
+ @Test
+ void getAllMenteesByProgramId_withUnavailableProgramId_thenThrowResourceNotFoundException() {
+ doReturn(false)
+ .when(programRepository)
+ .existsById(programId);
+
+ Throwable thrown = catchThrowable(
+ () -> programService.getAllMenteesByProgramId(programId));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Program by id: 1 doesn't exist");
+ }
+
+ @Test
+ void getAllMenteesByProgramId_withAvailableData_thenReturnDataFromRepository() throws ResourceNotFoundException {
+ doReturn(true)
+ .when(programRepository)
+ .existsById(programId);
+ List storedData = new ArrayList<>();
+ doReturn(storedData)
+ .when(menteeRepository)
+ .findAllByProgramId(programId);
+
+ List returnedData = programService.getAllMenteesByProgramId(programId);
+ assertThat(returnedData).isEqualTo(storedData);
+ }
+
+ @Test
+ void updateMenteeData_withValidData_thenReturnUpdatedData()
+ throws ResourceNotFoundException, BadRequestException {
+ mentor.setState(EnrolmentState.APPROVED);
+ mentee.setState(EnrolmentState.PENDING);
+ mentee.setAppliedMentor(mentor);
+
+ Program program = new Program();
+ program.setId(programId);
+ program.setState(ProgramState.MENTEE_APPLICATION);
+ mentee.setProgram(program);
+
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
+ doReturn(Optional.of(mentor))
+ .when(mentorRepository)
+ .findById(anyLong());
+ doReturn(mentee)
+ .when(menteeRepository)
+ .save(any(Mentee.class));
+
+ Mentee savedMentee = programService.updateMenteeData(profileId, programId, mentee);
+ assertThat(savedMentee).isNotNull();
+ }
+
+ @Test
+ void updateMenteeData_withUnavailableData_thenThrowResourceNotFound() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> programService.updateMenteeData(profileId, programId, mentee));
+ assertThat(thrown)
+ .isInstanceOf(ResourceNotFoundException.class)
+ .hasMessage("Error, Mentee by profile id: 1 and program id: 1 cannot be updated. " +
+ "Mentee doesn't exist.");
+ }
+
+ @Test
+ void updateMenteeData_withUnsuitableData_thenThrowBadRequest() {
+ mentee.setState(EnrolmentState.APPROVED);
+ mentor.setState(EnrolmentState.APPROVED);
+ mentee.setAppliedMentor(mentor);
+
+ Program program = new Program();
+ program.setId(programId);
+ program.setState(ProgramState.MENTEE_APPLICATION);
+ mentee.setProgram(program);
+
+ doReturn(Optional.of(mentee))
+ .when(menteeRepository)
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
+ doReturn(Optional.of(mentor))
+ .when(mentorRepository)
+ .findById(anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> programService.updateMenteeData(profileId, programId, mentee));
+ assertThat(thrown)
+ .isInstanceOf(BadRequestException.class)
+ .hasMessage("Error, Application cannot be updated. " +
+ "Mentee is not in a valid state.");
+ }
+
+ @Test
+ void getLoggedInMentee_withUnavailableData_thenThrowNoContent() {
+ doReturn(Optional.empty())
+ .when(menteeRepository)
+ .findByProgramIdAndProfileId(anyLong(), anyLong());
+
+ Throwable thrown = catchThrowable(
+ () -> programService.getLoggedInMentee(programId, profileId));
+ assertThat(thrown)
+ .isInstanceOf(NoContentException.class)
+ .hasMessage("Error, User by profile id: 1 " +
+ "hasn't applied for program with id: 1.");
+ }
}