Skip to content

Commit

Permalink
API-4540: reverted logic that allowed empty values to be sent to PPNS…
Browse files Browse the repository at this point in the history
… on add callbackUrl. (#86)
mattclark-zerogravit authored Aug 14, 2020

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 58b3d0a commit 79bd5c6
Showing 6 changed files with 100 additions and 80 deletions.
Original file line number Diff line number Diff line change
@@ -18,22 +18,21 @@ package uk.gov.hmrc.apisubscriptionfields.connector

import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.apisubscriptionfields.config.ApplicationConfig
import uk.gov.hmrc.apisubscriptionfields.model.{BoxId, ClientId, PPNSCallBackUrlValidationResponse, PPNSCallBackUrlSuccessResponse, PPNSCallBackUrlFailedResponse}
import uk.gov.hmrc.apisubscriptionfields.model.Types.FieldValue
import uk.gov.hmrc.apisubscriptionfields.model._
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.play.bootstrap.http.HttpClient
import uk.gov.hmrc.play.http.metrics._

import scala.concurrent.{ExecutionContext, Future}
import scala.util.control.NonFatal
import uk.gov.hmrc.apisubscriptionfields.model.PPNSCallBackUrlSuccessResponse
import uk.gov.hmrc.apisubscriptionfields.model.PPNSCallBackUrlFailedResponse

@Singleton
class PushPullNotificationServiceConnector @Inject()(http: HttpClient, appConfig: ApplicationConfig, val apiMetrics: ApiMetrics)
(implicit ec: ExecutionContext) extends RecordMetrics {
import uk.gov.hmrc.apisubscriptionfields.connector.JsonFormatters._

val api = API("api-subscription-fields")
val api: API = API("api-subscription-fields")

private lazy val externalServiceUri = appConfig.pushPullNotificationServiceURL

@@ -57,15 +56,15 @@ class PushPullNotificationServiceConnector @Inject()(http: HttpClient, appConfig
}
}

def updateCallBackUrl(clientId: ClientId, boxId: BoxId, callbackUrl: String)(implicit hc: HeaderCarrier): Future[PPNSCallBackUrlValidationResponse] = {
val payload = UpdateCallBackUrlRequest(clientId, callbackUrl)

http.PUT[UpdateCallBackUrlRequest, UpdateCallBackUrlResponse](s"$externalServiceUri/box/${boxId.value.toString}/callback", payload)
.map(response =>
if(response.successful) PPNSCallBackUrlSuccessResponse
else response.errorMessage.fold(PPNSCallBackUrlFailedResponse("Unknown Error"))(PPNSCallBackUrlFailedResponse)
).recover {
case NonFatal(e) => throw new RuntimeException(s"Unexpected response from $externalServiceUri: ${e.getMessage}")
}
def updateCallBackUrl(clientId: ClientId, boxId: BoxId, callbackUrl: FieldValue)
(implicit hc: HeaderCarrier): Future[PPNSCallBackUrlValidationResponse] = {
val payload = UpdateCallBackUrlRequest(clientId, callbackUrl)
http.PUT[UpdateCallBackUrlRequest, UpdateCallBackUrlResponse](s"$externalServiceUri/box/${boxId.value.toString}/callback", payload)
.map(response =>
if (response.successful) PPNSCallBackUrlSuccessResponse
else response.errorMessage.fold(PPNSCallBackUrlFailedResponse("Unknown Error"))(PPNSCallBackUrlFailedResponse)
).recover {
case NonFatal(e) => throw new RuntimeException(s"Unexpected response from $externalServiceUri: ${e.getMessage}")
}
}
}
Original file line number Diff line number Diff line change
@@ -16,11 +16,15 @@

package uk.gov.hmrc.apisubscriptionfields.service


import uk.gov.hmrc.apisubscriptionfields.connector.PushPullNotificationServiceConnector
import javax.inject.{Inject, Singleton}
import uk.gov.hmrc.apisubscriptionfields.model.FieldDefinition
import uk.gov.hmrc.apisubscriptionfields.model.Types.FieldValue

import scala.concurrent.Future
import uk.gov.hmrc.apisubscriptionfields.model._

import scala.concurrent.ExecutionContext
import uk.gov.hmrc.http.HeaderCarrier

@@ -34,12 +38,15 @@ class PushPullNotificationService @Inject()(ppnsConnector: PushPullNotificationS
def subscribeToPPNS(clientId: ClientId,
apiContext: ApiContext,
apiVersion: ApiVersion,
callBackUrl: String,
oFieldValue: Option[FieldValue],
fieldDefinition: FieldDefinition)
(implicit hc: HeaderCarrier): Future[PPNSCallBackUrlValidationResponse] = {
for {
boxId <- ppnsConnector.ensureBoxIsCreated(makeBoxName(apiContext, apiVersion, fieldDefinition), clientId)
result <- ppnsConnector.updateCallBackUrl(clientId, boxId, callBackUrl)
result <- oFieldValue match {
case Some(value) => ppnsConnector.updateCallBackUrl (clientId, boxId, value)
case None => Future.successful(PPNSCallBackUrlSuccessResponse)
}
} yield result
}

Original file line number Diff line number Diff line change
@@ -68,12 +68,8 @@ class SubscriptionFieldsService @Inject() (

ppnsFieldDefinition match {
case Some(fieldDefinition) =>
val callBackUrl: Option[FieldValue] = fields.get(fieldDefinition.name)
val callBackResponse: Future[PPNSCallBackUrlValidationResponse] = callBackUrl match {
case Some(fieldValue) => pushPullNotificationService.subscribeToPPNS(clientId, apiContext, apiVersion, fieldValue, fieldDefinition)
case None => Future.successful(PPNSCallBackUrlSuccessResponse)
}
callBackResponse.flatMap {
val oFieldValue: Option[FieldValue] = fields.get(fieldDefinition.name).filterNot(_.isEmpty)
pushPullNotificationService.subscribeToPPNS(clientId, apiContext, apiVersion, oFieldValue, fieldDefinition).flatMap {
case PPNSCallBackUrlSuccessResponse => upsertSubscriptionFields(clientId, apiContext, apiVersion, fields)
case PPNSCallBackUrlFailedResponse(error) => Future.successful(FailedValidationSubsFieldsUpsertResponse(Map(fieldDefinition.name -> error)))
}
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ package uk.gov.hmrc.apisubscriptionfields.connector

import java.{util => ju}

import akka.stream.Materializer
import org.scalatest.BeforeAndAfterEach
import org.scalatestplus.play.guice.GuiceOneAppPerSuite
import play.api.Application
@@ -49,7 +50,7 @@ class PushPullNotificationServiceConnectorSpec
.configure(("microservice.services.push-pull-notification.uri", s"http://$stubHost:$stubPort"))
.build()

implicit lazy val materializer = app.materializer
implicit lazy val materializer: Materializer = app.materializer

// Run wiremock server on local machine with specified port.
private val wireMockServer = new WireMockServer(wireMockConfig().port(stubPort))
@@ -70,11 +71,11 @@ class PushPullNotificationServiceConnectorSpec
trait Setup {

val boxName = "box-name"
val clientId = ClientId("client-id")
val subscriptionFieldsId = SubscriptionFieldsId(ju.UUID.randomUUID)
val boxId = BoxId(ju.UUID.randomUUID())
val clientId: ClientId = ClientId("client-id")
val subscriptionFieldsId: SubscriptionFieldsId = SubscriptionFieldsId(ju.UUID.randomUUID)
val boxId: BoxId = BoxId(ju.UUID.randomUUID())

val connector = app.injector.instanceOf[PushPullNotificationServiceConnector]
val connector: PushPullNotificationServiceConnector = app.injector.instanceOf[PushPullNotificationServiceConnector]

def primeStub(path: String, requestBody: String, responseBody: String){
wireMockServer.stubFor(
@@ -97,27 +98,27 @@ class PushPullNotificationServiceConnectorSpec

"PPNS Connector" should {
"send proper request to post box" in new Setup {
val requestBody = Json.stringify(Json.toJson(CreateBoxRequest(boxName, clientId)))
val responseBody = Json.stringify(Json.toJson(CreateBoxResponse(boxId)))
val requestBody: String = Json.stringify(Json.toJson(CreateBoxRequest(boxName, clientId)))
val responseBody: String = Json.stringify(Json.toJson(CreateBoxResponse(boxId)))

val path = "/box"
primeStub(path, requestBody, responseBody)

val ret = await(connector.ensureBoxIsCreated(boxName, clientId))
ret shouldBe (boxId)
val ret: BoxId = await(connector.ensureBoxIsCreated(boxName, clientId))
ret shouldBe boxId

verifyMock(path)
}

"send proper request to subscribe" in new Setup {
val callbackUrl = "my-callback"
val requestBody = Json.stringify(Json.toJson(UpdateSubscriberRequest(SubscriberRequest(callbackUrl, "API_PUSH_SUBSCRIBER"))))
val responseBody = Json.stringify(Json.toJson(UpdateSubscriberResponse(boxId)))
val requestBody: String = Json.stringify(Json.toJson(UpdateSubscriberRequest(SubscriberRequest(callbackUrl, "API_PUSH_SUBSCRIBER"))))
val responseBody: String = Json.stringify(Json.toJson(UpdateSubscriberResponse(boxId)))

val path = s"/box/${boxId.value}/subscriber"
primeStub(path, requestBody, responseBody)

val ret = await(connector.subscribe(boxId, callbackUrl))
val ret: Unit = await(connector.subscribe(boxId, callbackUrl))
ret shouldBe ()

verifyMock(path)
@@ -127,8 +128,8 @@ class PushPullNotificationServiceConnectorSpec

"send proper request to update callback and map response on success" in new Setup {
val callbackUrl = "my-callback"
val requestBody = Json.stringify(Json.toJson(UpdateCallBackUrlRequest(clientId, callbackUrl)))
val responseBody = Json.stringify(Json.toJson(UpdateCallBackUrlResponse(true, None)))
val requestBody: String = Json.stringify(Json.toJson(UpdateCallBackUrlRequest(clientId, callbackUrl)))
val responseBody: String = Json.stringify(Json.toJson(UpdateCallBackUrlResponse(successful = true, None)))

val path = s"/box/${boxId.value}/callback"
primeStub(path, requestBody, responseBody)
@@ -142,8 +143,8 @@ class PushPullNotificationServiceConnectorSpec

"send proper request to update callback and map response on failure" in new Setup {
val callbackUrl = "my-callback"
val requestBody = Json.stringify(Json.toJson( UpdateCallBackUrlRequest(clientId, callbackUrl)))
val responseBody = Json.stringify(Json.toJson(UpdateCallBackUrlResponse(false, Some("some error"))))
val requestBody: String = Json.stringify(Json.toJson( UpdateCallBackUrlRequest(clientId, callbackUrl)))
val responseBody: String = Json.stringify(Json.toJson(UpdateCallBackUrlResponse(successful = false, Some("some error"))))

val path = s"/box/${boxId.value}/callback"
primeStub(path, requestBody, responseBody)
@@ -156,8 +157,8 @@ class PushPullNotificationServiceConnectorSpec

"send proper request to update callback and map response on failure with Unknown Error" in new Setup {
val callbackUrl = "my-callback"
val requestBody = Json.stringify(Json.toJson(UpdateCallBackUrlRequest(clientId, callbackUrl)))
val responseBody = Json.stringify(Json.toJson(UpdateCallBackUrlResponse(false, None)))
val requestBody: String = Json.stringify(Json.toJson(UpdateCallBackUrlRequest(clientId, callbackUrl)))
val responseBody: String = Json.stringify(Json.toJson(UpdateCallBackUrlResponse(successful = false, None)))

val path = s"/box/${boxId.value}/callback"
primeStub(path, requestBody, responseBody)
Original file line number Diff line number Diff line change
@@ -35,7 +35,7 @@ class PushPullNotificationServiceSpec extends AsyncHmrcSpec with SubscriptionFie
val apiVersion: ApiVersion = ApiVersion("aVersion")

trait Setup {
val mockPPNSConnector = mock[PushPullNotificationServiceConnector]
val mockPPNSConnector: PushPullNotificationServiceConnector = mock[PushPullNotificationServiceConnector]

implicit val hc: HeaderCarrier = HeaderCarrier()

@@ -45,30 +45,42 @@ class PushPullNotificationServiceSpec extends AsyncHmrcSpec with SubscriptionFie
"subscribing to PPNS" should {
val ppnsFieldName = fieldN(1)
val callbackUrl = "123"
val oCallbackUrl = Some(callbackUrl)
val ppnsFieldDefinition = FieldDefinition(ppnsFieldName, "description-1", "hint-1", PPNS_FIELD, "short-description-1" )
val fieldDef2 = FieldDefinition(fieldN(2), "description-2", "hint-2", STRING, "short-description-2" )
val fieldDefns: NEL[FieldDefinition] = NEL.of(ppnsFieldDefinition, fieldDef2)
val fields: Types.Fields = Map(fieldN(1) -> callbackUrl, fieldN(2) -> "something else")
val expectedTopicName = s"${apiContext.value}##${apiVersion.value}##${ppnsFieldName}"
val fields: Types.Fields = Map(fieldN(1) -> oCallbackUrl.value, fieldN(2) -> "something else")
val expectedTopicName = s"${apiContext.value}##${apiVersion.value}##$ppnsFieldName"


"succeed and return PPNSCallBackUrlSuccessResponse when update of callback URL is successful" in new Setup {
when(mockPPNSConnector.ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)).thenReturn(successful(boxId))
when(mockPPNSConnector.updateCallBackUrl(clientId, boxId, callbackUrl)(hc)).thenReturn(successful(PPNSCallBackUrlSuccessResponse))

val result: PPNSCallBackUrlValidationResponse = await(service.subscribeToPPNS(clientId, apiContext, apiVersion, callbackUrl, ppnsFieldDefinition))
val result: PPNSCallBackUrlValidationResponse = await(service.subscribeToPPNS(clientId, apiContext, apiVersion, oCallbackUrl, ppnsFieldDefinition))

result shouldBe PPNSCallBackUrlSuccessResponse
verify(mockPPNSConnector).ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)
verify(mockPPNSConnector).updateCallBackUrl(eqTo(clientId), eqTo(boxId), eqTo(callbackUrl))(*)
}

"succeed and return PPNSCallBackUrlSuccessResponse but not call updatecallBackUrl when field is empty" in new Setup {
when(mockPPNSConnector.ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)).thenReturn(successful(boxId))


val result: PPNSCallBackUrlValidationResponse = await(service.subscribeToPPNS(clientId, apiContext, apiVersion, None, ppnsFieldDefinition))

result shouldBe PPNSCallBackUrlSuccessResponse
verify(mockPPNSConnector).ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)
verify(mockPPNSConnector, times(0)).updateCallBackUrl(eqTo(clientId), eqTo(boxId), eqTo(callbackUrl))(*)
}

"return PPNSCallBackUrlFailedResponse when update of callback URL fails" in new Setup {
val errorMessage = "Error Message"
when(mockPPNSConnector.ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)).thenReturn(successful(boxId))
when(mockPPNSConnector.updateCallBackUrl(clientId, boxId, callbackUrl)(hc)).thenReturn(successful(PPNSCallBackUrlFailedResponse(errorMessage)))

val result: PPNSCallBackUrlValidationResponse = await(service.subscribeToPPNS(clientId, apiContext, apiVersion, callbackUrl, ppnsFieldDefinition))
val result: PPNSCallBackUrlValidationResponse = await(service.subscribeToPPNS(clientId, apiContext, apiVersion, oCallbackUrl, ppnsFieldDefinition))

result shouldBe PPNSCallBackUrlFailedResponse(errorMessage)
verify(mockPPNSConnector).ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)
@@ -79,7 +91,7 @@ class PushPullNotificationServiceSpec extends AsyncHmrcSpec with SubscriptionFie
when(mockPPNSConnector.ensureBoxIsCreated(eqTo(expectedTopicName), eqTo(clientId))(*)).thenReturn(failed(new RuntimeException))

intercept[RuntimeException] {
await(service.subscribeToPPNS(clientId, apiContext, apiVersion, callbackUrl, ppnsFieldDefinition))
await(service.subscribeToPPNS(clientId, apiContext, apiVersion, oCallbackUrl, ppnsFieldDefinition))
}
}

@@ -88,7 +100,7 @@ class PushPullNotificationServiceSpec extends AsyncHmrcSpec with SubscriptionFie
when(mockPPNSConnector.updateCallBackUrl(clientId, boxId, callbackUrl)(hc)).thenReturn(failed(new RuntimeException))

intercept[RuntimeException] {
await(service.subscribeToPPNS(clientId, apiContext, apiVersion, callbackUrl, ppnsFieldDefinition))
await(service.subscribeToPPNS(clientId, apiContext, apiVersion, oCallbackUrl, ppnsFieldDefinition))
}
}
}
Original file line number Diff line number Diff line change
@@ -16,24 +16,25 @@

package uk.gov.hmrc.apisubscriptionfields.service

import java.{util=>ju}
import java.{util => ju}

import cats.data.NonEmptyList
import uk.gov.hmrc.apisubscriptionfields.model.Types.FieldErrorMap
import uk.gov.hmrc.apisubscriptionfields.model._
import uk.gov.hmrc.apisubscriptionfields.repository._
import uk.gov.hmrc.apisubscriptionfields.{FieldDefinitionTestData, SubscriptionFieldsTestData}
import uk.gov.hmrc.apisubscriptionfields.AsyncHmrcSpec
import cats.data.NonEmptyList
import scala.concurrent.Future.{successful,failed}
import uk.gov.hmrc.apisubscriptionfields.{AsyncHmrcSpec, FieldDefinitionTestData, SubscriptionFieldsTestData}
import uk.gov.hmrc.http.HeaderCarrier
import scala.concurrent.Future

import scala.concurrent.Future.{failed, successful}

class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionFieldsTestData with FieldDefinitionTestData {

trait Setup {
val mockSubscriptionFieldsRepository = mock[SubscriptionFieldsMongoRepository]
val mockApiFieldDefinitionsService = mock[ApiFieldDefinitionsService]
val mockPushPullNotificationService = mock[PushPullNotificationService](org.mockito.Mockito.withSettings().verboseLogging())
val mockSubscriptionFieldsRepository: SubscriptionFieldsMongoRepository = mock[SubscriptionFieldsMongoRepository]
val mockApiFieldDefinitionsService: ApiFieldDefinitionsService = mock[ApiFieldDefinitionsService]
val mockPushPullNotificationService: PushPullNotificationService = mock[PushPullNotificationService](org.mockito.Mockito.withSettings().verboseLogging())

val mockUuidCreator = new UUIDCreator {
val mockUuidCreator: UUIDCreator = new UUIDCreator {
override def uuid(): ju.UUID = FakeRawFieldsId
}

@@ -57,7 +58,7 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField

when(mockSubscriptionFieldsRepository.fetchAll).thenReturn(successful(List(sf1, sf2)))

val expectedResponse = BulkSubscriptionFieldsResponse(subscriptions =
val expectedResponse: BulkSubscriptionFieldsResponse = BulkSubscriptionFieldsResponse(subscriptions =
List(
SubscriptionFields(sf1.clientId, sf1.apiContext, sf1.apiVersion, sf1.fieldsId, sf1.fields),
SubscriptionFields(sf2.clientId, sf2.apiContext, sf2.apiVersion, sf2.fieldsId, sf2.fields)
@@ -76,11 +77,11 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
}

"return the expected response when the entry exists in the database collection" in new Setup {
val sf1 = createSubscriptionFieldsWithApiContext()
val sf2 = createSubscriptionFieldsWithApiContext(rawContext = fakeRawContext2)
val sf1: SubscriptionFields = createSubscriptionFieldsWithApiContext()
val sf2: SubscriptionFields = createSubscriptionFieldsWithApiContext(rawContext = fakeRawContext2)
when(mockSubscriptionFieldsRepository.fetchByClientId(FakeClientId)).thenReturn(successful(List(sf1, sf2)))

val result = await(service.getByClientId(FakeClientId))
val result: Option[BulkSubscriptionFieldsResponse] = await(service.getByClientId(FakeClientId))

result shouldBe Some(
BulkSubscriptionFieldsResponse(subscriptions =
@@ -103,7 +104,7 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
"return the expected response when the entry exists in the database collection" in new Setup {
when(mockSubscriptionFieldsRepository.fetch(FakeClientId, FakeContext, FakeVersion)).thenReturn(successful(Some(FakeApiSubscription)))

val result = await(service.get(FakeClientId, FakeContext, FakeVersion))
val result: Option[SubscriptionFields] = await(service.get(FakeClientId, FakeContext, FakeVersion))

result shouldBe Some(FakeSubscriptionFieldsResponse)
}
@@ -133,9 +134,9 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
when(mockApiFieldDefinitionsService.get(FakeContext, FakeVersion)).thenReturn(successful(Some(FakeApiFieldDefinitionsResponseWithRegex)))
when(mockSubscriptionFieldsRepository.saveAtomic(*)).thenReturn(successful((subscriptionFields, false)))

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))

result shouldBe (SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), false))
result shouldBe SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), isInsert = false)
verifyZeroInteractions(mockPushPullNotificationService)
verify(mockSubscriptionFieldsRepository).saveAtomic(*)
}
@@ -146,9 +147,9 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
.thenReturn(ppnsSuccessResponse)
when(mockSubscriptionFieldsRepository.saveAtomic(*)).thenReturn(successful((subscriptionFields, false)))

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidationPPNS))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidationPPNS))

result shouldBe (SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), false))
result shouldBe SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), isInsert = false)

verify(mockPushPullNotificationService).subscribeToPPNS(eqTo(FakeClientId), eqTo(FakeContext), eqTo(FakeVersion), any, any[FieldDefinition])(any)
verify(mockSubscriptionFieldsRepository).saveAtomic(*)
@@ -160,32 +161,35 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
.thenReturn(ppnsSuccessResponse)
when(mockSubscriptionFieldsRepository.saveAtomic(*)).thenReturn(successful((subscriptionFields, false)))

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsEmptyValueRegexValidationPPNS))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsEmptyValueRegexValidationPPNS))

result shouldBe (SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), false))
result shouldBe SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), isInsert = false)

verify(mockPushPullNotificationService).subscribeToPPNS(eqTo(FakeClientId), eqTo(FakeContext), eqTo(FakeVersion), any, any[FieldDefinition])(any)
verify(mockSubscriptionFieldsRepository).saveAtomic(*)
}

"return PPNSCallBackUrlSuccessResponse when updating an existing api subscription field for PPNS is not included" in new Setup {
when(mockApiFieldDefinitionsService.get(FakeContext, FakeVersion)).thenReturn(successful(Some(FakeApiFieldDefinitionsResponsePPNSWithRegex)))
when(mockPushPullNotificationService.subscribeToPPNS(eqTo(FakeClientId), eqTo(FakeContext), eqTo(FakeVersion), any, any[FieldDefinition])(any))
.thenReturn(ppnsSuccessResponse)
when(mockSubscriptionFieldsRepository.saveAtomic(*)).thenReturn(successful((subscriptionFields, false)))

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))

result shouldBe (SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), false))
result shouldBe SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), isInsert = false)

verify(mockPushPullNotificationService).subscribeToPPNS(eqTo(FakeClientId), eqTo(FakeContext), eqTo(FakeVersion), any, any[FieldDefinition])(any)
verify(mockSubscriptionFieldsRepository).saveAtomic(*)
verifyZeroInteractions(mockPushPullNotificationService)

}

"return FailedValidationSubsFieldsUpsertResponse when updating an existing api subscription fields and PPNS service returns failure" in new Setup {
when(mockApiFieldDefinitionsService.get(FakeContext, FakeVersion)).thenReturn(successful(Some(FakeApiFieldDefinitionsResponsePPNSWithRegex)))
when(mockPushPullNotificationService.subscribeToPPNS(eqTo(FakeClientId), eqTo(FakeContext), eqTo(FakeVersion), any, any[FieldDefinition])(any))
.thenReturn(ppnsFailureResponse)

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidationPPNS))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidationPPNS))

result shouldBe FailedValidationSubsFieldsUpsertResponse(Map(PPNSFieldFieldName -> "An Error Occurred"))

@@ -196,7 +200,7 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
"return FailedValidationSubsFieldsUpsertResponse when updating an existing api subscription fields and PPNS field fails validation" in new Setup {
when(mockApiFieldDefinitionsService.get(FakeContext, FakeVersion)).thenReturn(successful(Some(FakeApiFieldDefinitionsResponsePPNSWithRegex)))

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsDoNotMatchRegexValidationPPNS))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsDoNotMatchRegexValidationPPNS))

result shouldBe FailedValidationSubsFieldsUpsertResponse(Map(PPNSFieldFieldName -> "CallBackUrl Validation"))

@@ -209,17 +213,17 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField

when(mockSubscriptionFieldsRepository.saveAtomic(*)).thenReturn(successful((subscriptionFields, true)))

val result = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))
val result: SubsFieldsUpsertResponse = await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))

result shouldBe (SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), true))
result shouldBe SuccessfulSubsFieldsUpsertResponse(SubscriptionFields(FakeClientId, FakeContext, FakeVersion, FakeFieldsId, fields), isInsert = true)
verifyZeroInteractions(mockPushPullNotificationService)
}

"propagate the error" in new Setup {
when(mockApiFieldDefinitionsService.get(FakeContext, FakeVersion)).thenReturn(successful(Some(FakeApiFieldDefinitionsResponseWithRegex)))
when(mockSubscriptionFieldsRepository.saveAtomic(*)).thenReturn(failed(emulatedFailure))

val caught = intercept[EmulatedFailure] {
val caught: EmulatedFailure = intercept[EmulatedFailure] {
await(service.upsert(FakeClientId, FakeContext, FakeVersion, SubscriptionFieldsMatchRegexValidation))
}

@@ -285,18 +289,19 @@ class SubscriptionFieldsServiceSpec extends AsyncHmrcSpec with SubscriptionField
}

"validate Field Names Are Defined" should {
val fieldDefintionWithoutValidation = FieldDefinition(fieldN(1), "desc1", "hint1", FieldDefinitionType.URL, "short description", None)
val fieldDefinitionWithoutValidation = FieldDefinition(fieldN(1), "desc1", "hint1", FieldDefinitionType.URL, "short description", None)
val fields = Map(fieldN(1) -> "Emily")

"succeed when Fields match Field Definitions" in new Setup {
SubscriptionFieldsService.validateFieldNamesAreDefined(NonEmptyList.one(fieldDefintionWithoutValidation), fields) shouldBe empty
SubscriptionFieldsService.validateFieldNamesAreDefined(NonEmptyList.one(fieldDefinitionWithoutValidation), fields) shouldBe empty
}

"fail when when Fields are not present in the Field Definitions" in new Setup {
val errs = SubscriptionFieldsService.validateFieldNamesAreDefined(NonEmptyList.one(fieldDefintionWithoutValidation), Map(fieldN(5) -> "Bob", fieldN(1) -> "Fred"))
val errs: FieldErrorMap =
SubscriptionFieldsService.validateFieldNamesAreDefined(NonEmptyList.one(fieldDefinitionWithoutValidation), Map(fieldN(5) -> "Bob", fieldN(1) -> "Fred"))
errs should not be empty
errs.head match {
case (name, msg) if name == fieldN(5)=> succeed
case (name, _) if name == fieldN(5)=> succeed
case _ => fail("Not the field we expected")
}
}

0 comments on commit 79bd5c6

Please sign in to comment.