Welcome to Spring town.
This commit is contained in:
parent
1ef05d3822
commit
2f115e2837
2
.gitignore
vendored
2
.gitignore
vendored
@ -257,7 +257,7 @@ local.properties
|
||||
|
||||
# End of https://www.gitignore.io/api/java,node,intellij+all,visualstudiocode,eclipse
|
||||
|
||||
backend/src/main/resources/assets
|
||||
backend/src/main/resources/static
|
||||
frontend/node
|
||||
!maven-wrapper.jar
|
||||
dependency-reduced-pom.xml
|
||||
|
@ -1,20 +0,0 @@
|
||||
database:
|
||||
# the name of your JDBC driver
|
||||
driverClass: org.h2.Driver
|
||||
|
||||
# the JDBC URL
|
||||
url: jdbc:h2:file:./sampledatabase.db
|
||||
|
||||
# any properties specific to your JDBC driver:
|
||||
properties:
|
||||
foreign_keys: true
|
||||
hibernate.hbm2ddl.auto: update
|
||||
|
||||
server:
|
||||
rootPath: /api/
|
||||
requestLog:
|
||||
appenders:
|
||||
- type: console
|
||||
queueSize: 2048
|
||||
|
||||
adminPassword: "testPassword"
|
253
backend/pom.xml
253
backend/pom.xml
@ -1,198 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>backend</artifactId>
|
||||
<groupId>uk.co.neviyn</groupId>
|
||||
<artifactId>observationdatabase</artifactId>
|
||||
<version>PRE-ALPHA</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>observationdatabase</name>
|
||||
<description>Training observation database</description>
|
||||
|
||||
<parent>
|
||||
<groupId>uk.co.neviyn</groupId>
|
||||
<artifactId>Observations</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.5.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<dropwizard.version>1.3.5</dropwizard.version>
|
||||
<kotlin.version>1.2.71</kotlin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.2</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard</groupId>
|
||||
<artifactId>dropwizard-core</artifactId>
|
||||
<version>${dropwizard.version}</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard</groupId>
|
||||
<artifactId>dropwizard-hibernate</artifactId>
|
||||
<version>${dropwizard.version}</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard</groupId>
|
||||
<artifactId>dropwizard-assets</artifactId>
|
||||
<version>${dropwizard.version}</version>
|
||||
<groupId>com.fasterxml.jackson.module</groupId>
|
||||
<artifactId>jackson-module-kotlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard</groupId>
|
||||
<artifactId>dropwizard-testing</artifactId>
|
||||
<version>${dropwizard.version}</version>
|
||||
<scope>test</scope>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.dropwizard</groupId>
|
||||
<artifactId>dropwizard-auth</artifactId>
|
||||
<version>${dropwizard.version}</version>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-reflect</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>2.22.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.8</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.197</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy Vue.js frontend content</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>src/main/resources/assets</outputDirectory>
|
||||
<overwrite>true</overwrite>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${project.parent.basedir}/frontend/target/dist</directory>
|
||||
<excludes>
|
||||
<exclude>**/*.map</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>src/main/resources/assets</directory>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
</filesets>
|
||||
<args>
|
||||
<arg>-Xjsr305=strict</arg>
|
||||
</args>
|
||||
<compilerPlugins>
|
||||
<plugin>spring</plugin>
|
||||
<plugin>jpa</plugin>
|
||||
</compilerPlugins>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-allopen</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-noarg</artifactId>
|
||||
<version>${kotlin.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>uk.co.neviyn.observations.ObservationsApplication</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<arguments>
|
||||
<argument>server</argument>
|
||||
<argument>configuration.yml</argument>
|
||||
</arguments>
|
||||
<mainClass>uk.co.neviyn.observations.ObservationsApplication</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.0</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy Vue.js frontend content</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>src/main/resources/static</outputDirectory>
|
||||
<overwrite>true</overwrite>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>../frontend/target/dist</directory>
|
||||
<excludes>
|
||||
<exclude>**/*.map</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>src/main/resources/static</directory>
|
||||
<followSymlinks>false</followSymlinks>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
@ -1,65 +0,0 @@
|
||||
package uk.co.neviyn.observations;
|
||||
|
||||
import io.dropwizard.Application;
|
||||
import io.dropwizard.assets.AssetsBundle;
|
||||
import io.dropwizard.auth.AuthDynamicFeature;
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
|
||||
import io.dropwizard.db.DataSourceFactory;
|
||||
import io.dropwizard.hibernate.HibernateBundle;
|
||||
import io.dropwizard.jersey.setup.JerseyEnvironment;
|
||||
import io.dropwizard.setup.Bootstrap;
|
||||
import io.dropwizard.setup.Environment;
|
||||
import uk.co.neviyn.observations.auth.SimpleAuthenticator;
|
||||
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;
|
||||
import uk.co.neviyn.observations.dao.ObservationDao;
|
||||
import uk.co.neviyn.observations.dao.SiteDao;
|
||||
import uk.co.neviyn.observations.dao.TutorDao;
|
||||
import uk.co.neviyn.observations.resources.ObservationResource;
|
||||
import uk.co.neviyn.observations.resources.SiteResource;
|
||||
import uk.co.neviyn.observations.resources.TutorResource;
|
||||
|
||||
public class ObservationsApplication extends Application<ObservationsConfiguration> {
|
||||
|
||||
private final HibernateBundle<ObservationsConfiguration> hibernate =
|
||||
new HibernateBundle<ObservationsConfiguration>(Observation.class, Tutor.class, Site.class) {
|
||||
@Override
|
||||
public DataSourceFactory getDataSourceFactory(ObservationsConfiguration configuration) {
|
||||
return configuration.getDataSourceFactory();
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ObservationsApplication().run(args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Bootstrap<ObservationsConfiguration> bootstrap) {
|
||||
super.initialize(bootstrap);
|
||||
bootstrap.addBundle(hibernate);
|
||||
bootstrap.addBundle(new AssetsBundle("/assets/", "/", "/index.html"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ObservationsConfiguration observationsConfiguration, Environment environment) {
|
||||
final JerseyEnvironment jersey = environment.jersey();
|
||||
jersey.register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder<User>()
|
||||
.setAuthenticator(new SimpleAuthenticator(
|
||||
observationsConfiguration.getAdminPassword())
|
||||
).setRealm("SECURITY").buildAuthFilter()));
|
||||
jersey.register(new AuthValueFactoryProvider.Binder<>(User.class));
|
||||
TutorDao tutorDao = new TutorDao(hibernate.getSessionFactory());
|
||||
SiteDao siteDao = new SiteDao(hibernate.getSessionFactory());
|
||||
ObservationDao observationDao = new ObservationDao(hibernate.getSessionFactory());
|
||||
final TutorResource tutorResource = new TutorResource(tutorDao, siteDao);
|
||||
jersey.register(tutorResource);
|
||||
final ObservationResource observationResource =
|
||||
new ObservationResource(observationDao, tutorDao, siteDao);
|
||||
jersey.register(observationResource);
|
||||
final SiteResource siteResource = new SiteResource(siteDao);
|
||||
jersey.register(siteResource);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package uk.co.neviyn.observations;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.dropwizard.Configuration;
|
||||
import io.dropwizard.db.DataSourceFactory;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
public class ObservationsConfiguration extends Configuration {
|
||||
@Valid
|
||||
@NotNull
|
||||
private DataSourceFactory database = new DataSourceFactory();
|
||||
|
||||
@Valid
|
||||
@NotNull
|
||||
private String adminPassword;
|
||||
|
||||
@JsonProperty("database")
|
||||
public void setDataSourceFactory(DataSourceFactory factory) {
|
||||
this.database = factory;
|
||||
}
|
||||
|
||||
@JsonProperty("database")
|
||||
public DataSourceFactory getDataSourceFactory() {
|
||||
return database;
|
||||
}
|
||||
|
||||
@JsonProperty("adminPassword")
|
||||
public String getAdminPassword() {
|
||||
return adminPassword;
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package uk.co.neviyn.observations.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class AverageStats {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private double monitoring;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private double control;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private double conservatism;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private double teamwork;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private double knowledge;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private DateTime date;
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package uk.co.neviyn.observations.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
|
||||
/**
|
||||
* AverageStats in a format easily readable by Chart.js
|
||||
*/
|
||||
@Data
|
||||
public class AverageStatsChartJs {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private List<String> labels = new ArrayList<>();
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private List<Dataset> datasets = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* A list of AverageStats converted to a format compatible with Chart.js.
|
||||
* @param inputData List of average stats.
|
||||
*/
|
||||
public AverageStatsChartJs(List<AverageStats> inputData) {
|
||||
List<Double> monitoring = new ArrayList<>();
|
||||
List<Double> control = new ArrayList<>();
|
||||
List<Double> conservatism = new ArrayList<>();
|
||||
List<Double> teamwork = new ArrayList<>();
|
||||
List<Double> knowledge = new ArrayList<>();
|
||||
for (AverageStats averageStats: inputData) {
|
||||
labels.add(averageStats.getDate().toString("yyyy-MM-dd"));
|
||||
monitoring.add(averageStats.getMonitoring());
|
||||
control.add(averageStats.getControl());
|
||||
conservatism.add(averageStats.getConservatism());
|
||||
teamwork.add(averageStats.getTeamwork());
|
||||
knowledge.add(averageStats.getKnowledge());
|
||||
}
|
||||
datasets.add(new Dataset("Monitoring", "#F90", monitoring));
|
||||
datasets.add(new Dataset("Control", "#3F0", control));
|
||||
datasets.add(new Dataset("Conservatism", "#33F", conservatism));
|
||||
datasets.add(new Dataset("Teamwork", "#FF0", teamwork));
|
||||
datasets.add(new Dataset("Knowledge", "#000", knowledge));
|
||||
}
|
||||
|
||||
class Dataset {
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private final String label;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private final String backgroundColor;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private final String borderColor;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private final List<Double> data;
|
||||
|
||||
@JsonProperty
|
||||
private final boolean fill = false;
|
||||
|
||||
Dataset(String label, String color, List<Double> data) {
|
||||
this.label = label;
|
||||
this.backgroundColor = color;
|
||||
this.borderColor = color;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package uk.co.neviyn.observations.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import uk.co.neviyn.observations.core.ObservationEntry;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor(access = AccessLevel.PROTECTED)
|
||||
public class NewObservation {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private long siteId;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private List<Long> tutorIds;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String observed;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String type;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String whom;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float monitoring;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float control;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float conservatism;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float teamwork;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float knowledge;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private List<ObservationEntry> rawData;
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package uk.co.neviyn.observations.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SelectOption<T> {
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String text;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private T value;
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package uk.co.neviyn.observations.auth;
|
||||
|
||||
import io.dropwizard.auth.Authenticator;
|
||||
import io.dropwizard.auth.basic.BasicCredentials;
|
||||
import java.util.Optional;
|
||||
import lombok.AllArgsConstructor;
|
||||
import uk.co.neviyn.observations.core.User;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class SimpleAuthenticator implements Authenticator<BasicCredentials, User> {
|
||||
|
||||
private final String adminPassword;
|
||||
|
||||
@Override
|
||||
public Optional<User> authenticate(BasicCredentials credentials) {
|
||||
if (adminPassword.equals(credentials.getPassword())) {
|
||||
return Optional.of(new User(credentials.getUsername()));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
@Entity
|
||||
@Table(name = "OBSERVATION")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Observation implements Serializable {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "site_id", nullable = false)
|
||||
@JsonIgnore
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Site site;
|
||||
|
||||
@ManyToMany(mappedBy = "observations")
|
||||
@JsonIgnore
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Set<Tutor> tutors;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String observed;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String whom;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private TrainingType type;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float monitoring;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float control;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float conservatism;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float teamwork;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private float knowledge;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
@ElementCollection
|
||||
private List<ObservationEntry> observations;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private DateTime date;
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Embeddable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Embeddable
|
||||
public class ObservationEntry implements Serializable {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String type;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private int rating;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String strengths;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String improvements;
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Entity
|
||||
@Table(name = "SITE")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class Site implements Serializable {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@OneToMany(mappedBy = "site")
|
||||
@JsonIgnore
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Set<Tutor> tutors;
|
||||
|
||||
@OneToMany(mappedBy = "site")
|
||||
@JsonIgnore
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Set<Observation> observations;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
public enum TrainingType {
|
||||
INITIAL, CONTINUING
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToMany;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Entity
|
||||
@Table(name = "TUTOR")
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Tutor implements Serializable {
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "site_id", nullable = false)
|
||||
@JsonIgnore
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Site site;
|
||||
|
||||
@ManyToMany
|
||||
@JsonIgnore
|
||||
@JoinTable(
|
||||
name = "TUTOR_OBSERVATION",
|
||||
joinColumns = { @JoinColumn(name = "tutor_id")},
|
||||
inverseJoinColumns = { @JoinColumn(name = "observation_id")}
|
||||
)
|
||||
@EqualsAndHashCode.Exclude
|
||||
private Set<Observation> observations;
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
import java.security.Principal;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class User implements Principal {
|
||||
|
||||
private String name;
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import io.dropwizard.hibernate.AbstractDAO;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.query.Query;
|
||||
import org.joda.time.DateTime;
|
||||
import uk.co.neviyn.observations.api.AverageStats;
|
||||
import uk.co.neviyn.observations.core.Observation;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
import uk.co.neviyn.observations.core.Tutor;
|
||||
|
||||
public class ObservationDao extends AbstractDAO<Observation> {
|
||||
public ObservationDao(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public Observation get(long id) {
|
||||
return super.get(id);
|
||||
}
|
||||
|
||||
public Observation persist(Observation observation) {
|
||||
return super.persist(observation);
|
||||
}
|
||||
|
||||
public List<Observation> listAll() {
|
||||
return currentSession().createQuery("from Observation", Observation.class).list();
|
||||
}
|
||||
|
||||
public List<Observation> filteredList(Site site, Tutor tutor, DateTime startDate, DateTime endDate, String whom) {
|
||||
final CriteriaBuilder builder = currentSession().getCriteriaBuilder();
|
||||
CriteriaQuery<Observation> criteriaQuery = builder.createQuery(Observation.class);
|
||||
Root<Observation> root = criteriaQuery.from(Observation.class);
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (site != null) {
|
||||
predicates.add(builder.equal(root.get("site"), site));
|
||||
}
|
||||
if (tutor != null) {
|
||||
predicates.add(builder.equal(root.join("tutors"), tutor));
|
||||
}
|
||||
if (startDate != null) {
|
||||
predicates.add(builder.greaterThanOrEqualTo(root.get("date"), startDate));
|
||||
}
|
||||
if (endDate != null) {
|
||||
predicates.add(builder.lessThanOrEqualTo(root.get("date"), endDate));
|
||||
}
|
||||
if (whom != null) {
|
||||
predicates.add(builder.equal(root.get("whom"), whom));
|
||||
}
|
||||
if (!predicates.isEmpty()) {
|
||||
criteriaQuery.having(predicates.toArray(new Predicate[0]));
|
||||
}
|
||||
Query<Observation> query = currentSession().createQuery(criteriaQuery);
|
||||
System.out.println(query.getQueryString());
|
||||
return query.getResultList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the average observation stats with data constraints.
|
||||
*
|
||||
* @param site Restrict to a site.
|
||||
* @param tutor Restrict to a tutor.
|
||||
* @param startDate Restrict to after a certain date.
|
||||
* @param endDate Restrict to before a certain date.
|
||||
* @param whom Restrict to a particular person/group who was observed.
|
||||
* @return Average observation scores per day.
|
||||
*/
|
||||
public List<AverageStats> averageStats(Site site, Tutor tutor, DateTime startDate, DateTime endDate, String whom) {
|
||||
CriteriaBuilder builder = currentSession().getCriteriaBuilder();
|
||||
CriteriaQuery<AverageStats> criteriaQuery = builder.createQuery(AverageStats.class);
|
||||
Root<Observation> root = criteriaQuery.from(Observation.class);
|
||||
criteriaQuery.multiselect(builder.avg(root.get("monitoring")), builder.avg(root.get("control")),
|
||||
builder.avg(root.get("conservatism")), builder.avg(root.get("teamwork")), builder.avg(root.get("knowledge")),
|
||||
root.get("date"));
|
||||
criteriaQuery.groupBy(root.get("date"));
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (site != null) {
|
||||
predicates.add(builder.equal(root.get("site"), site));
|
||||
}
|
||||
if (tutor != null) {
|
||||
predicates.add(builder.equal(root.join("tutors"), tutor));
|
||||
}
|
||||
if (startDate != null) {
|
||||
predicates.add(builder.greaterThanOrEqualTo(root.get("date"), startDate));
|
||||
}
|
||||
if (endDate != null) {
|
||||
predicates.add(builder.lessThanOrEqualTo(root.get("date"), endDate));
|
||||
}
|
||||
if (whom != null) {
|
||||
predicates.add(builder.equal(root.get("whom"), whom));
|
||||
}
|
||||
if (!predicates.isEmpty()) {
|
||||
criteriaQuery.having(predicates.toArray(new Predicate[0]));
|
||||
}
|
||||
Query<AverageStats> query = currentSession().createQuery(criteriaQuery);
|
||||
System.out.println(query.getQueryString());
|
||||
return query.getResultList();
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import io.dropwizard.hibernate.AbstractDAO;
|
||||
import java.util.List;
|
||||
import org.hibernate.SessionFactory;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
|
||||
public class SiteDao extends AbstractDAO<Site> {
|
||||
public SiteDao(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public List<Site> listAll() {
|
||||
return currentSession().createQuery("from Site", Site.class).list();
|
||||
}
|
||||
|
||||
public Site get(long id) {
|
||||
return super.get(id);
|
||||
}
|
||||
|
||||
public Site persist(Site site) {
|
||||
return super.persist(site);
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import io.dropwizard.hibernate.AbstractDAO;
|
||||
import java.util.List;
|
||||
import org.hibernate.SessionFactory;
|
||||
import uk.co.neviyn.observations.core.Tutor;
|
||||
|
||||
public class TutorDao extends AbstractDAO<Tutor> {
|
||||
public TutorDao(SessionFactory sessionFactory) {
|
||||
super(sessionFactory);
|
||||
}
|
||||
|
||||
public Tutor get(long id) {
|
||||
return super.get(id);
|
||||
}
|
||||
|
||||
public List<Tutor> listAll() {
|
||||
return currentSession().createQuery("from Tutor", Tutor.class).list();
|
||||
}
|
||||
|
||||
public Tutor persist(Tutor tutor) {
|
||||
return super.persist(tutor);
|
||||
}
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package uk.co.neviyn.observations.resources;
|
||||
|
||||
import io.dropwizard.hibernate.UnitOfWork;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.LocalDate;
|
||||
import uk.co.neviyn.observations.api.AverageStatsChartJs;
|
||||
import uk.co.neviyn.observations.api.NewObservation;
|
||||
import uk.co.neviyn.observations.core.Observation;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
import uk.co.neviyn.observations.core.TrainingType;
|
||||
import uk.co.neviyn.observations.core.Tutor;
|
||||
import uk.co.neviyn.observations.dao.ObservationDao;
|
||||
import uk.co.neviyn.observations.dao.SiteDao;
|
||||
import uk.co.neviyn.observations.dao.TutorDao;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/observation")
|
||||
@Slf4j
|
||||
public class ObservationResource {
|
||||
|
||||
private final ObservationDao dao;
|
||||
private final TutorDao tutorDao;
|
||||
private final SiteDao siteDao;
|
||||
|
||||
/**
|
||||
* Create a new Observation.
|
||||
*
|
||||
* @param newObservation New observation data.
|
||||
* @return ID of newly created observation.
|
||||
*/
|
||||
@POST
|
||||
@UnitOfWork
|
||||
public long add(@NotNull NewObservation newObservation) {
|
||||
log.info(newObservation.toString());
|
||||
final DateTime submissionDate = LocalDate.now().toDateTimeAtStartOfDay();
|
||||
Set<Tutor> tutors = new HashSet<>();
|
||||
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).whom(newObservation.getWhom()).build();
|
||||
for (Tutor t : tutors) {
|
||||
t.getObservations().add(observation);
|
||||
}
|
||||
observation = dao.persist(observation);
|
||||
log.info("Created observation with ID " + observation.getId());
|
||||
return observation.getId();
|
||||
}
|
||||
|
||||
@GET
|
||||
@UnitOfWork
|
||||
public List<Observation> observations(@QueryParam("site") Integer siteId, @QueryParam("tutor") Integer tutorId,
|
||||
@QueryParam("startDate") String startDate, @QueryParam("endDate") String endDate,
|
||||
@QueryParam("whom") String whom) {
|
||||
Site site = null;
|
||||
Tutor tutor = null;
|
||||
DateTime start = null;
|
||||
DateTime end = null;
|
||||
try {
|
||||
site = siteDao.get(siteId);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get site with ID " + siteId);
|
||||
}
|
||||
try {
|
||||
tutor = tutorDao.get(tutorId);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get tutor with ID " + tutorId);
|
||||
}
|
||||
try {
|
||||
start = DateTime.parse(startDate);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get a valid date from " + startDate);
|
||||
}
|
||||
try {
|
||||
end = DateTime.parse(endDate);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get a valid date from " + endDate);
|
||||
}
|
||||
return dao.filteredList(site, tutor, start, end, whom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Chart.js compatible llist of average observation scores grouped by day.
|
||||
*
|
||||
* @param siteId Only observations for site.
|
||||
* @param tutorId Only observations for tutor.
|
||||
* @param startDate Only observations after startDate.
|
||||
* @param endDate Only observations before endDate.
|
||||
* @param whom Only observations of whom.
|
||||
* @return Chart.js stats object.
|
||||
*/
|
||||
@Path("/average")
|
||||
@GET
|
||||
@UnitOfWork
|
||||
public AverageStatsChartJs averageObservationScores(@QueryParam("site") Integer siteId,
|
||||
@QueryParam("tutor") Integer tutorId, @QueryParam("startDate") String startDate,
|
||||
@QueryParam("endDate") String endDate, @QueryParam("whom") String whom) {
|
||||
Site site = null;
|
||||
Tutor tutor = null;
|
||||
DateTime start = null;
|
||||
DateTime end = null;
|
||||
try {
|
||||
site = siteDao.get(siteId);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get site with ID " + siteId);
|
||||
}
|
||||
try {
|
||||
tutor = tutorDao.get(tutorId);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get tutor with ID " + tutorId);
|
||||
}
|
||||
try {
|
||||
start = DateTime.parse(startDate);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get a valid date from " + startDate);
|
||||
}
|
||||
try {
|
||||
end = DateTime.parse(endDate);
|
||||
} catch (Exception e) {
|
||||
log.warn("Couldn't get a valid date from " + endDate);
|
||||
}
|
||||
return new AverageStatsChartJs(dao.averageStats(site, tutor, start, end, whom));
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package uk.co.neviyn.observations.resources;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
import io.dropwizard.hibernate.UnitOfWork;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import uk.co.neviyn.observations.api.SelectOption;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
import uk.co.neviyn.observations.core.User;
|
||||
import uk.co.neviyn.observations.dao.SiteDao;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/site")
|
||||
@Slf4j
|
||||
public class SiteResource {
|
||||
|
||||
private final SiteDao dao;
|
||||
|
||||
/**
|
||||
* Add a new Site.
|
||||
* @param user Authorization account.
|
||||
* @param name Name of Site to add.
|
||||
* @return Newly created site object.
|
||||
*/
|
||||
@POST
|
||||
@UnitOfWork
|
||||
public Site add(@Auth User user, String name) {
|
||||
Site site = dao.persist(Site.builder().name(name).build());
|
||||
log.info("Created site '" + site.getName() + "' with id " + site.getId());
|
||||
return site;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all known Sites.
|
||||
* @return List of all Sites.
|
||||
*/
|
||||
@Path("/all")
|
||||
@GET
|
||||
@UnitOfWork
|
||||
public List<SelectOption<Long>> allSites() {
|
||||
return dao.listAll().stream().map(x ->
|
||||
new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A List of all the Tutors registered to Site.
|
||||
* @param id ID of site.
|
||||
* @return List of Tutors, compatible with a HTML select object.
|
||||
*/
|
||||
@Path("/{id}/tutors")
|
||||
@GET
|
||||
@UnitOfWork
|
||||
public List<SelectOption<Long>> getSiteTutors(@PathParam("id") long id) {
|
||||
return dao.get(id).getTutors().stream().map(x ->
|
||||
new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList()
|
||||
);
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package uk.co.neviyn.observations.resources;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.dropwizard.auth.Auth;
|
||||
import io.dropwizard.hibernate.UnitOfWork;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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;
|
||||
import uk.co.neviyn.observations.dao.SiteDao;
|
||||
import uk.co.neviyn.observations.dao.TutorDao;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/tutor")
|
||||
@Slf4j
|
||||
public class TutorResource {
|
||||
|
||||
private final TutorDao dao;
|
||||
private final SiteDao siteDao;
|
||||
|
||||
/**
|
||||
* Create a new Tutor.
|
||||
* @param user Authorization account.
|
||||
* @param newTutor Details of new Tutor.
|
||||
* @return Newly created Tutor object.
|
||||
*/
|
||||
@POST
|
||||
@UnitOfWork
|
||||
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);
|
||||
log.info("Created tutor '" + tutor.getName() + "' with id "
|
||||
+ tutor.getId() + " at site " + site.getId());
|
||||
return dao.persist(tutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a List of all Tutors.
|
||||
* @return List of all Tutors.
|
||||
*/
|
||||
@Path("/all")
|
||||
@GET
|
||||
@UnitOfWork
|
||||
public List<Tutor> allTutors() {
|
||||
List<Tutor> tutors = dao.listAll();
|
||||
if (tutors != null && !tutors.isEmpty()) {
|
||||
return tutors;
|
||||
}
|
||||
throw new WebApplicationException("No tutors found!", Response.Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of all observations by a tutor.
|
||||
* @param id Tutor ID.
|
||||
* @return List of tutors' observations.
|
||||
*/
|
||||
@Path("/{id}/observations")
|
||||
@GET
|
||||
@UnitOfWork
|
||||
public Set<Observation> getTutorObservation(@PathParam("id") long id) {
|
||||
return dao.get(id).getObservations();
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
static class NewTutor {
|
||||
@JsonProperty
|
||||
long siteId;
|
||||
@NonNull
|
||||
@JsonProperty
|
||||
String name;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.joda.time.LocalDate
|
||||
|
||||
data class NameValue(
|
||||
val text: String,
|
||||
val value: Long
|
||||
)
|
||||
|
||||
data class NewSite(
|
||||
val name: String
|
||||
)
|
||||
|
||||
data class NewTutor(
|
||||
val name: String,
|
||||
val siteId: Long
|
||||
)
|
||||
|
||||
data class SimpleObservation(
|
||||
val date: LocalDate,
|
||||
val type: TrainingType,
|
||||
val observed: String,
|
||||
val whom: String,
|
||||
val entries: List<Entry>
|
||||
){
|
||||
constructor(observation: Observation) : this(observation.date, observation.type,
|
||||
observation.observed, observation.whom, observation.entries)
|
||||
}
|
||||
|
||||
data class NewObservation(
|
||||
val site: Long,
|
||||
val type: TrainingType,
|
||||
val observed: String,
|
||||
val whom: String,
|
||||
val entries: List<Entry>,
|
||||
val tutors: List<Long>
|
||||
)
|
||||
|
||||
data class ObservationsRequest(
|
||||
val site: Long?,
|
||||
val tutor: Long?,
|
||||
val whom: String?,
|
||||
val startDate: LocalDate,
|
||||
val endDate: LocalDate
|
||||
)
|
||||
|
||||
data class ChartData(
|
||||
val labels: List<String>,
|
||||
val datasets: List<ChartDataset>
|
||||
)
|
||||
|
||||
data class ChartDataset(
|
||||
val label: String,
|
||||
val backgroundColor: String,
|
||||
val borderColor: String,
|
||||
val data: List<Double>
|
||||
){
|
||||
constructor(label: String, color: String, data: List<Double>): this(label, color, color, data)
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.joda.time.LocalDate
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import javax.validation.Valid
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
class Controller {
|
||||
|
||||
@Autowired
|
||||
lateinit var siteRepository: SiteRepository
|
||||
@Autowired
|
||||
lateinit var tutorRepository: TutorRepository
|
||||
@Autowired
|
||||
lateinit var observationRepository: ObservationRepository
|
||||
|
||||
@GetMapping("/site")
|
||||
fun getAllSites(): List<NameValue> = siteRepository.findAll().map { NameValue(it.name, it.id) }
|
||||
|
||||
|
||||
@PostMapping("/site")
|
||||
fun addSite(@Valid @RequestBody newSite: NewSite): NameValue {
|
||||
val site = siteRepository.save(Site(name = newSite.name))
|
||||
return NameValue(site.name, site.id)
|
||||
}
|
||||
|
||||
@GetMapping("/site/{id}/tutors")
|
||||
fun getTutorsForSite(@PathVariable(value = "id") id: Long): List<NameValue> =
|
||||
siteRepository.findById(id).map { site ->
|
||||
site.tutors.map { NameValue(it.name, it.id) }
|
||||
}.get()
|
||||
|
||||
@GetMapping
|
||||
fun getAllTutors(): List<NameValue> = tutorRepository.findAll().map { NameValue(it.name, it.id) }
|
||||
|
||||
@PostMapping("/tutor")
|
||||
fun addTutor(@Valid @RequestBody newTutor: NewTutor): NameValue? {
|
||||
var nameValue: NameValue? = null
|
||||
siteRepository.findById(newTutor.siteId).ifPresent {
|
||||
val tutor = tutorRepository.save(Tutor(name = newTutor.name, site = it))
|
||||
it.tutors.add(tutor)
|
||||
siteRepository.save(it)
|
||||
nameValue = NameValue(tutor.name, tutor.id)
|
||||
}
|
||||
return nameValue
|
||||
}
|
||||
|
||||
@GetMapping("/tutor/{id}/observations")
|
||||
fun getObservationsForTutor(@PathVariable(value = "id") id: Long): List<SimpleObservation> =
|
||||
tutorRepository.findById(id).map { tutor ->
|
||||
tutor.observations.map { SimpleObservation(it) }
|
||||
}.get()
|
||||
|
||||
@PostMapping("/observation")
|
||||
fun addObservation(@Valid @RequestBody newObservation: NewObservation): Long {
|
||||
val site = siteRepository.findById(newObservation.site).get()
|
||||
val tutors = tutorRepository.findAllById(newObservation.tutors).toSet()
|
||||
val overallScores = newObservation.entries.asSequence().groupBy { it.type }
|
||||
.map { entry -> entry.key to entry.value.asSequence().mapNotNull { it.rating }.average() }
|
||||
.map { it.first to if(it.second > 0) it.second else null }.toList()
|
||||
.toMap()
|
||||
var observation = Observation(
|
||||
site = site,
|
||||
date = LocalDate.now(),
|
||||
type = newObservation.type,
|
||||
observed = newObservation.observed,
|
||||
whom = newObservation.whom,
|
||||
monitoring = overallScores[RatingCategory.MONITORING],
|
||||
conservatism = overallScores[RatingCategory.CONSERVATISM],
|
||||
control = overallScores[RatingCategory.CONTROL],
|
||||
teamwork = overallScores[RatingCategory.TEAMWORK],
|
||||
knowledge = overallScores[RatingCategory.KNOWLEDGE],
|
||||
entries = newObservation.entries,
|
||||
tutors = tutors
|
||||
)
|
||||
observation = observationRepository.save(observation)
|
||||
tutors.forEach {
|
||||
it.observations.add(observation)
|
||||
tutorRepository.save(it)
|
||||
}
|
||||
return observation.id
|
||||
}
|
||||
|
||||
@GetMapping("/observations")
|
||||
fun getObservations(@Valid @RequestBody observationsRequest: ObservationsRequest): List<Observation>? {
|
||||
if (observationsRequest.tutor != null) {
|
||||
val tutor = tutorRepository.findById(observationsRequest.tutor).get()
|
||||
return if (observationsRequest.whom == null) {
|
||||
observationRepository.findByTutorsAndDateBetween(tutor = tutor,
|
||||
startDate = observationsRequest.startDate,
|
||||
endDate = observationsRequest.endDate)
|
||||
} else {
|
||||
observationRepository.findByTutorsAndWhomAndDateBetween(tutor = tutor,
|
||||
whom = observationsRequest.whom,
|
||||
startDate = observationsRequest.startDate,
|
||||
endDate = observationsRequest.endDate)
|
||||
}
|
||||
}
|
||||
if (observationsRequest.site != null) {
|
||||
val site = siteRepository.findById(observationsRequest.site).get()
|
||||
return if (observationsRequest.whom == null) {
|
||||
observationRepository.findBySiteAndDateBetween(site = site,
|
||||
startDate = observationsRequest.startDate,
|
||||
endDate = observationsRequest.endDate)
|
||||
} else {
|
||||
observationRepository.findBySiteAndWhomAndDateBetween(site = site,
|
||||
whom = observationsRequest.whom,
|
||||
startDate = observationsRequest.startDate,
|
||||
endDate = observationsRequest.endDate)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@GetMapping("/observations/chartdata")
|
||||
fun getObservationsChartData(@Valid @RequestBody observationsRequest: ObservationsRequest): ChartData? {
|
||||
val data = getObservations(observationsRequest) ?: return null
|
||||
val groupedData = data.asSequence().groupBy { it.date }.map{ entry -> AverageData(
|
||||
entry.value.asSequence().mapNotNull { it.monitoring }.average(),
|
||||
entry.value.asSequence().mapNotNull { it.control }.average(),
|
||||
entry.value.asSequence().mapNotNull { it.conservatism }.average(),
|
||||
entry.value.asSequence().mapNotNull { it.teamwork }.average(),
|
||||
entry.value.asSequence().mapNotNull { it.knowledge }.average(),
|
||||
entry.key
|
||||
)}.toList()
|
||||
val dates = groupedData.map { it.date.toString("yyyy-MM-dd") }
|
||||
return ChartData(
|
||||
labels = dates,
|
||||
datasets = listOf(
|
||||
ChartDataset("Monitoring", "#F90", groupedData.map { it.monitoring }),
|
||||
ChartDataset("Control", "#3F0", groupedData.map { it.control }),
|
||||
ChartDataset("Conservatism", "#33F", groupedData.map { it.conservatism }),
|
||||
ChartDataset("Teamwork", "#FF0", groupedData.map { it.teamwork }),
|
||||
ChartDataset("Knowledge", "#000", groupedData.map { it.knowledge })
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class AverageData(
|
||||
val monitoring: Double,
|
||||
val control: Double,
|
||||
val conservatism: Double,
|
||||
val teamwork: Double,
|
||||
val knowledge: Double,
|
||||
val date: LocalDate
|
||||
)
|
@ -0,0 +1,81 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import org.joda.time.LocalDate
|
||||
import javax.persistence.*
|
||||
|
||||
@Entity
|
||||
data class Site(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Long = 0,
|
||||
val name: String){
|
||||
@OneToMany(fetch = FetchType.LAZY)
|
||||
val tutors: MutableSet<Tutor> = mutableSetOf()
|
||||
}
|
||||
|
||||
@Entity
|
||||
data class Tutor(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Long = 0,
|
||||
val name: String,
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
val site: Site
|
||||
){
|
||||
@ManyToMany
|
||||
@JoinTable(name = "tutor_observations",
|
||||
joinColumns = [JoinColumn(name =" tutor_id", referencedColumnName = "id")],
|
||||
inverseJoinColumns = [JoinColumn(name = "observation_id", referencedColumnName = "id")])
|
||||
val observations: MutableSet<Observation> = mutableSetOf()
|
||||
}
|
||||
|
||||
enum class TrainingType {
|
||||
INITIAL, CONTINUING
|
||||
}
|
||||
|
||||
enum class RatingCategory {
|
||||
MONITORING, CONTROL, CONSERVATISM, TEAMWORK, KNOWLEDGE
|
||||
}
|
||||
|
||||
@Entity
|
||||
data class Observation(
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
val id: Long = 0,
|
||||
@ManyToOne
|
||||
val site: Site,
|
||||
@Column(nullable = false)
|
||||
val date: LocalDate,
|
||||
@Column(nullable = false)
|
||||
val type: TrainingType,
|
||||
@Column(nullable = false)
|
||||
val observed: String,
|
||||
@Column(nullable = false)
|
||||
val whom: String,
|
||||
val monitoring: Double?,
|
||||
val control: Double?,
|
||||
val conservatism: Double?,
|
||||
val teamwork: Double?,
|
||||
val knowledge: Double?,
|
||||
@ElementCollection
|
||||
val entries: List<Entry>,
|
||||
@ManyToMany(mappedBy = "observations")
|
||||
val tutors: Set<Tutor>
|
||||
)
|
||||
|
||||
@Embeddable
|
||||
data class Entry(
|
||||
@Column(nullable = false)
|
||||
@JsonProperty
|
||||
val type: RatingCategory,
|
||||
@Column(nullable = false)
|
||||
@JsonProperty
|
||||
val rating: Int,
|
||||
@Column(nullable = false)
|
||||
@JsonProperty
|
||||
val strengths: String,
|
||||
@Column(nullable = false)
|
||||
@JsonProperty
|
||||
val improvements: String
|
||||
)
|
@ -0,0 +1,11 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.boot.runApplication
|
||||
|
||||
@SpringBootApplication
|
||||
class ObservationDatabaseApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<ObservationDatabaseApplication>(*args)
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.joda.time.LocalDate
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
|
||||
import org.springframework.data.repository.CrudRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
interface SiteRepository: CrudRepository<Site, Long>
|
||||
|
||||
@Repository
|
||||
interface TutorRepository: CrudRepository<Tutor, Long>
|
||||
|
||||
@Repository
|
||||
interface ObservationRepository: CrudRepository<Observation, Long>, JpaSpecificationExecutor<Observation> {
|
||||
fun findBySiteAndDateBetween(site: Site, startDate: LocalDate, endDate: LocalDate): List<Observation>
|
||||
|
||||
fun findByTutorsAndDateBetween(tutor: Tutor, startDate: LocalDate, endDate: LocalDate): List<Observation>
|
||||
|
||||
fun findBySiteAndWhomAndDateBetween(site: Site, whom: String, startDate: LocalDate, endDate: LocalDate): List<Observation>
|
||||
|
||||
fun findByTutorsAndWhomAndDateBetween(tutor: Tutor, whom: String, startDate: LocalDate, endDate: LocalDate): List<Observation>
|
||||
}
|
1
backend/src/main/resources/application.properties
Normal file
1
backend/src/main/resources/application.properties
Normal file
@ -0,0 +1 @@
|
||||
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes = true
|
@ -1,7 +0,0 @@
|
||||
|
||||
____ __ __ _
|
||||
/ __ \/ / ___ ___ _____ _____ _/ /_(_)__ ___ ___
|
||||
/ /_/ / _ \(_-</ -_) __/ |/ / _ `/ __/ / _ \/ _ \(_-<
|
||||
\____/_.__/___/\__/_/ |___/\_,_/\__/_/\___/_//_/___/
|
||||
DUNGENESS B TRAINING OBSERVATIONS DATABASE
|
||||
BY NATHAN CANNON (nathan.cannon@edf-energy.com)
|
@ -1,33 +0,0 @@
|
||||
package uk.co.neviyn.observations.api;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dropwizard.jackson.Jackson;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.core.ObservationEntry;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static io.dropwizard.testing.FixtureHelpers.fixture;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class NewObservationTest {
|
||||
|
||||
private static final ObjectMapper mapper = Jackson.newObjectMapper();
|
||||
|
||||
private final NewObservation newObservation = NewObservation.builder().siteId(1).tutorIds(Arrays.asList(1L, 2L, 3L))
|
||||
.observed("A random thing made for testing.").whom("Group A").type("INITIAL").monitoring(1).control(2).conservatism(3)
|
||||
.teamwork(4).knowledge(5).rawData(Collections.singletonList(new ObservationEntry("MONITORING", 5, "some", "another sum"))).build();
|
||||
|
||||
@Test
|
||||
public void serializesToJson() throws Exception {
|
||||
final String expected = mapper.writeValueAsString(mapper.readValue(fixture("fixtures/NewObservation.json"), NewObservation.class));
|
||||
assertEquals(expected, mapper.writeValueAsString(newObservation));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializesFromJson() throws Exception {
|
||||
assertEquals(newObservation, mapper.readValue(fixture("fixtures/NewObservation.json"), NewObservation.class));
|
||||
}
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package uk.co.neviyn.observations.core;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.dropwizard.jackson.Jackson;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static io.dropwizard.testing.FixtureHelpers.fixture;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@Slf4j
|
||||
public class ObservationTest {
|
||||
private static final ObjectMapper mapper = Jackson.newObjectMapper();
|
||||
|
||||
private final Observation observation = Observation.builder().observed("Just a test observation").type(TrainingType.INITIAL)
|
||||
.monitoring(1).control(2).conservatism(3).teamwork(4).knowledge(5).whom("Group A")
|
||||
.observations(Collections.singletonList(new ObservationEntry("MONITORING", 5, "some", "another sum")))
|
||||
.date(DateTime.parse("2018-09-18T00:00:00.000Z")).build();
|
||||
|
||||
@Test
|
||||
public void serializesToJson() throws Exception {
|
||||
final String expected = mapper.writeValueAsString(mapper.readValue(fixture("fixtures/Observation.json"), Observation.class));
|
||||
assertEquals(expected, mapper.writeValueAsString(observation));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deserializesFromJson() throws Exception {
|
||||
assertEquals(observation, mapper.readValue(fixture("fixtures/Observation.json"), Observation.class));
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import io.dropwizard.testing.junit.DAOTestRule;
|
||||
import org.junit.Rule;
|
||||
import uk.co.neviyn.observations.core.Observation;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
import uk.co.neviyn.observations.core.Tutor;
|
||||
|
||||
public abstract class DaoTestBase {
|
||||
@Rule
|
||||
public DAOTestRule testRule = DAOTestRule.newBuilder().addEntityClass(Observation.class).addEntityClass(Site.class).addEntityClass(Tutor.class).build();
|
||||
}
|
@ -1,219 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.api.AverageStats;
|
||||
import uk.co.neviyn.observations.core.Observation;
|
||||
import uk.co.neviyn.observations.core.ObservationEntry;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
import uk.co.neviyn.observations.core.TrainingType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ObservationDaoTest extends DaoTestBase {
|
||||
|
||||
private ObservationDao dao;
|
||||
private SiteDao siteDao;
|
||||
|
||||
private final Site site = Site.builder().name("Test site").build();
|
||||
|
||||
private final Observation observation = Observation.builder().observed("Just a test observation").type(TrainingType.INITIAL)
|
||||
.site(site).monitoring(1f).control(2f).conservatism(3f).teamwork(4f).knowledge(5f).whom("Group A")
|
||||
.observations(Collections.singletonList(new ObservationEntry("MONITORING", 5, "some", "another sum")))
|
||||
.date(DateTime.parse("2018-09-18T00:00:00.000Z")).build();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
dao = new ObservationDao(testRule.getSessionFactory());
|
||||
siteDao = new SiteDao(testRule.getSessionFactory());
|
||||
testRule.inTransaction(() -> siteDao.persist(site));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistAndGet() {
|
||||
Observation insert = testRule.inTransaction(() -> dao.persist(observation));
|
||||
assertNotNull(insert);
|
||||
assertTrue(insert.getId() > 0);
|
||||
assertNotNull(dao.get(insert.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listAll() {
|
||||
int numberOfObservations = 5;
|
||||
testRule.inTransaction(() -> {
|
||||
for (int i = 0; i < numberOfObservations; i++) {
|
||||
// Make actual copies, otherwise they will merely overwrite.
|
||||
dao.persist(SerializationUtils.clone(observation));
|
||||
}
|
||||
});
|
||||
List<Observation> observations = dao.listAll();
|
||||
assertNotNull(observations);
|
||||
assertEquals(numberOfObservations, observations.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listAllWithNoObservations() {
|
||||
List<Observation> observations = dao.listAll();
|
||||
assertNotNull(observations);
|
||||
assertEquals(0, observations.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsNoParam() {
|
||||
Observation otherEntry = SerializationUtils.clone(observation);
|
||||
otherEntry.setMonitoring(5);
|
||||
otherEntry.setControl(5);
|
||||
otherEntry.setConservatism(5);
|
||||
otherEntry.setTeamwork(5);
|
||||
Observation differentDay = SerializationUtils.clone(observation);
|
||||
differentDay.setDate(DateTime.parse("2018-09-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(observation);
|
||||
dao.persist(otherEntry);
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
List<AverageStats> stats = dao.averageStats(null, null, null, null, null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(2, stats.size());
|
||||
final AverageStats statObject = stats.get(0);
|
||||
assertEquals(3, statObject.getMonitoring(), 0);
|
||||
assertEquals(3.5, statObject.getControl(), 0);
|
||||
assertEquals(4, statObject.getConservatism(), 0);
|
||||
assertEquals(4.5, statObject.getTeamwork(), 0);
|
||||
assertEquals(5, statObject.getKnowledge(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsWithSite() {
|
||||
Observation otherEntry = SerializationUtils.clone(observation);
|
||||
otherEntry.setMonitoring(5);
|
||||
otherEntry.setControl(5);
|
||||
otherEntry.setConservatism(5);
|
||||
otherEntry.setTeamwork(5);
|
||||
Observation differentDay = SerializationUtils.clone(observation);
|
||||
differentDay.setDate(DateTime.parse("2018-09-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(observation);
|
||||
dao.persist(otherEntry);
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
List<AverageStats> stats = dao.averageStats(site, null, null, null, null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(2, stats.size());
|
||||
final AverageStats statObject = stats.get(0);
|
||||
assertEquals(3, statObject.getMonitoring(), 0);
|
||||
assertEquals(3.5, statObject.getControl(), 0);
|
||||
assertEquals(4, statObject.getConservatism(), 0);
|
||||
assertEquals(4.5, statObject.getTeamwork(), 0);
|
||||
assertEquals(5, statObject.getKnowledge(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsWithStartDate() {
|
||||
Observation otherEntry = SerializationUtils.clone(observation);
|
||||
otherEntry.setMonitoring(5);
|
||||
otherEntry.setControl(5);
|
||||
otherEntry.setConservatism(5);
|
||||
otherEntry.setTeamwork(5);
|
||||
Observation differentDay = SerializationUtils.clone(observation);
|
||||
differentDay.setDate(DateTime.parse("2018-09-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(observation);
|
||||
dao.persist(otherEntry);
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
List<AverageStats> stats = dao.averageStats(null, null, DateTime.parse("2018-09-01").withTimeAtStartOfDay(), null, null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(2, stats.size());
|
||||
// Change one observation to outside range
|
||||
differentDay.setDate(DateTime.parse("2018-08-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
stats = dao.averageStats(null, null, DateTime.parse("2018-09-01").withTimeAtStartOfDay(), null, null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(1, stats.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsWithEndDate() {
|
||||
Observation otherEntry = SerializationUtils.clone(observation);
|
||||
otherEntry.setMonitoring(5);
|
||||
otherEntry.setControl(5);
|
||||
otherEntry.setConservatism(5);
|
||||
otherEntry.setTeamwork(5);
|
||||
Observation differentDay = SerializationUtils.clone(observation);
|
||||
differentDay.setDate(DateTime.parse("2018-09-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(observation);
|
||||
dao.persist(otherEntry);
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
List<AverageStats> stats = dao.averageStats(null, null, null, DateTime.parse("2018-10-01").withTimeAtStartOfDay(), null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(2, stats.size());
|
||||
// Change one observation to outside range
|
||||
differentDay.setDate(DateTime.parse("2018-10-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
stats = dao.averageStats(null, null, null, DateTime.parse("2018-10-01").withTimeAtStartOfDay(), null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(1, stats.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsWithBothDate() {
|
||||
Observation otherEntry = SerializationUtils.clone(observation);
|
||||
otherEntry.setMonitoring(5);
|
||||
otherEntry.setControl(5);
|
||||
otherEntry.setConservatism(5);
|
||||
otherEntry.setTeamwork(5);
|
||||
otherEntry.setDate(DateTime.parse("2018-08-20"));
|
||||
Observation differentDay = SerializationUtils.clone(observation);
|
||||
differentDay.setDate(DateTime.parse("2018-10-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(observation);
|
||||
dao.persist(otherEntry);
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
List<AverageStats> stats = dao.averageStats(site, null, null, null, null);
|
||||
assertNotNull(stats);
|
||||
assertEquals(3, stats.size());
|
||||
stats = dao.averageStats(null, null, DateTime.parse("2018-09-01").withTimeAtStartOfDay(), DateTime.parse("2018-10-01").withTimeAtStartOfDay(), null);
|
||||
assertNotNull(stats);
|
||||
System.out.println(stats.toString());
|
||||
assertEquals(1, stats.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsWithWhom() {
|
||||
Observation otherEntry = SerializationUtils.clone(observation);
|
||||
otherEntry.setMonitoring(5);
|
||||
otherEntry.setControl(5);
|
||||
otherEntry.setConservatism(5);
|
||||
otherEntry.setTeamwork(5);
|
||||
Observation differentDay = SerializationUtils.clone(observation);
|
||||
differentDay.setDate(DateTime.parse("2018-09-20"));
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(observation);
|
||||
dao.persist(otherEntry);
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
List<AverageStats> stats = dao.averageStats(null, null, null, null, "Group A");
|
||||
assertNotNull(stats);
|
||||
assertEquals(2, stats.size());
|
||||
differentDay.setWhom("Group B");
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(differentDay);
|
||||
});
|
||||
stats = dao.averageStats(null, null, null, null, "Group A");
|
||||
assertNotNull(stats);
|
||||
assertEquals(1, stats.size());
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class SiteDaoTest extends DaoTestBase{
|
||||
|
||||
private SiteDao dao;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
dao = new SiteDao(testRule.getSessionFactory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listAll() {
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(Site.builder().name("Site A").build());
|
||||
dao.persist(Site.builder().name("Site B").build());
|
||||
dao.persist(Site.builder().name("Site C").build());
|
||||
});
|
||||
List<Site> result = dao.listAll();
|
||||
assertNotNull(result);
|
||||
assertEquals(3, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listAllWithNoObservations() {
|
||||
List<Site> sites = dao.listAll();
|
||||
assertNotNull(sites);
|
||||
assertEquals(0, sites.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistAndGet() {
|
||||
Site insert = testRule.inTransaction(() -> dao.persist(Site.builder().name("Test Site").build()));
|
||||
assertNotNull(insert);
|
||||
assertTrue(insert.getId() > 0);
|
||||
assertNotNull(dao.get(insert.getId()));
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package uk.co.neviyn.observations.dao;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.core.Site;
|
||||
import uk.co.neviyn.observations.core.Tutor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class TutorDaoTest extends DaoTestBase{
|
||||
|
||||
private TutorDao dao;
|
||||
private SiteDao siteDao;
|
||||
private final Site site = Site.builder().name("Test site").build();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
dao = new TutorDao(testRule.getSessionFactory());
|
||||
siteDao = new SiteDao(testRule.getSessionFactory());
|
||||
testRule.inTransaction(() -> siteDao.persist(site));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listAll() {
|
||||
testRule.inTransaction(() -> {
|
||||
dao.persist(Tutor.builder().name("Mr Test").site(site).build());
|
||||
dao.persist(Tutor.builder().name("Mr Test2").site(site).build());
|
||||
dao.persist(Tutor.builder().name("Mr Test3").site(site).build());
|
||||
});
|
||||
List<Tutor> result = dao.listAll();
|
||||
assertNotNull(result);
|
||||
assertEquals(3, result.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listAllWithNoObservations() {
|
||||
List<Tutor> tutors = dao.listAll();
|
||||
assertNotNull(tutors);
|
||||
assertEquals(0, tutors.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistAndGet() {
|
||||
Tutor insert = testRule.inTransaction(() -> dao.persist(Tutor.builder().name("Mr Test").site(site).build()));
|
||||
assertNotNull(insert);
|
||||
assertTrue(insert.getId() > 0);
|
||||
assertNotNull(dao.get(insert.getId()));
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package uk.co.neviyn.observations.resources;
|
||||
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import org.junit.After;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.api.NewObservation;
|
||||
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.dao.ObservationDao;
|
||||
import uk.co.neviyn.observations.dao.SiteDao;
|
||||
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.*;
|
||||
|
||||
public class ObservationResourceTest {
|
||||
|
||||
private static final ObservationDao dao = mock(ObservationDao.class);
|
||||
private static final SiteDao siteDao = mock(SiteDao.class);
|
||||
private static final TutorDao tutorDao = mock(TutorDao.class);
|
||||
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addResource(new ObservationResource(dao, tutorDao, siteDao))
|
||||
.build();
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
reset(dao);
|
||||
reset(siteDao);
|
||||
reset(tutorDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void add() {
|
||||
final Site testSite = Site.builder().id(1).name("Test Site").build();
|
||||
final List<Tutor> 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));
|
||||
resources.target("/observation").request().post(Entity.json(NewObservation.builder().type("INITIAL")
|
||||
.conservatism(1f).control(2f).knowledge(3f).monitoring(4f).teamwork(5f).siteId(1).tutorIds(Arrays.asList(1L, 2L))
|
||||
.observed("").whom("Group A").rawData(new ArrayList<>()).build()));
|
||||
verify(dao, times(1)).persist(any(Observation.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageObservationScores() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageStatsChartJs() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageObservationScoresForSite() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void averageObservationScoresForSiteChartJs() {
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package uk.co.neviyn.observations.resources;
|
||||
|
||||
import io.dropwizard.auth.AuthDynamicFeature;
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import org.junit.After;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.api.SelectOption;
|
||||
import uk.co.neviyn.observations.auth.SimpleAuthenticator;
|
||||
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.client.Entity;
|
||||
import javax.ws.rs.core.GenericType;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class SiteResourceTest {
|
||||
|
||||
private static final SiteDao dao = mock(SiteDao.class);
|
||||
private final String httpAuth = "Basic dGVzdDpURVNUUFc=";
|
||||
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addResource(new AuthDynamicFeature(
|
||||
new BasicCredentialAuthFilter.Builder<User>()
|
||||
.setAuthenticator(new SimpleAuthenticator("TESTPW"))
|
||||
.setRealm("SECURITY")
|
||||
.buildAuthFilter()
|
||||
))
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(User.class))
|
||||
.addResource(new SiteResource(dao))
|
||||
.build();
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
reset(dao);
|
||||
}
|
||||
|
||||
@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").tutors(new HashSet<>()).build());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allSites() {
|
||||
when(dao.listAll()).thenReturn(Arrays.asList(Site.builder().id(1).name("Site 1").build(), Site.builder().id(2).name("Site 2").build()));
|
||||
List<SelectOption<Long>> sites = resources.target("/site/all").request().get(new GenericType<List<SelectOption<Long>>>() {
|
||||
});
|
||||
assertNotNull(sites);
|
||||
assertEquals(2, sites.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSiteTutors() {
|
||||
Set<Tutor> 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());
|
||||
List<SelectOption<Long>> result = resources.target("/site/1/tutors").request().get(new GenericType<List<SelectOption<Long>>>() {
|
||||
});
|
||||
assertNotNull(result);
|
||||
assertEquals(2, result.size());
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
package uk.co.neviyn.observations.resources;
|
||||
|
||||
import io.dropwizard.auth.AuthDynamicFeature;
|
||||
import io.dropwizard.auth.AuthValueFactoryProvider;
|
||||
import io.dropwizard.auth.basic.BasicCredentialAuthFilter;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import org.junit.After;
|
||||
import org.junit.ClassRule;
|
||||
import org.junit.Test;
|
||||
import uk.co.neviyn.observations.auth.SimpleAuthenticator;
|
||||
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 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;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class TutorResourceTest {
|
||||
|
||||
private static final TutorDao dao = mock(TutorDao.class);
|
||||
private static final SiteDao siteDao = mock(SiteDao.class);
|
||||
private final String httpAuth = "Basic dGVzdDpURVNUUFc=";
|
||||
|
||||
@ClassRule
|
||||
public static final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addResource(new AuthDynamicFeature(
|
||||
new BasicCredentialAuthFilter.Builder<User>()
|
||||
.setAuthenticator(new SimpleAuthenticator("TESTPW"))
|
||||
.setRealm("SECURITY")
|
||||
.buildAuthFilter()
|
||||
))
|
||||
.addProvider(new AuthValueFactoryProvider.Binder<>(User.class))
|
||||
.addResource(new TutorResource(dao, siteDao))
|
||||
.build();
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
reset(dao);
|
||||
reset(siteDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void add() {
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allTutors() {
|
||||
List<Tutor> tutors = Arrays.asList(Tutor.builder().id(1).name("Mr A").build(), Tutor.builder().id(2).name("Mr B").build());
|
||||
when(dao.listAll()).thenReturn(tutors);
|
||||
List<Tutor> result = resources.target("/tutor/all").request().get(new GenericType<List<Tutor>>() {
|
||||
});
|
||||
for (Tutor t : result) {
|
||||
assertTrue(tutors.contains(t));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package uk.co.neviyn.observationdatabase
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.springframework.boot.test.context.SpringBootTest
|
||||
import org.springframework.test.context.junit4.SpringRunner
|
||||
|
||||
@RunWith(SpringRunner::class)
|
||||
@SpringBootTest
|
||||
class ObservationdatabaseApplicationTests {
|
||||
|
||||
@Test
|
||||
fun contextLoads() {
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
{
|
||||
"siteId":1,
|
||||
"tutorIds":[1,2,3],
|
||||
"observed":"A random thing made for testing.",
|
||||
"whom": "Group A",
|
||||
"type":"INITIAL",
|
||||
"monitoring":1,
|
||||
"control":2,
|
||||
"conservatism":3,
|
||||
"teamwork":4,
|
||||
"knowledge":5,
|
||||
"rawData":[{"type":"MONITORING","rating":5,"strengths":"some","improvements":"another sum"}]
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"id":0,
|
||||
"observed":"Just a test observation",
|
||||
"whom": "Group A",
|
||||
"type":"INITIAL",
|
||||
"monitoring":1,
|
||||
"control":2,
|
||||
"conservatism":3,
|
||||
"teamwork":4,
|
||||
"knowledge":5,
|
||||
"observations":[{
|
||||
"type": "MONITORING",
|
||||
"rating":5,
|
||||
"strengths":"some",
|
||||
"improvements":"another sum"
|
||||
}],
|
||||
"date":"2018-09-18T00:00:00.000Z"
|
||||
}
|
@ -92,7 +92,7 @@ export default {
|
||||
mounted() {
|
||||
this.resetStore();
|
||||
Vue.axios
|
||||
.get("/site/all")
|
||||
.get("/site")
|
||||
.then(response => {
|
||||
this.siteOptions = response.data;
|
||||
this.loaded = true;
|
||||
|
@ -40,10 +40,10 @@ export default {
|
||||
var form = document.getElementById("submission-form");
|
||||
if (form.checkValidity()) {
|
||||
Vue.axios
|
||||
.post("/site", this.siteName)
|
||||
.post("/site", { 'name':this.siteName })
|
||||
.then(response => {
|
||||
this.alertVariant = "success";
|
||||
this.alertText = "Successfully added " + response.data.name;
|
||||
this.alertText = "Successfully added " + response.data.text;
|
||||
this.showAlert();
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -38,7 +38,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
Vue.axios
|
||||
.get("/site/all")
|
||||
.get("/site")
|
||||
.then(response => {
|
||||
this.siteOptions = response.data;
|
||||
})
|
||||
@ -67,12 +67,12 @@ export default {
|
||||
if (form.checkValidity()) {
|
||||
Vue.axios
|
||||
.post("/tutor", {
|
||||
siteId: this.siteSelection,
|
||||
name: this.tutorName
|
||||
'siteId': this.siteSelection,
|
||||
'name': this.tutorName
|
||||
})
|
||||
.then(response => {
|
||||
this.alertVariant = "success";
|
||||
this.alertText = "Successfully added " + response.data.name;
|
||||
this.alertText = "Successfully added " + response.data.text;
|
||||
this.showAlert();
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -199,17 +199,12 @@ export default {
|
||||
if (form.checkValidity()) {
|
||||
Vue.axios
|
||||
.post("/observation", {
|
||||
siteId: this.site,
|
||||
tutorIds: this.tutors,
|
||||
site: this.site,
|
||||
tutors: this.tutors,
|
||||
observed: this.description,
|
||||
whom: this.whom,
|
||||
type: this.type,
|
||||
monitoring: this.totals[0],
|
||||
control: this.totals[1],
|
||||
conservatism: this.totals[2],
|
||||
teamwork: this.totals[3],
|
||||
knowledge: this.totals[4],
|
||||
rawData: JSON.parse(JSON.stringify(this.observations))
|
||||
entries: JSON.parse(JSON.stringify(this.observations))
|
||||
})
|
||||
.then(function(response) {
|
||||
console.log(response);
|
||||
|
@ -103,14 +103,12 @@ export default {
|
||||
methods: {
|
||||
getFilteredAverage: function() {
|
||||
Vue.axios
|
||||
.get("/observation/average", {
|
||||
params: {
|
||||
.get("/observations/chartdata", {
|
||||
site: this.siteSelection,
|
||||
tutor: this.tutorSelection,
|
||||
startDate: moment(this.startDate).format("YYYY-MM-DD"),
|
||||
endDate: moment(this.endDate).format("YYYY-MM-DD"),
|
||||
whom: this.whom
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
this.chartData = response.data;
|
||||
|
@ -26,22 +26,31 @@
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-container v-if="observationData != null">
|
||||
<b-row v-for="(observation, index) in observationData" v-bind:key="index">
|
||||
<b-col cols="3">
|
||||
<p>Category: {{ observation.type }}</p>
|
||||
<p>Rating: {{ observation.rating }}</p>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-form-group label="Strengths">
|
||||
<b-form-textarea :value="item.strengths" readonly>
|
||||
</b-form-textarea>
|
||||
</b-form-group>
|
||||
<b-form-group label="Areas of Improvement">
|
||||
<b-form-textarea :value="item.improvements" readonly>
|
||||
</b-form-textarea>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-container v-for="(observation, index) in observationData" v-bind:key="index">
|
||||
<b-row>
|
||||
<b-col>
|
||||
<p>{{ observation.date }}-{{ observation.type }}/{{ observation.observed }}-{{ obsevation.whom }}</p>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<b-row v-for="(entry, index) in observation.observations" v-bind:key="index">
|
||||
<b-row>
|
||||
<b-col cols="3">
|
||||
<p>{{ entry.type }}</p>
|
||||
<p>{{ entry.rating }}</p>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-form-group label="Strengths">
|
||||
<b-form-textarea :value="entry.strengths" readonly>
|
||||
</b-form-textarea>
|
||||
</b-form-group>
|
||||
<b-form-group label="Areas of Improvement">
|
||||
<b-form-textarea :value="entry.improvements" readonly>
|
||||
</b-form-textarea>
|
||||
</b-form-group>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</b-container>
|
||||
</b-container>
|
||||
</template>
|
||||
@ -78,14 +87,12 @@ export default {
|
||||
methods: {
|
||||
getFiltered: function() {
|
||||
Vue.axios
|
||||
.get("/observation", {
|
||||
params: {
|
||||
.get("/observations", {
|
||||
site: this.siteSelection,
|
||||
tutor: this.tutorSelection,
|
||||
startDate: moment(this.startDate).format("YYYY-MM-DD"),
|
||||
endDate: moment(this.endDate).format("YYYY-MM-DD"),
|
||||
whom: this.whom
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
this.chartData = response.data;
|
||||
@ -96,12 +103,12 @@ export default {
|
||||
this.$refs.errorModal.show();
|
||||
});
|
||||
},
|
||||
changeStartDate: function(e) {
|
||||
this.startDate = e.date;
|
||||
},
|
||||
changeEndDate: function(e) {
|
||||
this.endDate = e.date;
|
||||
}
|
||||
changeStartDate: function(e) {
|
||||
this.startDate = e.date;
|
||||
},
|
||||
changeEndDate: function(e) {
|
||||
this.endDate = e.date;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user