diff --git a/backend/configuration.yml b/backend/configuration.yml index 35f86dc..f6f2ad8 100644 --- a/backend/configuration.yml +++ b/backend/configuration.yml @@ -3,7 +3,7 @@ database: driverClass: org.h2.Driver # the JDBC URL - url: jdbc:h2:./sampledatabase.db + url: jdbc:h2:file:./sampledatabase.db # any properties specific to your JDBC driver: properties: @@ -17,4 +17,4 @@ server: - type: console queueSize: 2048 -adminPassword: "testPassword" \ No newline at end of file +adminPassword: "testPassword" diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java b/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java index d96716b..b6d7864 100644 --- a/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java +++ b/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java @@ -11,7 +11,6 @@ import java.io.Serializable; import java.util.List; import java.util.Set; -@ToString(callSuper = true) @Entity @Table(name = "OBSERVATION") @Data @@ -27,13 +26,13 @@ public class Observation implements Serializable { @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; - @JsonProperty @ManyToOne @JoinColumn(name="site_id", nullable=false) + @EqualsAndHashCode.Exclude private Site site; - @JsonProperty @ManyToMany(mappedBy = "observations") + @EqualsAndHashCode.Exclude private Set tutors; @NonNull diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java b/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java index 60fd954..7f42e74 100644 --- a/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java +++ b/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java @@ -1,20 +1,21 @@ package uk.co.neviyn.Observations.core; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import lombok.*; import javax.persistence.*; import java.io.Serializable; import java.util.Set; -@EqualsAndHashCode -@ToString @Entity @Table(name = "SITE") @Data @NoArgsConstructor @Builder @AllArgsConstructor +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Site implements Serializable { @NonNull @@ -27,12 +28,11 @@ public class Site implements Serializable { @JsonProperty private String name; - @JsonProperty @OneToMany(mappedBy="site") + @EqualsAndHashCode.Exclude private Set tutors; - @JsonProperty @OneToMany(mappedBy = "site") + @EqualsAndHashCode.Exclude private Set observations; - } diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java b/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java index 423f1ef..e15c3bc 100644 --- a/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java +++ b/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java @@ -1,19 +1,21 @@ package uk.co.neviyn.Observations.core; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; import lombok.*; import javax.persistence.*; import java.io.Serializable; import java.util.Set; -@ToString @Entity @Table(name = "TUTOR") @Data @NoArgsConstructor @AllArgsConstructor @Builder +@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Tutor implements Serializable { @NonNull @@ -26,17 +28,17 @@ public class Tutor implements Serializable { @JsonProperty private String name; - @JsonProperty @ManyToOne @JoinColumn(name="site_id", nullable=false) + @EqualsAndHashCode.Exclude private Site site; - @JsonProperty @ManyToMany @JoinTable( name = "TUTOR_OBSERVATION", joinColumns = { @JoinColumn(name = "tutor_id")}, inverseJoinColumns = { @JoinColumn(name = "observation_id")} ) + @EqualsAndHashCode.Exclude private Set observations; } diff --git a/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java b/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java index 88a50bb..346a5a9 100644 --- a/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java +++ b/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java @@ -37,26 +37,21 @@ public class ObservationResource { @POST @UnitOfWork - public long add(@NotNull @Valid NewObservation newObservation){ + public long add(@NotNull @Valid NewObservation newObservation) { final DateTime submissionDate = LocalDate.now().toDateTimeAtStartOfDay(); Set tutors = new HashSet<>(); - for(long l: newObservation.getTutorIds()){ + for (long l : newObservation.getTutorIds()) { tutors.add(tutorDao.get(l)); } final Site site = siteDao.get(newObservation.getSiteId()); - Observation observation = Observation.builder() - .site(site) - .tutors(tutors) - .observed(newObservation.getObserved()) - .type(TrainingType.valueOf(newObservation.getType())) - .monitoring(newObservation.getMonitoring()) - .control(newObservation.getControl()) - .conservatism(newObservation.getConservatism()) - .teamwork(newObservation.getTeamwork()) - .knowledge(newObservation.getKnowledge()) - .observations(newObservation.getRawData()) - .date(submissionDate) - .build(); + Observation observation = Observation.builder().site(site).tutors(tutors).observed(newObservation.getObserved()) + .type(TrainingType.valueOf(newObservation.getType())).monitoring(newObservation.getMonitoring()) + .control(newObservation.getControl()).conservatism(newObservation.getConservatism()) + .teamwork(newObservation.getTeamwork()).knowledge(newObservation.getKnowledge()) + .observations(newObservation.getRawData()).date(submissionDate).build(); + for (Tutor t : tutors) { + t.getObservations().add(observation); + } observation = dao.persist(observation); log.info("Created observation with ID " + observation.getId() + " at " + DateTime.now().toString()); return observation.getId(); @@ -64,23 +59,27 @@ public class ObservationResource { @Path("/average/all") @GET - public List averageObservationScores(){ + @UnitOfWork + public List averageObservationScores() { return dao.averageStatsForAll(); } @Path("/average/all/chartjs") @GET - public AverageStatsChartJs averageStatsChartJs(){ + public AverageStatsChartJs averageStatsChartJs() { return new AverageStatsChartJs(averageObservationScores()); } @Path("/average/{id}") + @GET + @UnitOfWork public List averageObservationScoresForSite(@PathParam("id") long siteId) { Site site = siteDao.get(siteId); return dao.averageStatsForSite(site); } @Path("/average/{id}/chartjs") + @GET public AverageStatsChartJs averageObservationScoresForSiteChartJs(@PathParam("id") long siteId) { return new AverageStatsChartJs(averageObservationScoresForSite(siteId)); } diff --git a/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java b/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java index 526c1a0..682a67d 100644 --- a/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java +++ b/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java @@ -5,14 +5,12 @@ import io.dropwizard.hibernate.UnitOfWork; import lombok.RequiredArgsConstructor; import uk.co.neviyn.Observations.api.SelectOption; import uk.co.neviyn.Observations.core.Site; -import uk.co.neviyn.Observations.core.Tutor; import uk.co.neviyn.Observations.core.User; import uk.co.neviyn.Observations.dao.SiteDao; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; @RequiredArgsConstructor @@ -38,7 +36,7 @@ public class SiteResource { @Path("/{id}/tutors") @GET @UnitOfWork - public Set getSiteTutors(@PathParam("id") long id){ - return dao.get(id).getTutors(); + public List> getSiteTutors(@PathParam("id") long id) { + return dao.get(id).getTutors().stream().map(x -> new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList()); } } diff --git a/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java b/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java index 93f0cd8..2f5f4ff 100644 --- a/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java +++ b/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java @@ -7,6 +7,7 @@ import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.RequiredArgsConstructor; +import uk.co.neviyn.Observations.core.Observation; import uk.co.neviyn.Observations.core.Site; import uk.co.neviyn.Observations.core.Tutor; import uk.co.neviyn.Observations.core.User; @@ -17,6 +18,7 @@ import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.List; +import java.util.Set; @RequiredArgsConstructor @Produces(MediaType.APPLICATION_JSON) @@ -31,6 +33,7 @@ public class TutorResource { public Tutor add(@Auth User user, NewTutor newTutor) { final Site site = siteDao.get(newTutor.siteId); final Tutor tutor = Tutor.builder().name(newTutor.name).site(site).build(); + site.getTutors().add(tutor); return dao.persist(tutor); } @@ -44,6 +47,13 @@ public class TutorResource { throw new WebApplicationException("No tutors found!", Response.Status.NOT_FOUND); } + @Path("/{id}/observations") + @GET + @UnitOfWork + public Set getSiteTutors(@PathParam("id") long id) { + return dao.get(id).getObservations(); + } + @AllArgsConstructor @NoArgsConstructor static class NewTutor { diff --git a/backend/src/test/java/uk/co/neviyn/Observations/resources/ObservationResourceTest.java b/backend/src/test/java/uk/co/neviyn/Observations/resources/ObservationResourceTest.java index 341c2b6..708df0e 100644 --- a/backend/src/test/java/uk/co/neviyn/Observations/resources/ObservationResourceTest.java +++ b/backend/src/test/java/uk/co/neviyn/Observations/resources/ObservationResourceTest.java @@ -15,6 +15,7 @@ import uk.co.neviyn.Observations.dao.TutorDao; import javax.ws.rs.client.Entity; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import static org.mockito.Mockito.*; @@ -40,7 +41,7 @@ public class ObservationResourceTest { @Test public void add() { final Site testSite = Site.builder().id(1).name("Test Site").build(); - final List tutors = Arrays.asList(Tutor.builder().id(1).name("Mr A").build(), Tutor.builder().id(2).name("Mr B").build()); + final List tutors = Arrays.asList(Tutor.builder().id(1).name("Mr A").observations(new HashSet<>()).build(), Tutor.builder().id(2).name("Mr B").observations(new HashSet<>()).build()); when(siteDao.get(1)).thenReturn(testSite); when(tutorDao.get(1)).thenReturn(tutors.get(0)); when(tutorDao.get(2)).thenReturn(tutors.get(1)); diff --git a/backend/src/test/java/uk/co/neviyn/Observations/resources/SiteResourceTest.java b/backend/src/test/java/uk/co/neviyn/Observations/resources/SiteResourceTest.java index 3477708..bb07552 100644 --- a/backend/src/test/java/uk/co/neviyn/Observations/resources/SiteResourceTest.java +++ b/backend/src/test/java/uk/co/neviyn/Observations/resources/SiteResourceTest.java @@ -50,7 +50,7 @@ public class SiteResourceTest { @Test public void add() { resources.target("/site").request().header("Authorization", httpAuth).post(Entity.json("New Site")); - verify(dao, times(1)).persist(Site.builder().name("New Site").build()); + verify(dao, times(1)).persist(Site.builder().name("New Site").tutors(new HashSet<>()).build()); } @Test @@ -66,9 +66,9 @@ public class SiteResourceTest { public void getSiteTutors() { Set tutors = new HashSet<>(Arrays.asList(Tutor.builder().id(1).name("Test 1").build(), Tutor.builder().id(2).name("Test 2").build())); when(dao.get(1)).thenReturn(Site.builder().id(1).name("Site").tutors(tutors).build()); - Set result = resources.target("/site/1/tutors").request().get(new GenericType>() { + List> result = resources.target("/site/1/tutors").request().get(new GenericType>>() { }); assertNotNull(result); - assertEquals(tutors, result); + assertEquals(2, result.size()); } } \ No newline at end of file diff --git a/backend/src/test/java/uk/co/neviyn/Observations/resources/TutorResourceTest.java b/backend/src/test/java/uk/co/neviyn/Observations/resources/TutorResourceTest.java index a8ee81c..bb8a48b 100644 --- a/backend/src/test/java/uk/co/neviyn/Observations/resources/TutorResourceTest.java +++ b/backend/src/test/java/uk/co/neviyn/Observations/resources/TutorResourceTest.java @@ -17,6 +17,7 @@ import uk.co.neviyn.Observations.dao.TutorDao; import javax.ws.rs.client.Entity; import javax.ws.rs.core.GenericType; import java.util.Arrays; +import java.util.HashSet; import java.util.List; import static org.junit.Assert.assertTrue; @@ -48,7 +49,7 @@ public class TutorResourceTest { @Test public void add() { - final Site testSite = Site.builder().id(1).name("Test Site").build(); + final Site testSite = Site.builder().id(1).name("Test Site").tutors(new HashSet<>()).build(); when(siteDao.get(1)).thenReturn(testSite); resources.target("/tutor").request().header("Authorization", httpAuth).post(Entity.json(new TutorResource.NewTutor(1, "Mr X"))); verify(dao, times(1)).persist(Tutor.builder().name("Mr X").site(testSite).build());