Skip to content

Commit

Permalink
Man 183 get sentences (#4493)
Browse files Browse the repository at this point in the history
* MAN-183 - add new api

* MAN-183 - add new api

* MAN-183 - small refactor to create appointment and update tests

* Formatting changes

---------

Co-authored-by: probation-integration-bot[bot] <177347787+probation-integration-bot[bot]@users.noreply.github.com>
  • Loading branch information
1 parent ae0b9ca commit 3dc7f10
Show file tree
Hide file tree
Showing 21 changed files with 419 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ class DataLoader(
OffenderManagerGenerator.STAFF_2,
OffenderManagerGenerator.STAFF_USER_1,
OffenderManagerGenerator.STAFF_USER_2,
OffenderManagerGenerator.STAFF_TEAM,
OffenderManagerGenerator.OFFENDER_MANAGER_ACTIVE,
OffenderManagerGenerator.OFFENDER_MANAGER_INACTIVE,
OffenderManagerGenerator.DEFAULT_LOCATION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,22 @@ object OffenderManagerGenerator {

val STAFF_1 = Staff(IdGenerator.getAndIncrement(), "Peter", "Parker", DEFAULT_PROVIDER, null)
val STAFF_2 = Staff(IdGenerator.getAndIncrement(), "Bruce", "Wayne", DEFAULT_PROVIDER, null)
val STAFF_USER_1 = StaffUser(IdGenerator.getAndIncrement(), STAFF_1, "peter-parker")
val STAFF_USER_2 = StaffUser(IdGenerator.getAndIncrement(), STAFF_2, "bwayne")
val STAFF_USER_1 = StaffUser(IdGenerator.getAndIncrement(), STAFF_1, "peter-parker", "peter", surname = "parker")
val STAFF_USER_2 = StaffUser(IdGenerator.getAndIncrement(), STAFF_2, "bwayne", "bruce", surname = "wayne")
val STAFF_TEAM = ContactStaffTeam(StaffTeamLinkId(STAFF_1.id, TEAM))

val DEFAULT_LOCATION = Location(IdGenerator.getAndIncrement(), "B20", "1 Birmingham Street")
val DEFAULT_LOCATION =
Location(
IdGenerator.getAndIncrement(),
"B20",
"1 Birmingham Street",
"Bham House",
"1",
"Birmingham Street",
"Birmingham",
"West Midlands",
"B20 3BA"
)

val TEAM_OFFICE = TeamOfficeLink(TeamOfficeLinkId(TEAM.id, DEFAULT_LOCATION))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import uk.gov.justice.digital.hmpps.api.model.appointment.Outcome
import uk.gov.justice.digital.hmpps.api.model.appointment.User
import uk.gov.justice.digital.hmpps.data.generator.AppointmentGenerator.APPOINTMENT_TYPES
import uk.gov.justice.digital.hmpps.data.generator.AppointmentGenerator.ATTENDED_COMPLIED
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.DEFAULT_LOCATION
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository
import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo
Expand Down Expand Up @@ -134,7 +134,7 @@ class AppointmentOutcomeIntegrationTest {
.withToken()
.withJson(
CreateAppointment(
User(STAFF_USER_1.username, TEAM.description),
User(STAFF_USER_1.username, DEFAULT_LOCATION.id),
CreateAppointment.Type.PlannedOfficeVisitNS,
ZonedDateTime.now().plusDays(1),
ZonedDateTime.now().plusDays(2),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import uk.gov.justice.digital.hmpps.data.generator.ContactGenerator.DEFAULT_PROV
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.DEFAULT_LOCATION
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_1
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.TEAM
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.integrations.delius.sentence.entity.AppointmentRepository
import uk.gov.justice.digital.hmpps.test.CustomMatchers.isCloseTo
Expand All @@ -41,7 +40,7 @@ class CreateAppointmentIntegrationTest {
@Autowired
internal lateinit var appointmentRepository: AppointmentRepository

private val user = User(STAFF_USER_1.username, TEAM.description)
private val user = User(STAFF_USER_1.username, DEFAULT_LOCATION.id)

private val person = PersonGenerator.PERSON_1

Expand Down Expand Up @@ -156,7 +155,7 @@ class CreateAppointmentIntegrationTest {
}

companion object {
private val user = User(STAFF_USER_1.username, TEAM.description)
private val user = User(STAFF_USER_1.username, DEFAULT_LOCATION.id)

@JvmStatic
fun createAppointment() = listOf(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package uk.gov.justice.digital.hmpps

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import uk.gov.justice.digital.hmpps.api.model.sentence.*
import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITHOUT_NOTES
import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITH_1500_CHAR_NOTE
import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITH_NOTES
import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LC_WITH_NOTES_WITHOUT_ADDED_BY
import uk.gov.justice.digital.hmpps.data.generator.LicenceConditionGenerator.LIC_COND_MAIN_CAT
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.ACTIVE_ORDER
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.EVENT_1
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.EVENT_2
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.REQUIREMENT
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.REQUIREMENT_UNPAID_WORK
import uk.gov.justice.digital.hmpps.data.generator.personalDetails.PersonDetailsGenerator
import uk.gov.justice.digital.hmpps.service.toSummary
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SentencesIntegrationTest {
@Autowired
lateinit var mockMvc: MockMvc

@Test
fun `unauthorized status returned`() {
mockMvc
.perform(MockMvcRequestBuilders.get("/sentences/X123456"))
.andExpect(MockMvcResultMatchers.status().isUnauthorized)
}

@Test
fun `no active sentences`() {
val response = mockMvc
.perform(
MockMvcRequestBuilders.get("/sentences/${PersonDetailsGenerator.PERSONAL_DETAILS.crn}").withToken()
)
.andExpect(MockMvcResultMatchers.status().isOk)
.andReturn().response.contentAsJson<MinimalSentenceOverview>()

val expected = MinimalSentenceOverview(
PersonDetailsGenerator.PERSONAL_DETAILS.toSummary()
)

assertEquals(expected, response)
}

@Test
fun `get active sentences`() {
val response = mockMvc
.perform(MockMvcRequestBuilders.get("/sentences/${PersonGenerator.OVERVIEW.crn}").withToken())
.andExpect(MockMvcResultMatchers.status().isOk)
.andReturn().response.contentAsJson<MinimalSentenceOverview>()

val expected = MinimalSentenceOverview(
PersonGenerator.OVERVIEW.toSummary(),
listOf(
MinimalSentence(EVENT_2.id),
MinimalSentence(
EVENT_1.id,
order = MinimalOrder(ACTIVE_ORDER.type.description, ACTIVE_ORDER.date),
licenceConditions = listOf(
MinimalLicenceCondition(LC_WITH_NOTES.id, LIC_COND_MAIN_CAT.description),
MinimalLicenceCondition(LC_WITHOUT_NOTES.id, LIC_COND_MAIN_CAT.description),
MinimalLicenceCondition(LC_WITH_NOTES_WITHOUT_ADDED_BY.id, LIC_COND_MAIN_CAT.description),
MinimalLicenceCondition(LC_WITH_1500_CHAR_NOTE.id, LIC_COND_MAIN_CAT.description)
),
requirements = listOf(
MinimalRequirement(REQUIREMENT.id, "1 days RAR, 1 completed"),
MinimalRequirement(REQUIREMENT_UNPAID_WORK.id, "Unpaid Work - Intensive")
)
)
)
)

assertEquals(expected, response)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package uk.gov.justice.digital.hmpps

import org.hamcrest.Matchers.equalTo
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import uk.gov.justice.digital.hmpps.api.model.sentence.Address
import uk.gov.justice.digital.hmpps.api.model.sentence.LocationDetails
import uk.gov.justice.digital.hmpps.api.model.sentence.Name
import uk.gov.justice.digital.hmpps.api.model.sentence.UserOfficeLocation
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.DEFAULT_LOCATION
import uk.gov.justice.digital.hmpps.data.generator.OffenderManagerGenerator.STAFF_USER_1
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class UserLocationIntegrationTest {
@Autowired
lateinit var mockMvc: MockMvc

@Test
fun `unauthorized status returned`() {
mockMvc
.perform(MockMvcRequestBuilders.get("/user/peter-parker/locations"))
.andExpect(MockMvcResultMatchers.status().isUnauthorized)
}

@Test
fun `user not found`() {
mockMvc.perform(MockMvcRequestBuilders.get("/user/user/locations").withToken())
.andDo(print())
.andExpect(MockMvcResultMatchers.status().isNotFound)
.andExpect(jsonPath("$.message", equalTo("User with username of user not found")))
}

@Test
fun `get user locations`() {
val response = mockMvc.perform(MockMvcRequestBuilders.get("/user/peter-parker/locations").withToken())
.andDo(print())
.andExpect(MockMvcResultMatchers.status().isOk)
.andReturn().response.contentAsJson<UserOfficeLocation>()

val expected = UserOfficeLocation(
Name(STAFF_USER_1.forename, surname = STAFF_USER_1.surname),
listOf(
LocationDetails(
DEFAULT_LOCATION.id,
DEFAULT_LOCATION.description,
Address(
DEFAULT_LOCATION.buildingNumber,
DEFAULT_LOCATION.streetName,
DEFAULT_LOCATION.townCity,
DEFAULT_LOCATION.county,
DEFAULT_LOCATION.postcode
)
)
)
)
assertEquals(expected, response)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package uk.gov.justice.digital.hmpps.api.controller

import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.*
import uk.gov.justice.digital.hmpps.service.SentenceService

@RestController
@Tag(name = "Sentences")
@RequestMapping("/sentences/{crn}")
@PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')")
class SentencesController(private val sentenceService: SentenceService) {

@GetMapping
@Operation(summary = "Display active events")
fun getOverview(
@PathVariable crn: String,
@RequestParam(required = false) number: String?,
) = sentenceService.getActiveSentences(crn)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package uk.gov.justice.digital.hmpps.api.controller

import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.security.access.prepost.PreAuthorize
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import uk.gov.justice.digital.hmpps.service.UserLocationService

@RestController
@Tag(name = "Locations")
@RequestMapping("/user/{username}")
@PreAuthorize("hasRole('PROBATION_API__MANAGE_A_SUPERVISION__CASE_DETAIL')")
class UserLocationController(private val userLocationService: UserLocationService) {

@GetMapping("/locations")
@Operation(summary = "Display user locations")
fun getUserOfficeLocations(@PathVariable username: String) = userLocationService.getUserOfficeLocations(username)
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ data class CreateAppointment(

data class User(
val username: String,
val team: String
val locationId: Long
)

data class OverlappingAppointment(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import java.time.LocalDate

data class Order(
val description: String,
val length: Long?,
val length: Long? = null,
val endDate: LocalDate?,
val releaseDate: LocalDate? = null,
val startDate: LocalDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ data class LicenceConditionNote(
data class LicenceConditionNoteDetail(
val personSummary: PersonSummary,
val licenceCondition: LicenceCondition? = null
)

data class MinimalLicenceCondition(
val id: Long,
val mainDescription: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,8 @@ data class Requirement(
val notes: String?,
val rar: Rar? = null
)

data class MinimalRequirement(
val id: Long,
val description: String
)
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
package uk.gov.justice.digital.hmpps.api.model.sentence

import uk.gov.justice.digital.hmpps.api.model.overview.Order
import java.time.LocalDate

data class Sentence(
val offenceDetails: OffenceDetails,
val conviction: Conviction? = null,
val order: Order? = null,
val requirements: List<Requirement> = listOf(),
val courtDocuments: List<CourtDocument> = listOf(),
val unpaidWorkProgress: String?,
val unpaidWorkProgress: String? = null,
val licenceConditions: List<LicenceCondition> = listOf()
)
)

data class MinimalSentence(
val id: Long,
val order: MinimalOrder? = null,
val licenceConditions: List<MinimalLicenceCondition> = listOf(),
val requirements: List<MinimalRequirement> = listOf()
)

data class MinimalOrder(
val description: String,
val startDate: LocalDate,
val endDate: LocalDate? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ data class SentenceSummary(
val eventNumber: String,
val description: String
)

data class MinimalSentenceOverview(
val personSummary: PersonSummary,
val sentences: List<MinimalSentence> = emptyList(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package uk.gov.justice.digital.hmpps.api.model.sentence

data class UserOfficeLocation(
val name: Name,
val locations: List<LocationDetails>
)

data class Name(
val forename: String,
val middleName: String? = null,
val surname: String
)

data class LocationDetails(
val id: Long,
val description: String,
val address: Address
)

data class Address(
val buildingNumber: String? = null,
val streetName: String? = null,
val town: String? = null,
val county: String? = null,
val postcode: String? = null
)
Loading

0 comments on commit 3dc7f10

Please sign in to comment.