Skip to content

Commit

Permalink
PI-2344 - add api (#4031)
Browse files Browse the repository at this point in the history
* PI-2344 - add api

* PI-2344 - update test

* Formatting changes

* Empty-Commit

* PI-2344 - correct role details

* PI-2344 - small refactor

* PI-2344 - apply review comments

* Formatting changes

* Empty-Commit

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
achimber-moj and github-actions[bot] authored Jul 15, 2024
1 parent 71e7dc8 commit 7050535
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
package uk.gov.justice.digital.hmpps.data

import jakarta.annotation.PostConstruct
import jakarta.persistence.EntityManager
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.boot.context.event.ApplicationReadyEvent
import org.springframework.context.ApplicationListener
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.data.generator.UserGenerator
import uk.gov.justice.digital.hmpps.user.AuditUserRepository

@Component
@ConditionalOnProperty("seed.database")
class DataLoader(
private val auditUserRepository: AuditUserRepository
private val auditUserRepository: AuditUserRepository,
private val em: EntityManager
) : ApplicationListener<ApplicationReadyEvent> {

@PostConstruct
fun saveAuditUser() {
auditUserRepository.save(UserGenerator.AUDIT_USER)
}

@Transactional
override fun onApplicationEvent(are: ApplicationReadyEvent) {
// Perform dev/test database setup here, using JPA repositories and generator classes...
em.persistAll(PersonGenerator.PERSON1)
}

private fun EntityManager.persistAll(vararg entities: Any) {
entities.forEach { persist(it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package uk.gov.justice.digital.hmpps.data.generator

import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person

object PersonGenerator {

val PERSON1: Person = generate("A123456", "Jon", "Harry", "Fred", "Smith")
val PERSON2: Person = generate("A123456", "Jon", "Harry", surname = "Smith")
val PERSON3: Person = generate("A123456", "Jon", thirdName = "Fred", surname = "Smith")
val PERSON4: Person = generate("A123456", "Jon", surname = "Smith")

fun generate(
crn: String,
forename: String,
secondName: String? = null,
thirdName: String? = null,
surname: String,
) = Person(IdGenerator.getAndIncrement(), crn, forename, secondName, thirdName, surname)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultHandlers.print
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import uk.gov.justice.digital.hmpps.api.model.Person
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator.PERSON1
import uk.gov.justice.digital.hmpps.telemetry.TelemetryService
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.contentAsJson
import uk.gov.justice.digital.hmpps.test.MockMvcExtensions.withToken

@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = RANDOM_PORT)
internal class GetPersonByCRNIntegrationTest {
@Autowired
lateinit var mockMvc: MockMvc

val crn = PERSON1.crn

@MockBean
lateinit var telemetryService: TelemetryService

@Test
fun `unauthorized status returned`() {
mockMvc
.perform(get("/probation-case/$crn"))
.andExpect(status().isUnauthorized)
}

@Test
fun `API call probation record not found`() {
mockMvc
.perform(get("/probation-case/Z123456").withToken())
.andExpect(status().isNotFound)
.andExpect(jsonPath("$.message").value("Person with crn of Z123456 not found"))
}

@Test
fun `API call return person data`() {
val expectedResponse = Person("Jon Harry Fred Smith")

val response = mockMvc
.perform(get("/probation-case/$crn").withToken())
.andExpect(status().isOk)
.andDo(print())
.andReturn().response.contentAsJson<Person>()

assertEquals(expectedResponse, response)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package uk.gov.justice.digital.hmpps.api.controller

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.SubjectAccessRequestsService

@RestController
@RequestMapping("probation-case/{crn}")
@PreAuthorize("hasRole('PROBATION_API__SUBJECT_ACCESS_REQUEST__DETAIL')")
class SubjectAccessRequestsController(private val subjectAccessRequestsService: SubjectAccessRequestsService) {

@GetMapping
fun getPersonalDetails(@PathVariable crn: String) = subjectAccessRequestsService.getPersonDetailsByCrn(crn)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package uk.gov.justice.digital.hmpps.api.model

data class Person(
val fullName: String
)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package uk.gov.justice.digital.hmpps.integration.delius.person.entity

import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.Id
import jakarta.persistence.Table
import org.hibernate.annotations.Immutable
import org.hibernate.annotations.SQLRestriction
import org.springframework.data.jpa.repository.JpaRepository
import uk.gov.justice.digital.hmpps.exception.NotFoundException

@Immutable
@Entity
@Table(name = "offender")
@SQLRestriction("soft_deleted = 0")
class Person(
@Id
@Column(name = "offender_id")
val id: Long,

@Column(columnDefinition = "char(7)")
val crn: String,

@Column(name = "first_name", length = 35)
val forename: String,

@Column(name = "second_name", length = 35)
val secondName: String? = null,

@Column(name = "third_name", length = 35)
val thirdName: String? = null,

@Column(name = "surname", length = 35)
val surname: String,

@Column(columnDefinition = "number")
val softDeleted: Boolean = false,
)

interface PersonRepository : JpaRepository<Person, Long> {
fun findByCrn(crn: String): Person?
}

fun PersonRepository.getPerson(crn: String) = findByCrn(crn) ?: throw NotFoundException("Person", "crn", crn)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package uk.gov.justice.digital.hmpps.service

import org.springframework.stereotype.Service
import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonRepository
import uk.gov.justice.digital.hmpps.integration.delius.person.entity.getPerson
import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person as PersonEntity
import uk.gov.justice.digital.hmpps.api.model.Person

@Service
class SubjectAccessRequestsService(private val personRepository: PersonRepository) {

fun getPersonDetailsByCrn(crn: String): Person {
return personRepository.getPerson(crn).toPerson()
}
}

fun PersonEntity.toPerson(): Person = Person(getName())

fun PersonEntity.getName(): String {
return listOfNotNull(forename, secondName, thirdName, surname).joinToString(" ")
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spring:
threads.virtual.enabled: true

oauth2.roles:
- EXAMPLE
- PROBATION_API__SUBJECT_ACCESS_REQUEST__DETAIL

springdoc.default-produces-media-type: application/json

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package uk.gov.justice.digital.hmpps.service

import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.junit.jupiter.MockitoExtension
import org.mockito.kotlin.whenever
import uk.gov.justice.digital.hmpps.data.generator.PersonGenerator
import uk.gov.justice.digital.hmpps.integration.delius.person.entity.Person
import uk.gov.justice.digital.hmpps.integration.delius.person.entity.PersonRepository

@ExtendWith(MockitoExtension::class)
class SubjectAccessRequestsServiceTest {

@Mock
lateinit var personRepository: PersonRepository

@InjectMocks
lateinit var subjectAccessRequestsService: SubjectAccessRequestsService

val person1 = PersonGenerator.PERSON1

@ParameterizedTest
@CsvSource(
"A123456,Jon Harry Fred Smith, 1",
"A123456,Jon Harry Smith, 2",
"A123456,Jon Fred Smith, 3",
"A123456,Jon Smith, 4",
)
fun `test returned name`(crn: String, fullName: String, person: Int) {

whenever(personRepository.findByCrn(crn)).thenReturn(getPerson(person))

val response = subjectAccessRequestsService.getPersonDetailsByCrn(crn)

assertEquals(fullName, response.fullName)
}

private fun getPerson(person: Int): Person {
return when (person) {
1 -> PersonGenerator.PERSON1
2 -> PersonGenerator.PERSON2
3 -> PersonGenerator.PERSON3
else -> PersonGenerator.PERSON4
}
}
}

0 comments on commit 7050535

Please sign in to comment.