Skip to content

Commit

Permalink
feat: add controllers into public_api for vessel search and port
Browse files Browse the repository at this point in the history
  • Loading branch information
lwih committed Jan 13, 2025
1 parent 6d6db7a commit b593770
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.public_api
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.cache.CacheManager
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import fr.gouv.cnsp.monitorfish.domain.use_cases.port.GetActivePorts
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.PortDataOutput

@RestController
@RequestMapping("/api/v1/ports")
@Tag(name = "Public APIs for ports")
class PublicPortController(
private val cacheManager: CacheManager,
private val getActivePorts: GetActivePorts,
) {
@GetMapping("")
@Operation(summary = "Get all active ports")
fun getActivePorts(): List<PortDataOutput> {
return getActivePorts.execute().map { port ->
PortDataOutput.fromPort(port)
}
}

@PutMapping(value = ["/invalidate"])
@Operation(summary = "Invalidate ports cache")
fun invalidatePorts() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.public_api

import fr.gouv.cnsp.monitorfish.domain.use_cases.vessel.SearchVessels
import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.VesselIdentityDataOutput
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v1/vessels")
@Tag(name = "APIs for Vessels")
class PublicVesselController(
private val searchVessels: SearchVessels,
) {

@GetMapping("/search")
@Operation(summary = "Search vessels")
fun searchVessel(
@Parameter(
description =
"Vessel internal reference number (CFR), external marker, IRCS, MMSI, name or beacon number",
required = true,
)
@RequestParam(name = "searched")
searched: String,
): List<VesselIdentityDataOutput> {
return searchVessels.execute(searched).map {
VesselIdentityDataOutput.fromVesselAndBeacon(it)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.public_api
import fr.gouv.cnsp.monitorfish.config.SentryConfig
import fr.gouv.cnsp.monitorfish.fakers.PortFaker
import fr.gouv.cnsp.monitorfish.infrastructure.cache.CaffeineConfiguration
import fr.gouv.cnsp.monitorfish.domain.use_cases.port.GetActivePorts
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -13,6 +14,12 @@ import org.springframework.context.annotation.Import
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.hamcrest.Matchers.equalTo
import org.mockito.BDDMockito.given

@Import(SentryConfig::class, CaffeineConfiguration::class)
@AutoConfigureMockMvc(addFilters = false)
Expand All @@ -24,6 +31,30 @@ class PublicPortControllerITests {
@Autowired
lateinit var cacheManager: CacheManager

@MockBean
private lateinit var getActivePorts: GetActivePorts

@Test
fun `Should get all active ports`() {
// Given
given(this.getActivePorts.execute()).willReturn(
listOf(
PortFaker.fakePort(locode = "ET", name = "Etel", latitude = 47.123, longitude = 0.123),
PortFaker.fakePort(locode = "AY", name = "Auray"),
),
)

// When
api.perform(get("/api/v1/ports"))
// Then
.andExpect(status().isOk)
.andExpect(jsonPath("$.length()", equalTo(2)))
.andExpect(jsonPath("$[0].locode", equalTo("ET")))
.andExpect(jsonPath("$[0].name", equalTo("Etel")))
.andExpect(jsonPath("$[0].latitude", equalTo(47.123)))
.andExpect(jsonPath("$[0].longitude", equalTo(0.123)))
}

@Test
fun `Should invalidate the cache`() {
// Given
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package fr.gouv.cnsp.monitorfish.infrastructure.api.public_api

import com.neovisionaries.i18n.CountryCode
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.anyOrNull
import com.nhaarman.mockitokotlin2.eq
import fr.gouv.cnsp.monitorfish.config.SentryConfig
import fr.gouv.cnsp.monitorfish.domain.entities.alerts.type.ThreeMilesTrawlingAlert
import fr.gouv.cnsp.monitorfish.domain.entities.vessel.*
import fr.gouv.cnsp.monitorfish.domain.use_cases.TestUtils
import fr.gouv.cnsp.monitorfish.domain.use_cases.vessel.*
import fr.gouv.cnsp.monitorfish.domain.entities.beacon_malfunctions.*
import org.hamcrest.Matchers.equalTo
import org.junit.jupiter.api.Test
import org.mockito.BDDMockito
import org.mockito.BDDMockito.given
import org.mockito.Mockito
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.context.annotation.Import
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status

@Import(SentryConfig::class)
@AutoConfigureMockMvc(addFilters = false)
@WebMvcTest(value = [(PublicVesselController::class)])
class PublicVesselControllerITests {
@Autowired
private lateinit var api: MockMvc

@MockBean
private lateinit var searchVessels: SearchVessels

@Test
fun `Should search for a vessel`() {
// Given
given(this.searchVessels.execute(any())).willReturn(
listOf(
VesselAndBeacon(
vessel =
Vessel(
id = 1,
internalReferenceNumber = "FR224226850",
vesselName = "MY AWESOME VESSEL",
flagState = CountryCode.FR,
declaredFishingGears = listOf("Trémails"),
vesselType = "Fishing",
hasLogbookEsacapt = false,
),
beacon = Beacon(beaconNumber = "123456", vesselId = 1),
),
VesselAndBeacon(
vessel =
Vessel(
id = 2,
internalReferenceNumber = "GBR21555445",
vesselName = "ANOTHER VESSEL",
flagState = CountryCode.GB,
declaredFishingGears = listOf("Trémails"),
vesselType = "Fishing",
hasLogbookEsacapt = false,
),
beacon = null,
),
),
)

// When
api.perform(get("/api/v1/vessels/search?searched=VESSEL"))
// Then
.andExpect(status().isOk)
.andExpect(jsonPath("$.length()", equalTo(2)))
.andExpect(jsonPath("$[0].flagState", equalTo("FR")))
.andExpect(jsonPath("$[0].vesselName", equalTo("MY AWESOME VESSEL")))
.andExpect(jsonPath("$[0].internalReferenceNumber", equalTo("FR224226850")))
.andExpect(jsonPath("$[0].beaconNumber", equalTo("123456")))
.andExpect(jsonPath("$[1].flagState", equalTo("GB")))
.andExpect(jsonPath("$[1].vesselName", equalTo("ANOTHER VESSEL")))
.andExpect(jsonPath("$[1].internalReferenceNumber", equalTo("GBR21555445")))

Mockito.verify(searchVessels).execute("VESSEL")
}
}

0 comments on commit b593770

Please sign in to comment.