Skip to content

Commit

Permalink
HAI-1844: Create hankekayttaja instance for Hanke perustaja (#390)
Browse files Browse the repository at this point in the history
Add functionality to include Hanke perustaja in hanke kayttaja listing.

A hanke generated from a cable report is a special case. In these cases perustaja is generated from the ordered person in application contacts.

Additional: permission for hanke creator is now set in the service layer as the permission entity is required for token creation.
  • Loading branch information
pitkni authored Aug 31, 2023
1 parent 72fa279 commit 8e4ece4
Show file tree
Hide file tree
Showing 19 changed files with 271 additions and 177 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
package fi.hel.haitaton.hanke

import com.fasterxml.jackson.databind.node.ObjectNode
import fi.hel.haitaton.hanke.application.ApplicationsResponse
import fi.hel.haitaton.hanke.domain.HankeWithApplications
import fi.hel.haitaton.hanke.domain.Hankealue
import fi.hel.haitaton.hanke.factory.AlluDataFactory
import fi.hel.haitaton.hanke.factory.DateFactory
import fi.hel.haitaton.hanke.factory.HankeFactory
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withGeneratedOmistaja
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withPerustaja
import fi.hel.haitaton.hanke.geometria.Geometriat
import fi.hel.haitaton.hanke.logging.DisclosureLogService
import fi.hel.haitaton.hanke.permissions.PermissionCode
import fi.hel.haitaton.hanke.permissions.PermissionService
import fi.hel.haitaton.hanke.permissions.Role
import io.mockk.checkUnnecessaryStub
import io.mockk.clearAllMocks
import io.mockk.confirmVerified
Expand Down Expand Up @@ -322,7 +319,6 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
createdAt = getCurrentTimeUTC(),
)
every { hankeService.createHanke(any()) }.returns(createdHanke)
justRun { permissionService.setPermission(hankeId, USERNAME, Role.KAIKKI_OIKEUDET) }

post(url, hankeToBeCreated)
.andExpect(status().isOk)
Expand All @@ -332,56 +328,24 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll

verifySequence {
hankeService.createHanke(any())
permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET)
disclosureLogService.saveDisclosureLogsForHanke(createdHanke, USERNAME)
}
}

@Test
fun `When perustaja is provided return provided information`() {
val hanke = HankeFactory.create().withPerustaja()
every { hankeService.createHanke(any()) } returns hanke
justRun { permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET) }

post(url, hanke)
.andExpect(status().isOk)
.andExpect(jsonPath("$.perustaja.nimi").value("Pertti Perustaja"))
.andExpect(jsonPath("$.perustaja.email").value("[email protected]"))

verifySequence {
hankeService.createHanke(any())
permissionService.setPermission(any(), any(), any())
disclosureLogService.saveDisclosureLogsForHanke(any(), any())
}
}

@Test
fun `Sanitize hanke input and return 200`() {
val hanke = HankeFactory.create().apply { generated = true }
every { hankeService.createHanke(hanke.copy(id = null, generated = false)) } returns
hanke.copy(generated = false)
justRun { permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET) }

post(url, hanke).andExpect(status().isOk)

verifySequence {
hankeService.createHanke(any())
permissionService.setPermission(any(), any(), any())
disclosureLogService.saveDisclosureLogsForHanke(any(), any())
}
}

@Test
fun `With perustaja without sahkoposti returns 400`() {
val hakemus = HankeFactory.create().withPerustaja()
val content: ObjectNode = OBJECT_MAPPER.valueToTree(hakemus)
(content.get("perustaja") as ObjectNode).remove("email")

postRaw(url, content.toJsonString())
.andExpect(status().isBadRequest)
.andExpect(hankeError(HankeError.HAI0003))
}

@Test
fun `Add Hanke and HankeYhteystiedot and return it with newly created hankeTunnus (POST)`() {
val hankeToBeMocked =
Expand All @@ -393,7 +357,6 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
id = 12
omistajat[0].id = 3
}
justRun { permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET) }
every { hankeService.createHanke(any()) }.returns(expectedHanke)
val expectedContent = expectedHanke.toJsonString()

Expand All @@ -405,7 +368,6 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll

verifySequence {
hankeService.createHanke(any())
permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET)
disclosureLogService.saveDisclosureLogsForHanke(expectedHanke, USERNAME)
}
}
Expand Down Expand Up @@ -457,7 +419,6 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
expectedDateLoppu.toJsonString().substringAfter('"').substringBeforeLast('"')
// faking the service call
every { hankeService.createHanke(any()) }.returns(expectedHanke)
justRun { permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET) }

// Call it and check results
post(url, hankeToBeMocked)
Expand All @@ -472,7 +433,6 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll

verifySequence {
hankeService.createHanke(any())
permissionService.setPermission(any(), any(), Role.KAIKKI_OIKEUDET)
disclosureLogService.saveDisclosureLogsForHanke(expectedHanke, USERNAME)
}
}
Expand All @@ -495,14 +455,14 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
@Test
fun `Without permission returns 404`() {
val hanke = HankeFactory.create(version = null)
every { hankeService.loadHanke(HANKE_TUNNUS) } returns hanke
every { hankeService.findHankeOrThrow(HANKE_TUNNUS) } returns hanke
every { permissionService.hasPermission(hankeId, USERNAME, PermissionCode.EDIT) }
.returns(false)

put(url, hanke).andExpect(status().isNotFound).andExpect(hankeError(HankeError.HAI1001))

verifySequence {
hankeService.loadHanke(HANKE_TUNNUS)
hankeService.findHankeOrThrow(HANKE_TUNNUS)
permissionService.hasPermission(hankeId, USERNAME, PermissionCode.EDIT)
}
}
Expand All @@ -516,7 +476,7 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
modifiedBy = USERNAME
status = HankeStatus.PUBLIC
}
every { hankeService.loadHanke(HANKE_TUNNUS) } returns HankeFactory.create()
every { hankeService.findHankeOrThrow(HANKE_TUNNUS) } returns HankeFactory.create()
every { permissionService.hasPermission(hankeId, USERNAME, PermissionCode.EDIT) }
.returns(true)
every { hankeService.updateHanke(any()) }.returns(updatedHanke)
Expand All @@ -528,7 +488,7 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
.andExpect(jsonPath("$.status").value(HankeStatus.PUBLIC.name))

verifySequence {
hankeService.loadHanke(HANKE_TUNNUS)
hankeService.findHankeOrThrow(HANKE_TUNNUS)
permissionService.hasPermission(hankeId, USERNAME, PermissionCode.EDIT)
hankeService.updateHanke(any())
disclosureLogService.saveDisclosureLogsForHanke(updatedHanke, USERNAME)
Expand Down Expand Up @@ -565,7 +525,7 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
expectedHanke.alueet[0].haittaAlkuPvm = expectedDateAlku
expectedHanke.alueet[0].haittaLoppuPvm = expectedDateLoppu
val expectedContent = expectedHanke.toJsonString()
every { hankeService.loadHanke(HANKE_TUNNUS) } returns hankeToBeUpdated
every { hankeService.findHankeOrThrow(HANKE_TUNNUS) } returns hankeToBeUpdated
every {
permissionService.hasPermission(expectedHanke.id!!, USERNAME, PermissionCode.EDIT)
} returns true
Expand All @@ -583,7 +543,7 @@ class HankeControllerITests(@Autowired override val mockMvc: MockMvc) : Controll
) // Note, here as string, not the enum.

verifySequence {
hankeService.loadHanke(HANKE_TUNNUS)
hankeService.findHankeOrThrow(HANKE_TUNNUS)
permissionService.hasPermission(expectedHanke.id!!, USERNAME, PermissionCode.EDIT)
hankeService.updateHanke(any())
disclosureLogService.saveDisclosureLogsForHanke(expectedHanke, USERNAME)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import fi.hel.haitaton.hanke.application.CableReportWithoutHanke
import fi.hel.haitaton.hanke.domain.Hanke
import fi.hel.haitaton.hanke.domain.HankeYhteystieto
import fi.hel.haitaton.hanke.domain.Hankealue
import fi.hel.haitaton.hanke.domain.Perustaja
import fi.hel.haitaton.hanke.domain.YhteystietoTyyppi.YHTEISO
import fi.hel.haitaton.hanke.domain.YhteystietoTyyppi.YKSITYISHENKILO
import fi.hel.haitaton.hanke.domain.YhteystietoTyyppi.YRITYS
Expand All @@ -29,7 +28,6 @@ import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withGeneratedOmistaj
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withGeneratedOmistajat
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withGeneratedRakennuttaja
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withHankealue
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withPerustaja
import fi.hel.haitaton.hanke.factory.HankeFactory.Companion.withYhteystiedot
import fi.hel.haitaton.hanke.factory.HankealueFactory
import fi.hel.haitaton.hanke.geometria.Geometriat
Expand All @@ -41,6 +39,8 @@ import fi.hel.haitaton.hanke.logging.Status
import fi.hel.haitaton.hanke.logging.UserRole
import fi.hel.haitaton.hanke.permissions.HankeKayttajaRepository
import fi.hel.haitaton.hanke.permissions.KayttajaTunnisteRepository
import fi.hel.haitaton.hanke.permissions.PermissionCode
import fi.hel.haitaton.hanke.permissions.PermissionService
import fi.hel.haitaton.hanke.test.Asserts.isRecent
import fi.hel.haitaton.hanke.test.TestUtils
import fi.hel.haitaton.hanke.test.TestUtils.nextYear
Expand Down Expand Up @@ -94,6 +94,7 @@ class HankeServiceITests : DatabaseTest() {

@MockkBean private lateinit var cableReportService: CableReportService
@Autowired private lateinit var hankeService: HankeService
@Autowired private lateinit var permissionService: PermissionService
@Autowired private lateinit var auditLogRepository: AuditLogRepository
@Autowired private lateinit var applicationRepository: ApplicationRepository
@Autowired private lateinit var hankeRepository: HankeRepository
Expand All @@ -114,8 +115,7 @@ class HankeServiceITests : DatabaseTest() {

@Test
fun `create Hanke with full data set succeeds and returns a new domain object with the correct values`() {
val hanke: Hanke =
getATestHanke().withYhteystiedot { it.id = null }.withPerustaja().withHankealue()
val hanke: Hanke = getATestHanke().withYhteystiedot { it.id = null }.withHankealue()

val datetimeAlku = hanke.alueet[0].haittaAlkuPvm // nextyear.2.20 23:45:56Z
val datetimeLoppu = hanke.alueet[0].haittaLoppuPvm // nextyear.2.21 0:12:34Z
Expand All @@ -125,6 +125,10 @@ class HankeServiceITests : DatabaseTest() {
// Call create and get the return object:
val returnedHanke = hankeService.createHanke(hanke)

// Verify privileges
PermissionCode.values().forEach {
assertThat(permissionService.hasPermission(returnedHanke.id!!, USER_NAME, it)).isTrue()
}
// Check the return object in general:
assertThat(returnedHanke).isNotNull
assertThat(returnedHanke).isNotSameAs(hanke)
Expand All @@ -142,7 +146,6 @@ class HankeServiceITests : DatabaseTest() {
assertThat(returnedHanke.loppuPvm).isEqualTo(expectedDateLoppu)
assertThat(returnedHanke.vaihe).isEqualTo(Vaihe.SUUNNITTELU)
assertThat(returnedHanke.suunnitteluVaihe).isEqualTo(SuunnitteluVaihe.RAKENNUS_TAI_TOTEUTUS)
assertThat(returnedHanke.perustaja).isEqualTo(Perustaja("Pertti Perustaja", "[email protected]"))
assertThat(returnedHanke.tyomaaKatuosoite).isEqualTo("Testikatu 1")
assertThat(returnedHanke.tyomaaTyyppi).contains(TyomaaTyyppi.VESI, TyomaaTyyppi.MUU)
assertThat(returnedHanke.alueet[0].kaistaHaitta)
Expand Down Expand Up @@ -207,6 +210,16 @@ class HankeServiceITests : DatabaseTest() {
assertThat(kayttajaTunnisteRepository.findAll()).hasSize(4)
}

@Test
fun `create Hanke with without perustaja and contacts does not create hanke users`() {
val hanke = hankeService.createHanke(getATestHanke())

val hankeEntity = hankeRepository.findByHankeTunnus(hanke.hankeTunnus!!)!!
assertThat(hankeEntity.perustaja).isNull()
assertThat(hankeKayttajaRepository.findAll()).isEmpty()
assertThat(kayttajaTunnisteRepository.findAll()).isEmpty()
}

@Test
fun `create Hanke with partial data set and update with full data set give correct status`() {
// Setup Hanke (without any yhteystieto):
Expand Down Expand Up @@ -935,11 +948,13 @@ class HankeServiceITests : DatabaseTest() {

with(result) {
val application = applications.first()

assertThat(hanke.hankeTunnus).isEqualTo(application.hankeTunnus)
assertThat(hanke.nimi).isEqualTo(application.applicationData.name)
assertThat(application.applicationData.name)
.isEqualTo(inputApplication.applicationData.name)
val hankePerustaja = hankeRepository.findByHankeTunnus(hanke.hankeTunnus!!)?.perustaja
assertThat(hankePerustaja?.nimi).isEqualTo("Teppo Testihenkilö")
assertThat(hankePerustaja?.email).isEqualTo("[email protected]")
}
}

Expand Down Expand Up @@ -1378,7 +1393,6 @@ class HankeServiceITests : DatabaseTest() {
TemplateData(
updatedHanke.id!!,
updatedHanke.hankeTunnus!!,
updatedHanke.perustaja != null,
updatedHanke.alueet[0].id,
updatedHanke.alueet[0].geometriat?.id,
hankeVersion = 1,
Expand Down Expand Up @@ -1504,7 +1518,6 @@ class HankeServiceITests : DatabaseTest() {
data class TemplateData(
val hankeId: Int,
val hankeTunnus: String,
val hankePerustaja: Boolean = false,
val alueId: Int? = null,
val geometriaId: Int? = null,
val geometriaVersion: Int = 0,
Expand Down Expand Up @@ -1534,7 +1547,6 @@ class HankeServiceITests : DatabaseTest() {
TemplateData(
hanke.id!!,
hanke.hankeTunnus!!,
hanke.perustaja != null,
alue?.id,
alue?.geometriat?.id,
geometriaVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class HankeKayttajaServiceITest : DatabaseTest() {
@Autowired private lateinit var permissionRepository: PermissionRepository
@Autowired private lateinit var roleRepository: RoleRepository

private val perustaja = HankeFactory.defaultPerustaja

@Test
fun `getKayttajatByHankeId should return users from correct hanke only`() {
val hankeToFind = hankeFactory.save(HankeFactory.create().withYhteystiedot())
Expand Down Expand Up @@ -76,6 +78,25 @@ class HankeKayttajaServiceITest : DatabaseTest() {
}
}

@Test
fun `addHankeFounder saves kayttaja with correct permission and other data`() {
val hankeEntity = hankeFactory.saveEntity()
val savedHankeId = hankeEntity.id!!
val savedPermission = savePermission(savedHankeId, USERNAME, Role.KAIKKI_OIKEUDET)

hankeKayttajaService.addHankeFounder(savedHankeId, perustaja, savedPermission)

val kayttajaEntity =
hankeKayttajaRepository.findAll().also { assertThat(it).hasSize(1) }.first()
with(kayttajaEntity) {
assertThat(id).isNotNull()
assertThat(hankeId).isEqualTo(savedHankeId)
assertThat(permission!!).isOfEqualDataTo(savedPermission)
assertThat(sahkoposti).isEqualTo(perustaja.email)
assertThat(nimi).isEqualTo(perustaja.nimi)
}
}

@Test
fun `saveNewTokensFromApplication does nothing if application has no contacts`() {
val hanke = hankeFactory.saveEntity()
Expand Down Expand Up @@ -339,6 +360,20 @@ class HankeKayttajaServiceITest : DatabaseTest() {
k.transform { it.kayttajaTunniste }.isNotNull()
}

private fun Assert<PermissionEntity>.isOfEqualDataTo(other: PermissionEntity) =
given { actual ->
assertThat(actual.id).isEqualTo(other.id)
assertThat(actual.hankeId).isEqualTo(other.hankeId)
assertThat(actual.userId).isEqualTo(other.userId)
assertThat(actual.role).isOfEqualDataTo(other.role)
}

private fun Assert<RoleEntity>.isOfEqualDataTo(other: RoleEntity) = given { actual ->
assertThat(actual.id).isEqualTo(other.id)
assertThat(actual.role).isEqualTo(other.role)
assertThat(actual.permissionCode).isEqualTo(other.permissionCode)
}

private val expectedNames =
arrayOf(
"yhteys-etu1 yhteys-suku1",
Expand Down Expand Up @@ -386,14 +421,7 @@ class HankeKayttajaServiceITest : DatabaseTest() {
nimi: String,
sahkoposti: String
): HankeKayttajaEntity {
val permissionEntity =
permissionRepository.save(
PermissionEntity(
userId = "fake id",
hankeId = hankeId,
role = roleRepository.findOneByRole(Role.KATSELUOIKEUS),
)
)
val permissionEntity = savePermission(hankeId, "fake id", Role.KATSELUOIKEUS)

return hankeKayttajaRepository.save(
HankeKayttajaEntity(
Expand All @@ -405,4 +433,13 @@ class HankeKayttajaServiceITest : DatabaseTest() {
)
)
}

private fun savePermission(hankeId: Int, userId: String, role: Role) =
permissionRepository.save(
PermissionEntity(
userId = userId,
hankeId = hankeId,
role = roleRepository.findOneByRole(role)
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class PermissionServiceITest : DatabaseTest() {
@Test
fun `setPermission creates a new permission`() {
val hankeId = saveSeveralHanke(1)[0].id!!
permissionRepository.deleteAll() // remove permission created in hanke creation

permissionService.setPermission(hankeId, username, Role.KATSELUOIKEUS)

Expand All @@ -178,6 +179,7 @@ class PermissionServiceITest : DatabaseTest() {
@Test
fun `setPermission updates an existing permission`() {
val hankeId = saveSeveralHanke(1)[0].id!!
permissionRepository.deleteAll() // remove permission created in hanke creation
val role = roleRepository.findOneByRole(Role.KATSELUOIKEUS)
permissionRepository.save(
PermissionEntity(userId = username, hankeId = hankeId, role = role)
Expand Down
Loading

0 comments on commit 8e4ece4

Please sign in to comment.