Skip to content

Commit

Permalink
Remove Reports (Backend & Frontend) & Other Frontend Model Changes (#141
Browse files Browse the repository at this point in the history
)

* feat(domain): implemented Edit Enrollment

related issues: #28

* feat(service): implemented Edit Enrollment

* feat(controller): implemented PUT

related issues: #32

* feat: added update on participation.java

* feat: added Update Participation Method Test

Related: #52

* feat: added updateParticipation in ParticipationService.java

Related: #48

* feat: added UpdateParticipation Service test

Related: #50

* feat: added updateParticipation method in ParticipationController.java

Related: #44

* feat: added UpdateParticipationWebServiceIT.groovy

Related: #46

* feat: added deleteParticipation in ParticipationService.java

Related: #49

* feat: added deleteParticipation method in ParticipationController.java

Related: #45

* feat: added deleteParticipation Service test

Related: #51

* feat: added deleteParticipation WebService Test

Related: #47

* feat(domain test): implemented UpdateEnrollmentMethodTest

* feat(Service Test): implemented UpdateEnrollmentServiceTest

related issues: #40

* feat(domain): implemented Delete Enrollment and fix Edit Enrollment

related issues: #28 #29

* feat(WebService Test): implemented UpdateEnrollmentWebServiceIT

related issues: #38

* feat: added delete method in ParticipationService.java and updated necessary files to support delete operation

Related: #43

* feat: added delete participation domain tests

Related: #53

* feat(controller): implemented DELETE

related issues: #33

* feat(domain): fix Delete and Edit

related issues: #28 #29

* feat(Service): implemented Delete Enrollment

related issues: #35

* feat(domain test): updated UpdateEnrollmentMethodTest

related issues: #36

* feat(domain/serice/webservice tests):

	-implemented DeleteEnrollmentMethodTest
	-implemented DeleteEnrollmentServiceTest
	-updated UpdateEnrollmentServiceTest
	-implemented DeleteEnrollmentWebService

related issues: #37 #39 #40 #41

* feat(): small changes in some files

* feat(fix): small change

* feat(fix): small changes

* feat(fix): small changes

* feat(fix): fix some errors

* feat(fix): fix some erros

* feat(domain/service tests): fix some errors

relating issues: #37 #36 #35 #41

* feat(fix): small changes

* fix: prevent unauthorized access in participation controller

* fix update and remove participation access control

* fix: fixed webservice tests

* feat(domain/service/controller/tests):
      - changed EnrollmentController.java
      - implemented "ENROLLMENT.MANAGER" in HEPermissionEvaluator.java
      - changed Enrollment.java
      -  some changes in UpdateEnrollmentMethodTest, UpdateEnrollmentServiceTest, DeleteEnrollmentWebServiceIT and UpdateEnrollmentWebServiceIT

realted issues: #32 #33 #28 #29 #40 #36

* feat(domain): small changes

* feat(button/view):
                - implemented EditEnrollment Button
                - implemented RemoveEnrollment Button
                - implemented VolunteerEnrollmentsView

related issues: #71 #72 #70

* feat(End-to-End Tests):  implemented Remove/Edit Enrollment End-to-End Tests

realted issues: #74 #75 #76 #77 #78

* feat(fix): small changes

* feat(fix): fix errors
        - changed assement End-to-End tests
        - changes in VolunteerEnrollmetView

* small fixes

* feat(domain/service/controller):
	- create the "report" entity
	- implemented condition: only a Volunteer can report
	- implemented constraint: this justification can only be readed by a Administrator
	- implemented condition: report is associated to the volunteer who reported
	- implemented condition: only can be reported until the end of the activity
	- implmented POST: createReport
	- implemented GET: getAdministratorReports

	related issues: #94 #95 #96 #97 #98 #99 #100

* feat(domain/service/controller Tests):
	- Test Domain: CreateReportMethodTest
	- Test Service: CreateReportServiceTest
	- Test WebService: CreateReportWebServiceIT

	related issues: #101 #102 #103

* Merge master into pereira

* feat(fix): small change

* feat(fix): small change

* feat(Controller/Service/ Service Tests/WebServices Test): some changes

      -implement GetVolunteerReportsWebServiceIT
      -implement GetVolunteerReportsServicesTest
      -changes in RerportController and ReportService

      related issues: #119 #120 #100

* feat(fix): changes

* feat(fix): changes

* feat(fix): changes

* feat(fix): some changes

* feat(fix): some changes

* feat(Controller/Service/Service Test/WebServiceTest):
        -implemented GET: getActivtyReports
        -implemented Service: getReportsByActivity
        -implemented GetReportsByActivityServiceTest
        -implemented GetReportsByActivityWebServiceTest

        related issues: #121 #122 #123

* feat(fix): small change

* feat(fix): fix errors

* feat(button/view/dialog):
     - implemented Report Activity
     - implemented constraint: Report Button only exist until the activity end
     - implemented Report Dialog

     related issues: #125 #126 #127

* feat(button/view/dialog):

    - implemented button "REPORTED"
    - implemented Dialog to see all Activtiy Reports

    related issues: #130 #131

* feat(End-to-End Tests):
    - implemented Test: report an activity
    - implemented Test: Admin reads the Activity Reports

    related issues: #128 #129

* feat(domain / service / controller):
     - implemented Functionality: volunteer remove a report
     - implmented DELETE Controller
     - implemented Service Remove

     related issues: #135 #136 #137

* feat(Domain Test / Service Test/ WebService Test):
    - implemented domain test
    - implementeed service test
    - implemented webservice test

    related issues: #138 #139 #140

* feat(fix): changes

* feat(Controller / WebService Test): some changes in the validate activtiy

* feat(Controller / Service):
    - implemented Controller: getVolunteerReportsAsVolunteer
    - implemented Service: getVolunteerReportsAsVolunteer

    related issues: #142 #143

* feat(button):
   - implemented RemoveReport Button

   related issue: #144

* feat(frontend model):
   - Modify text boxes

   related issue: #145

* feat(frontend model):
   - in the VolunteerViews when the mouse go over "REPORTED" appears the justification
   - modify the "REPORTED" button in tje AdminActivitiesView

   related issues: #146 #147

* feat(End-to-End Tests):
  - remove a report from an activity

  related issues: #148 #149

---------

Co-authored-by: Andre Gamito <[email protected]>
Co-authored-by: André Pereira <[email protected]>
Co-authored-by: Antonio Rito Silva <[email protected]>
  • Loading branch information
4 people authored Jul 14, 2024
1 parent 50c64d6 commit 4a54648
Show file tree
Hide file tree
Showing 19 changed files with 714 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public ActivityDto suspendActivity(Principal principal, @PathVariable Integer ac
}

@PutMapping("/{activityId}/validate")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_VOLUNTEER')")
public ActivityDto validateActivity(@PathVariable int activityId) {
return activityService.validateActivity(activityId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ public void addReport(Report report) {
this.reports.add(report);
}

public void removeReport(Report report) {
this.reports.remove(report);
}

public void validate() {
activityAndThemesMustBeApproved();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import pt.ulisboa.tecnico.socialsoftware.humanaethica.participation.domain.Participation;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.enrollment.domain.Enrollment;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.enrollment.EnrollmentRepository;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.domain.Report;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.ReportRepository;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.user.domain.Member;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.user.domain.Volunteer;

Expand All @@ -29,6 +31,8 @@ public class HEPermissionEvaluator implements PermissionEvaluator {
private EnrollmentRepository enrollmentRepository;
@Autowired
private AssessmentRepository assessmentRepository;
@Autowired
private ReportRepository reportRepository;


@Override
Expand All @@ -51,6 +55,10 @@ public boolean hasPermission(Authentication authentication, Object targetDomainO
Enrollment enrollment = enrollmentRepository.findById(id).orElse(null);
if (enrollment == null) return false;
return enrollment.getVolunteer().getId().equals(((Volunteer)authUser.getUser()).getId());
case "REPORT.MANAGER":
Report report = reportRepository.findById(id).orElse(null);
if (report == null) return false;
return report.getVolunteer().getId().equals(((Volunteer)authUser.getUser()).getId());
case "ASSESSMENT.WRITER":
Assessment assessment = assessmentRepository.findById(id).orElse(null);
if (assessment == null) return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public enum ErrorMessage {
REPORT_REQUIRES_JUSTIFICATION("To do a report have to write a justification shorter than 256 characters"),
REPORT_ACTIVTIY_IS_ALREADY_REPORTED("The activity is already reported"),
REPORT_AFTER_ACTIVTY_CLOSED("The activity period is already closed"),
REPORT_NOT_FOUND("Report not found with id %d"),
;

public final String label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.web.bind.annotation.*;

import pt.ulisboa.tecnico.socialsoftware.humanaethica.auth.domain.AuthUser;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.enrollment.dto.EnrollmentDto;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.ReportService;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.dto.ReportDto;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.dto.ReportDto;
Expand Down Expand Up @@ -38,6 +39,21 @@ public ReportDto createReport(Principal principal, @PathVariable Integer activit
int userId = ((AuthUser) ((Authentication) principal).getPrincipal()).getUser().getId();
return reportService.createReport(userId, activityId, reportDto);
}

@DeleteMapping("/reports/{reportId}")
@PreAuthorize("(hasRole('ROLE_VOLUNTEER')) and hasPermission(#reportId, 'REPORT.MANAGER')")
public ReportDto removeReport(@PathVariable Integer reportId){
return reportService.removeReport(reportId);
}

@GetMapping("/reports/volunteer")
@PreAuthorize("(hasRole('ROLE_VOLUNTEER'))")
public List<ReportDto> getVolunteerReportsAsVolunteer(Principal principal) {
int userId = ((AuthUser) ((Authentication) principal).getPrincipal()).getUser().getId();
return reportService.getVolunteerReportsAsVolunteer(userId);
}



}

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import org.springframework.transaction.annotation.Transactional;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.activity.domain.Activity;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.activity.repository.ActivityRepository;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.enrollment.domain.Enrollment;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.enrollment.dto.EnrollmentDto;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.domain.Report;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.dto.ReportDto;
import pt.ulisboa.tecnico.socialsoftware.humanaethica.exceptions.HEException;
Expand Down Expand Up @@ -65,4 +67,29 @@ public ReportDto createReport(Integer userId, Integer activityId, ReportDto repo
return new ReportDto(report);
}

@Transactional(isolation = Isolation.READ_COMMITTED)
public ReportDto removeReport(Integer reportId) {
if (reportId == null) throw new HEException(REPORT_NOT_FOUND);

Report report = reportRepository.findById(reportId).orElseThrow(() -> new HEException(REPORT_NOT_FOUND, reportId));

report.delete();

reportRepository.delete(report);

return new ReportDto(report);
}

@Transactional(isolation = Isolation.READ_COMMITTED)
public List<ReportDto> getVolunteerReportsAsVolunteer(Integer userId) {
if (userId == null) throw new HEException(USER_NOT_FOUND);

return reportRepository.getReportsForVolunteerId(userId).stream()
.sorted(Comparator.comparing(Report::getReportDateTime))
.map(ReportDto::new)
.toList();
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ public Report(Activity activity, Volunteer volunteer, ReportDto reportDto){
verifyInvariants();
}

public void delete(){
volunteer.removeReport(this);
activity.removeReport(this);

deleteReportBeforeActivityEnd();
verifyInvariants();
}

public Integer getId() {
return id;
}
Expand Down Expand Up @@ -105,4 +113,10 @@ private void reportBeforeActivityEnd() {
throw new HEException(REPORT_AFTER_ACTIVTY_CLOSED);
}
}

private void deleteReportBeforeActivityEnd() {
if (LocalDateTime.now().isAfter(this.activity.getEndingDate())) {
throw new HEException(REPORT_AFTER_ACTIVTY_CLOSED);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,12 @@ public void deleteAssessment(Assessment assessment) {
public void addReport(Report report) {
this.reports.add(report);
}

public void removeReport(Report report) {
this.reports.remove(report);
}

public List<Report> getReports() {
return reports;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,21 +102,41 @@ class ValidateActivityWebServiceIT extends SpockTest {
activity.state == Activity.State.REPORTED
}

def "volunteer tries to validate activity"() {
def "volunteer validate activity"() {
given:
demoVolunteerLogin()

when: 'validate'
def response = webClient.put()
.uri('/activities/' + activityId + '/validate')
.headers(httpHeaders -> httpHeaders.putAll(headers))
.retrieve()
.bodyToMono(ActivityDto.class)
.block()

then: "check response"
response.state == Activity.State.APPROVED.name()
and: 'database'
activityRepository.findAll().size() == 1
def activity = activityRepository.findAll().get(0)
activity.state == Activity.State.APPROVED
}

def "volunteer validates activity with wrong id"() {
given:
demoVolunteerLogin()

when:
webClient.put()
.uri('/activities/' + activityId + '/validate')
.uri('/activities/' + '222' + '/validate')
.headers(httpHeaders -> httpHeaders.putAll(headers))
.retrieve()
.bodyToMono(ActivityDto.class)
.block()

then: "error is thrown"
then: "error"
def error = thrown(WebClientResponseException)
error.statusCode == HttpStatus.FORBIDDEN
error.statusCode == HttpStatus.BAD_REQUEST
activityRepository.findAll().size() == 1
def activity = activityRepository.findAll().get(0)
activity.state == Activity.State.REPORTED
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package pt.ulisboa.tecnico.socialsoftware.humanaethica.report.domain

import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.context.TestConfiguration
import pt.ulisboa.tecnico.socialsoftware.humanaethica.BeanConfiguration
import pt.ulisboa.tecnico.socialsoftware.humanaethica.SpockTest
import pt.ulisboa.tecnico.socialsoftware.humanaethica.exceptions.ErrorMessage
import pt.ulisboa.tecnico.socialsoftware.humanaethica.exceptions.HEException
import pt.ulisboa.tecnico.socialsoftware.humanaethica.activity.dto.ActivityDto
import pt.ulisboa.tecnico.socialsoftware.humanaethica.activity.domain.Activity
import pt.ulisboa.tecnico.socialsoftware.humanaethica.institution.domain.Institution
import pt.ulisboa.tecnico.socialsoftware.humanaethica.theme.domain.Theme
import pt.ulisboa.tecnico.socialsoftware.humanaethica.report.dto.ReportDto
import pt.ulisboa.tecnico.socialsoftware.humanaethica.auth.domain.AuthUser
import pt.ulisboa.tecnico.socialsoftware.humanaethica.user.domain.User
import pt.ulisboa.tecnico.socialsoftware.humanaethica.user.domain.Volunteer
import pt.ulisboa.tecnico.socialsoftware.humanaethica.utils.DateHandler
import spock.lang.Unroll

import java.time.LocalDateTime

@DataJpaTest
class DeleteReportMethodTest extends SpockTest {
Institution institution = Mock()
Theme theme = Mock()
def reportOne
def volunteer
def activity
def activity2
def reportTwo

def setup() {
theme.getState() >> Theme.State.APPROVED
institution.getActivities() >> []

given:"activity"
def themes = [theme]
def activityDtoOne
activityDtoOne = new ActivityDto()
activityDtoOne.name = ACTIVITY_NAME_1
activityDtoOne.region = ACTIVITY_REGION_1
activityDtoOne.participantsNumberLimit = 2
activityDtoOne.description = ACTIVITY_DESCRIPTION_1
activityDtoOne.startingDate = DateHandler.toISOString(IN_TWO_DAYS)
activityDtoOne.endingDate = DateHandler.toISOString(IN_THREE_DAYS)
activityDtoOne.applicationDeadline = DateHandler.toISOString(IN_ONE_DAY)
activity = new Activity(activityDtoOne, institution, themes)

and: "volunteer"
volunteer = createVolunteer(USER_1_NAME, USER_1_PASSWORD, USER_1_EMAIL, AuthUser.Type.NORMAL, User.State.APPROVED)

and: "report"
def reportDto = new ReportDto()
reportDto.justification = REPORT_JUSTIFICATION_1
reportOne = new Report(activity, volunteer, reportDto)
}

def "delete report"() {

when: "report is deleted"
reportOne.delete()

then: "checks if the report was deleted in the activtiy and volunteer"
volunteer.getReports().size() == 0
activity.getReports().size() == 0

}

def "try to delete report after activity deadline"() {
given:
def activityDtoTwo
def themes = [theme]
activityDtoTwo = new ActivityDto()
activityDtoTwo.name = ACTIVITY_NAME_1
activityDtoTwo.region = ACTIVITY_REGION_1
activityDtoTwo.participantsNumberLimit = 2
activityDtoTwo.description = ACTIVITY_DESCRIPTION_1
activityDtoTwo.startingDate = DateHandler.toISOString(IN_TWO_DAYS)
activityDtoTwo.endingDate = DateHandler.toISOString(IN_THREE_DAYS)
activityDtoTwo.applicationDeadline = DateHandler.toISOString(IN_ONE_DAY)
activity2 = new Activity(activityDtoTwo, institution, themes)

and: "report"
def reportDtoTwo = new ReportDto()
reportDtoTwo.justification = REPORT_JUSTIFICATION_1
reportTwo = new Report(activity2, volunteer, reportDtoTwo)
activity2.setEndingDate(ONE_DAY_AGO)

when:
reportTwo.delete()

then:
def error = thrown(HEException)
error.getErrorMessage() == ErrorMessage.REPORT_AFTER_ACTIVTY_CLOSED
}

@TestConfiguration
static class LocalBeanConfiguration extends BeanConfiguration {}
}
Loading

0 comments on commit 4a54648

Please sign in to comment.