More tests, more sanity checks

This commit is contained in:
neviyn 2019-03-04 15:54:30 +00:00
parent efb7903482
commit ff2618cc5d
4 changed files with 76 additions and 5 deletions

View File

@ -120,8 +120,8 @@ data class RatingComponent(
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0, val id: Long = 0,
val rating: Int, val rating: Int,
val strengths: String, val strengths: String = "",
val improvements: String val improvements: String = ""
) )
@Entity @Entity

View File

@ -64,6 +64,10 @@ object GroupSessionManager {
} }
fun dataComplete(): Boolean { fun dataComplete(): Boolean {
if(observations.isEmpty()){
logger.warn("Observations is currently empty")
return false
}
observations.values.forEach { observations.values.forEach {
it.scenarios.forEach { x -> it.scenarios.forEach { x ->
if (!x.ratingsAllValid()) if (!x.ratingsAllValid())

View File

@ -125,6 +125,11 @@ class GroupSessionController {
*/ */
@PostMapping("/submit") @PostMapping("/submit")
fun addGroupObservation(@Valid @RequestBody observationData: GroupObservation) { fun addGroupObservation(@Valid @RequestBody observationData: GroupObservation) {
val titles = observationData.scenarios.map { it.title }
if(GroupSessionManager.scenarioTitles!!.size != titles.size || !GroupSessionManager.scenarioTitles!!.containsAll(titles)) {
logger.warn("Received scenario data but titles did not match\nInput:$titles\nRequired:${GroupSessionManager.scenarioTitles}")
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Submission data contains non-matching title(s)")
}
GroupSessionManager.updateObservationData(observationData) GroupSessionManager.updateObservationData(observationData)
websocketMessenger.convertAndSend("/ws/scenarios", mapOf("scenarios" to GroupSessionManager.asScenarioView())) websocketMessenger.convertAndSend("/ws/scenarios", mapOf("scenarios" to GroupSessionManager.asScenarioView()))
} }
@ -132,6 +137,7 @@ class GroupSessionController {
@PostMapping("/complete") @PostMapping("/complete")
fun pushObservationsToDatabase(): Map<String, String> { fun pushObservationsToDatabase(): Map<String, String> {
if (GroupSessionManager.isValid() && GroupSessionManager.dataComplete()) { if (GroupSessionManager.isValid() && GroupSessionManager.dataComplete()) {
logger.info("Completing session ${GroupSessionManager.sessionId}")
val tutors = tutorRepository.findAllById(GroupSessionManager.tutors!!).toSet() val tutors = tutorRepository.findAllById(GroupSessionManager.tutors!!).toSet()
GroupSessionManager.observations.values.forEach { x -> GroupSessionManager.observations.values.forEach { x ->
saveObservation(Observation( saveObservation(Observation(
@ -157,6 +163,7 @@ class GroupSessionController {
websocketMessenger.convertAndSend("/ws/status", mapOf("status" to "complete")) websocketMessenger.convertAndSend("/ws/status", mapOf("status" to "complete"))
return mapOf("success" to "The submission was successfully completed.") return mapOf("success" to "The submission was successfully completed.")
} else if (!GroupSessionManager.dataComplete()) { } else if (!GroupSessionManager.dataComplete()) {
logger.info("Tried to complete a session whilst data was incomplete\n${GroupSessionManager.observations}")
throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Data is incomplete") throw ResponseStatusException(HttpStatus.BAD_REQUEST, "Data is incomplete")
} }
throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "No valid session") throw ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "No valid session")
@ -178,11 +185,10 @@ class GroupSessionController {
} }
if (ipv4 != null && this::environment.isInitialized) if (ipv4 != null && this::environment.isInitialized)
return mapOf("ip" to ipv4, "port" to environment["local.server.port"]) return mapOf("ip" to ipv4, "port" to environment["local.server.port"])
else if(ipv4 == null) { else if (ipv4 == null) {
logger.error("IP Address could not be determined") logger.error("IP Address could not be determined")
return mapOf("error" to "Could not determine IP Address") return mapOf("error" to "Could not determine IP Address")
} } else {
else {
logger.error("Port could not be determined, environment not initialised") logger.error("Port could not be determined, environment not initialised")
return mapOf("error" to "Could not determine port") return mapOf("error" to "Could not determine port")
} }

View File

@ -1,18 +1,29 @@
package uk.co.neviyn.observationdatabase.controller package uk.co.neviyn.observationdatabase.controller
import org.joda.time.LocalDate
import org.junit.After import org.junit.After
import org.junit.Assert.* import org.junit.Assert.*
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.any
import org.mockito.InjectMocks import org.mockito.InjectMocks
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito import org.mockito.Mockito
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnitRunner import org.mockito.junit.MockitoJUnitRunner
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.messaging.simp.SimpMessagingTemplate
import org.springframework.web.server.ResponseStatusException import org.springframework.web.server.ResponseStatusException
import uk.co.neviyn.observationdatabase.GroupObservation
import uk.co.neviyn.observationdatabase.GroupObservationInit import uk.co.neviyn.observationdatabase.GroupObservationInit
import uk.co.neviyn.observationdatabase.GroupSessionManager import uk.co.neviyn.observationdatabase.GroupSessionManager
import uk.co.neviyn.observationdatabase.Observation
import uk.co.neviyn.observationdatabase.ObservationRepository import uk.co.neviyn.observationdatabase.ObservationRepository
import uk.co.neviyn.observationdatabase.Person
import uk.co.neviyn.observationdatabase.PersonRepository import uk.co.neviyn.observationdatabase.PersonRepository
import uk.co.neviyn.observationdatabase.RatingComponent
import uk.co.neviyn.observationdatabase.Scenario
import uk.co.neviyn.observationdatabase.Site import uk.co.neviyn.observationdatabase.Site
import uk.co.neviyn.observationdatabase.SiteRepository import uk.co.neviyn.observationdatabase.SiteRepository
import uk.co.neviyn.observationdatabase.TrainingType import uk.co.neviyn.observationdatabase.TrainingType
@ -26,6 +37,8 @@ class GroupSessionControllerTest {
@InjectMocks @InjectMocks
lateinit var controller: GroupSessionController lateinit var controller: GroupSessionController
@Mock
lateinit var websocketMessenger: SimpMessagingTemplate
@Mock @Mock
lateinit var siteRepository: SiteRepository lateinit var siteRepository: SiteRepository
@Mock @Mock
@ -74,4 +87,52 @@ class GroupSessionControllerTest {
fun testRecoverSession_NoActiveSession() { fun testRecoverSession_NoActiveSession() {
controller.reconnectToGroupObservation() controller.reconnectToGroupObservation()
} }
@Test
fun testCompleteSession(){
val site = Site(1, "Test site")
val tutor = Tutor(1, "Mr X", site)
Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1)
Mockito.doReturn(listOf(tutor)).`when`(tutorRepository).findAllById(listOf(1))
val person = Person(1, "A Student")
Mockito.doReturn(person).`when`(personRepository).save(any())
val rc = RatingComponent(rating = 5)
val scenario = Scenario(0, "Sample title", rc, rc, rc, rc, rc, rc, rc, rc)
Mockito.doReturn(Observation(1, site, LocalDate.now(), TrainingType.INITIAL, "Sample title", 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, listOf(scenario), setOf(tutor), person)).`when`(observationRepository).save(any())
controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title")))
controller.addGroupObservation(GroupObservation("A Student", listOf(scenario)))
controller.pushObservationsToDatabase()
verify(observationRepository, times(1)).save(any())
assertEquals(1, tutor.observations.size)
}
@Test(expected = ResponseStatusException::class)
fun testCompleteSession_NoObservationData() {
val site = Site(1, "Test site")
Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1)
Mockito.doReturn(listOf(Tutor(1, "Mr X", site))).`when`(tutorRepository).findAllById(listOf(1))
controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title")))
controller.pushObservationsToDatabase()
}
@Test(expected = ResponseStatusException::class)
fun testCompleteSession_PartialObservationData() {
val site = Site(1, "Test site")
Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1)
Mockito.doReturn(listOf(Tutor(1, "Mr X", site))).`when`(tutorRepository).findAllById(listOf(1))
controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title")))
val rc = RatingComponent(rating = 5)
controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Sample title", RatingComponent(rating = 0), rc, rc, rc, rc, rc, rc, rc))))
controller.pushObservationsToDatabase()
}
@Test(expected = ResponseStatusException::class)
fun testCompleteSession_NonMatchingTitles() {
val site = Site(1, "Test site")
Mockito.doReturn(Optional.of(site)).`when`(siteRepository).findById(1)
Mockito.doReturn(listOf(Tutor(1, "Mr X", site))).`when`(tutorRepository).findAllById(listOf(1))
controller.startGroupObservation(GroupObservationInit(1, TrainingType.INITIAL, listOf(1), listOf("Sample title")))
val rc = RatingComponent(rating = 5)
controller.addGroupObservation(GroupObservation("A Student", listOf(Scenario(0, "Different Title", rc, rc, rc, rc, rc, rc, rc, rc))))
}
} }