Skip to content

Commit

Permalink
Merge pull request #507 from hmrc/TGP-2420/cya-update-refactor-to-inc…
Browse files Browse the repository at this point in the history
…lude-changes

TGP-2420/cya-update-refactor-to-include-changes
  • Loading branch information
besscerule authored Oct 16, 2024
2 parents 9e9c89b + 4ff0dbe commit 5684b41
Show file tree
Hide file tree
Showing 2 changed files with 302 additions and 5 deletions.
67 changes: 63 additions & 4 deletions app/controllers/CyaUpdateRecordController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import com.google.inject.Inject
import config.FrontendAppConfig
import connectors.{GoodsRecordConnector, OttConnector}
import controllers.actions.{DataRequiredAction, DataRetrievalAction, IdentifierAction}
import models.router.requests.PutRecordRequest
import models.{CheckMode, Country, NormalMode, UpdateGoodsRecord, UserAnswers, ValidationError}
import navigation.Navigator
import org.apache.pekko.Done
Expand Down Expand Up @@ -228,7 +229,6 @@ class CyaUpdateRecordController @Inject() (
newUpdateGoodsRecord: UpdateGoodsRecord
)(implicit hc: HeaderCarrier): Future[Done] =
if (newValue != oldValue) {

// TODO: remove this flag when EIS has implemented the PATCH method - TGP-2417 and keep the call to patchGoodsRecord as default
if (config.useEisPatchMethod) {
goodsRecordConnector.patchGoodsRecord(
Expand All @@ -239,6 +239,29 @@ class CyaUpdateRecordController @Inject() (
newUpdateGoodsRecord
)
}
} else {
Future.successful(Done)
}

private def updateGoodsRecordIfPutValueChanged(
newValue: String,
oldValue: String,
newUpdateGoodsRecord: UpdateGoodsRecord,
putRecordRequest: PutRecordRequest
)(implicit hc: HeaderCarrier): Future[Done] =
if (newValue != oldValue) {

// TODO: remove this flag when EIS has implemented the PATCH method - TGP-2417 and keep the call to putGoodsRecord as default
if (config.useEisPatchMethod) {
goodsRecordConnector.putGoodsRecord(
putRecordRequest,
newUpdateGoodsRecord.recordId
)
} else {
goodsRecordConnector.updateGoodsRecord(
newUpdateGoodsRecord
)
}

} else {
Future.successful(Done)
Expand Down Expand Up @@ -271,8 +294,28 @@ class CyaUpdateRecordController @Inject() (
)
updateGoodsRecord <-
Future.successful(UpdateGoodsRecord(request.eori, recordId, countryOfOrigin = Some(countryOfOrigin)))
putGoodsRecord <- Future.successful(
PutRecordRequest(
actorId = oldRecord.eori,
traderRef = oldRecord.traderRef,
comcode = oldRecord.comcode,
goodsDescription = oldRecord.goodsDescription,
countryOfOrigin = countryOfOrigin,
category = None,
assessments = oldRecord.assessments,
supplementaryUnit = oldRecord.supplementaryUnit,
measurementUnit = oldRecord.measurementUnit,
comcodeEffectiveFromDate = oldRecord.comcodeEffectiveFromDate,
comcodeEffectiveToDate = oldRecord.comcodeEffectiveToDate
)
)
_ = auditService.auditFinishUpdateGoodsRecord(recordId, request.affinityGroup, updateGoodsRecord)
_ <- updateGoodsRecordIfValueChanged(countryOfOrigin, oldRecord.countryOfOrigin, updateGoodsRecord)
_ <- updateGoodsRecordIfPutValueChanged(
countryOfOrigin,
oldRecord.countryOfOrigin,
updateGoodsRecord,
putGoodsRecord
)
updatedAnswersWithChange <- Future.fromTry(request.userAnswers.remove(HasCountryOfOriginChangePage(recordId)))
updatedAnswers <- Future.fromTry(updatedAnswersWithChange.remove(CountryOfOriginUpdatePage(recordId)))
_ <- sessionRepository.set(updatedAnswers)
Expand Down Expand Up @@ -316,11 +359,27 @@ class CyaUpdateRecordController @Inject() (
)
updateGoodsRecord <-
Future.successful(UpdateGoodsRecord(request.eori, recordId, commodityCode = Some(commodity)))
putGoodsRecord <- Future.successful(
PutRecordRequest(
actorId = oldRecord.eori,
traderRef = oldRecord.traderRef,
comcode = commodity.commodityCode,
goodsDescription = oldRecord.goodsDescription,
countryOfOrigin = oldRecord.countryOfOrigin,
category = None,
assessments = oldRecord.assessments,
supplementaryUnit = oldRecord.supplementaryUnit,
measurementUnit = oldRecord.measurementUnit,
comcodeEffectiveFromDate = oldRecord.comcodeEffectiveFromDate,
comcodeEffectiveToDate = oldRecord.comcodeEffectiveToDate
)
)
_ = auditService.auditFinishUpdateGoodsRecord(recordId, request.affinityGroup, updateGoodsRecord)
_ <- updateGoodsRecordIfValueChanged(
_ <- updateGoodsRecordIfPutValueChanged(
commodity.commodityCode,
oldRecord.comcode,
updateGoodsRecord
updateGoodsRecord,
putGoodsRecord
)
updatedAnswersWithChange <-
Future.fromTry(request.userAnswers.remove(HasCommodityCodeChangePage(recordId)))
Expand Down
240 changes: 239 additions & 1 deletion test/controllers/CyaUpdateRecordControllerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import base.SpecBase
import base.TestConstants.{testEori, testRecordId}
import config.FrontendAppConfig
import connectors.{GoodsRecordConnector, OttConnector}
import models.{CheckMode, Country, UpdateGoodsRecord}
import models.{CheckMode, Commodity, Country, UpdateGoodsRecord}
import org.apache.pekko.Done
import org.mockito.ArgumentMatchers.{any, eq => eqTo}
import org.mockito.Mockito.{never, verify, when}
Expand Down Expand Up @@ -316,6 +316,63 @@ class CyaUpdateRecordControllerSpec extends SpecBase with SummaryListFluency wit
}
}

"must PUT the goods record, cleanse the data and redirect to the Goods record Page" in {

val userAnswers = emptyUserAnswers
.set(page, answer)
.success
.value
.set(warningPage, true)
.success
.value

val mockGoodsRecordConnector = mock[GoodsRecordConnector]
val mockAuditService = mock[AuditService]
val mockSessionRepository = mock[SessionRepository]
val mockAppConfig = mock[FrontendAppConfig]

when(mockAppConfig.useEisPatchMethod).thenReturn(true)

when(mockGoodsRecordConnector.putGoodsRecord(any(), any())(any())).thenReturn(Future.successful(Done))
when(mockAuditService.auditFinishUpdateGoodsRecord(any(), any(), any())(any))
.thenReturn(Future.successful(Done))
when(mockSessionRepository.set(any())).thenReturn(Future.successful(true))

when(mockGoodsRecordConnector.getRecord(any(), any())(any())) thenReturn Future
.successful(record)

val application =
applicationBuilder(userAnswers = Some(userAnswers))
.overrides(
bind[GoodsRecordConnector].toInstance(mockGoodsRecordConnector),
bind[SessionRepository].toInstance(mockSessionRepository),
bind[AuditService].toInstance(mockAuditService),
bind[FrontendAppConfig].toInstance(mockAppConfig)
)
.build()

running(application) {
val request = FakeRequest(POST, postUrl)

val result = route(application, request).value
status(result) mustEqual SEE_OTHER
redirectLocation(result).value mustEqual routes.SingleRecordController.onPageLoad(testRecordId).url
verify(mockGoodsRecordConnector).putGoodsRecord(any(), any())(any())
verify(mockSessionRepository).set(any())

withClue("must call the audit connector with the supplied details") {
verify(mockAuditService)
.auditFinishUpdateGoodsRecord(
eqTo(testRecordId),
eqTo(AffinityGroup.Individual),
eqTo(expectedPayload)
)(
any()
)
}
}
}

}

"when user answers cannot create an update goods record" - {
Expand Down Expand Up @@ -776,6 +833,60 @@ class CyaUpdateRecordControllerSpec extends SpecBase with SummaryListFluency wit
}
}

"must PATCH the goods record, cleanse the data and redirect to the Goods record Page" in {

val userAnswers = emptyUserAnswers
.set(page, answer)
.success
.value

val mockGoodsRecordConnector = mock[GoodsRecordConnector]
val mockAuditService = mock[AuditService]
val mockSessionRepository = mock[SessionRepository]
val mockAppConfig = mock[FrontendAppConfig]

when(mockAppConfig.useEisPatchMethod).thenReturn(true)

when(mockGoodsRecordConnector.patchGoodsRecord(any())(any())).thenReturn(Future.successful(Done))
when(mockAuditService.auditFinishUpdateGoodsRecord(any(), any(), any())(any))
.thenReturn(Future.successful(Done))
when(mockSessionRepository.set(any())).thenReturn(Future.successful(true))

when(mockGoodsRecordConnector.getRecord(any(), any())(any())) thenReturn Future
.successful(record)

val application =
applicationBuilder(userAnswers = Some(userAnswers))
.overrides(
bind[GoodsRecordConnector].toInstance(mockGoodsRecordConnector),
bind[SessionRepository].toInstance(mockSessionRepository),
bind[AuditService].toInstance(mockAuditService),
bind[FrontendAppConfig].toInstance(mockAppConfig)
)
.build()

running(application) {
val request = FakeRequest(POST, postUrl)

val result = route(application, request).value
status(result) mustEqual SEE_OTHER
redirectLocation(result).value mustEqual routes.SingleRecordController.onPageLoad(testRecordId).url
verify(mockGoodsRecordConnector).patchGoodsRecord(any())(any())
verify(mockSessionRepository).set(any())

withClue("must call the audit connector with the supplied details") {
verify(mockAuditService)
.auditFinishUpdateGoodsRecord(
eqTo(testRecordId),
eqTo(AffinityGroup.Individual),
eqTo(expectedPayload)
)(
any()
)
}
}
}

"when trader reference has not been changed must not update the goods record and redirect to the Home Page" in {
val answer = record.traderRef
val expectedPayload = UpdateGoodsRecord(testEori, testRecordId, traderReference = Some(answer))
Expand Down Expand Up @@ -1153,6 +1264,133 @@ class CyaUpdateRecordControllerSpec extends SpecBase with SummaryListFluency wit
}
}
}

"must PUT the goods record, cleanse the data and redirect to the Goods record Page" in {

val userAnswers = emptyUserAnswers
.set(page, testCommodity.commodityCode)
.success
.value
.set(HasCorrectGoodsCommodityCodeUpdatePage(testRecordId), true)
.success
.value
.set(warningPage, true)
.success
.value
.set(HasCommodityCodeChangePage(testRecordId), true)
.success
.value
.set(CommodityUpdateQuery(testRecordId), testCommodity)
.success
.value

val mockGoodsRecordConnector = mock[GoodsRecordConnector]
val mockAuditService = mock[AuditService]
val mockSessionRepository = mock[SessionRepository]
val mockAppConfig = mock[FrontendAppConfig]

when(mockAppConfig.useEisPatchMethod).thenReturn(true)

when(mockGoodsRecordConnector.putGoodsRecord(any(), any())(any())).thenReturn(Future.successful(Done))
when(mockAuditService.auditFinishUpdateGoodsRecord(any(), any(), any())(any))
.thenReturn(Future.successful(Done))
when(mockSessionRepository.set(any())).thenReturn(Future.successful(true))

when(mockGoodsRecordConnector.getRecord(any(), any())(any())) thenReturn Future
.successful(record)

val application =
applicationBuilder(userAnswers = Some(userAnswers))
.overrides(
bind[GoodsRecordConnector].toInstance(mockGoodsRecordConnector),
bind[SessionRepository].toInstance(mockSessionRepository),
bind[AuditService].toInstance(mockAuditService),
bind[FrontendAppConfig].toInstance(mockAppConfig)
)
.build()

running(application) {
val request = FakeRequest(POST, postUrl)

val result = route(application, request).value
status(result) mustEqual SEE_OTHER
redirectLocation(result).value mustEqual routes.SingleRecordController.onPageLoad(testRecordId).url
verify(mockGoodsRecordConnector).putGoodsRecord(any(), any())(any())
verify(mockSessionRepository).set(any())

withClue("must call the audit connector with the supplied details") {
verify(mockAuditService)
.auditFinishUpdateGoodsRecord(
eqTo(testRecordId),
eqTo(AffinityGroup.Individual),
eqTo(expectedPayload)
)(
any()
)
}
}
}

"when commodity code has not been changed must not update the goods record and redirect to the Home Page" in {

val answer = Commodity(record.comcode, List("test"), validityStartDate, None)
val expectedPayload = UpdateGoodsRecord(testEori, testRecordId, commodityCode = Some(answer))

val userAnswers = emptyUserAnswers
.set(page, answer.commodityCode)
.success
.value
.set(HasCorrectGoodsCommodityCodeUpdatePage(testRecordId), true)
.success
.value
.set(warningPage, true)
.success
.value
.set(HasCommodityCodeChangePage(testRecordId), true)
.success
.value
.set(CommodityUpdateQuery(testRecordId), answer)
.success
.value

val mockConnector = mock[GoodsRecordConnector]
val mockAuditService = mock[AuditService]

when(mockConnector.getRecord(any(), any())(any())).thenReturn(Future.successful(record))
when(mockAuditService.auditFinishUpdateGoodsRecord(any(), any(), any())(any))
.thenReturn(Future.successful(Done))

val application =
applicationBuilder(userAnswers = Some(userAnswers))
.overrides(
bind[GoodsRecordConnector].toInstance(mockConnector),
bind[AuditService].toInstance(mockAuditService)
)
.build()

running(application) {
val request = FakeRequest(POST, postUrl)

val result = route(application, request).value

status(result) mustEqual SEE_OTHER
redirectLocation(result).value mustEqual routes.SingleRecordController.onPageLoad(testRecordId).url
verify(mockConnector, never()).updateGoodsRecord(any())(any())
verify(mockConnector).getRecord(eqTo(testEori), eqTo(testRecordId))(any())

withClue("must call the audit connector with the supplied details") {
verify(mockAuditService)
.auditFinishUpdateGoodsRecord(
eqTo(testRecordId),
eqTo(AffinityGroup.Individual),
eqTo(expectedPayload)
)(
any()
)
}
}
}

}

"when user answers cannot create an update goods record" - {
Expand Down

0 comments on commit 5684b41

Please sign in to comment.