diff --git a/.scalafmt.conf b/.scalafmt.conf index 7a1aff6..1a13616 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,19 +1,39 @@ version="3.5.3" -runner.dialect = "scala212" +runner.dialect = "scala213" maxColumn = 180 assumeStandardLibraryStripMargin = true align.stripMargin = true + align.preset = most align.multiline = true + indent.extendSite = 4 indent.defnSite = 4 + align.arrowEnumeratorGenerator = true + align.closeParenSite = true align.openParenCallSite = false align.openParenDefnSite = false align.openParenCtrlSite = false + danglingParentheses.defnSite = true danglingParentheses.callSite = true -danglingParentheses.exclude = [] \ No newline at end of file +danglingParentheses.exclude = [] + +newlines.source = keep +newlines.topLevelStatements = [before] +newlines.alwaysBeforeMultilineDef = false +newlines.implicitParamListModifierPrefer = before +# newlines.implicitParamListModifierForce = [before] +newlines.avoidForSimpleOverflow = [tooLong, punct, slc] + +rewrite.rules = [SortModifiers] +rewrite.imports.sort = ascii + +verticalMultiline.atDefnSite = true +verticalMultiline.newlineAfterOpenParen = true + +includeNoParensInSelectChains = true \ No newline at end of file diff --git a/acceptance/uk/gov/hmrc/apisubscriptionfields/AcceptanceTestSpec.scala b/acceptance/uk/gov/hmrc/apisubscriptionfields/AcceptanceTestSpec.scala index 88ab055..23ea54e 100644 --- a/acceptance/uk/gov/hmrc/apisubscriptionfields/AcceptanceTestSpec.scala +++ b/acceptance/uk/gov/hmrc/apisubscriptionfields/AcceptanceTestSpec.scala @@ -17,7 +17,6 @@ package uk.gov.hmrc.apisubscriptionfields import java.util.UUID -import org.scalatest._ import org.scalatestplus.play.guice.GuiceOneServerPerSuite import play.api.Application import play.api.inject.guice.GuiceApplicationBuilder @@ -35,7 +34,12 @@ import cats.data.NonEmptyList import uk.gov.hmrc.apisubscriptionfields.controller.Helper import uk.gov.hmrc.mongo.MongoComponent -trait AcceptanceTestSpec extends FeatureSpec +import org.scalatest.matchers.should.Matchers +import org.scalatest.GivenWhenThen +import org.scalatest.BeforeAndAfterAll +import org.scalatest.featurespec.AnyFeatureSpec + +trait AcceptanceTestSpec extends AnyFeatureSpec with GivenWhenThen with BeforeAndAfterAll with Matchers @@ -87,12 +91,16 @@ trait AcceptanceTestSpec extends FeatureSpec protected def await[A](future: Future[A]): A = Await.result(future, 5.seconds) - override protected def beforeAll: Unit = { + override protected def beforeAll(): Unit = { + super.beforeAll() + dropDatabase() } - override protected def afterAll: Unit = { + override protected def afterAll(): Unit = { dropDatabase() + + super.afterAll() } private def dropDatabase(): Unit = { diff --git a/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsHappySpec.scala b/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsHappySpec.scala index ce601dd..1140819 100644 --- a/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsHappySpec.scala +++ b/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsHappySpec.scala @@ -37,34 +37,38 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec with BeforeAndAfterAll with ApplicationLogger { - override def beforeAll() { + override def beforeAll(): Unit = { + super.beforeAll() + val putRequest = validDefinitionPutRequest(NelOfFieldDefinitions) .withTarget( RequestTarget(uriString="", path=definitionEndpoint(fakeRawContext, fakeRawVersion), queryString = Map.empty)) Await.result(route(app, putRequest).get, 10.seconds) } - override def afterAll() { + override def afterAll(): Unit = { val request = ValidRequest .withMethod(DELETE) .withTarget( RequestTarget(uriString="", path=definitionEndpoint(fakeRawContext, fakeRawVersion), queryString = Map.empty)) route(app, request) + + super.afterAll() } - feature("Subscription-Fields") { + Feature("Subscription-Fields") { appLogger.logger.info(s"App.mode = ${app.mode.toString}") - scenario("the API is called to store some values for a new subscription field") { + Scenario("the API is called to store some values for a new subscription field") { val request: Request[AnyContentAsJson] = createSubscriptionFieldsRequest() When("a PUT request with data is sent to the API") val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 201 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe CREATED @@ -86,7 +90,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec route(app, createSubscriptionFieldsRequest()) } - scenario("the API is called to GET some existing subscription fields") { + Scenario("the API is called to GET some existing subscription fields") { Given("a request with a known subscription field") createSubscriptionFields() @@ -97,7 +101,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -110,7 +114,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec sfr.get shouldBe SubscriptionFields(FakeClientId, ApiContext("acontext"), ApiVersion("1.0.2"), fieldsId, SampleFields1) } - scenario("the API is called to GET all existing subscription fields") { + Scenario("the API is called to GET all existing subscription fields") { Given("a request with a known subscription field") createSubscriptionFields() @@ -121,7 +125,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -134,7 +138,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec sfr.get shouldBe BulkSubscriptionFieldsResponse(Seq(SubscriptionFields(FakeClientId, ApiContext("acontext"), ApiVersion("1.0.2"), fieldsId, SampleFields1))) } - scenario("the API is called to GET with a known fieldsId") { + Scenario("the API is called to GET with a known fieldsId") { Given("a request with a known fieldsId") @@ -146,7 +150,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, requestId) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -164,7 +168,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val resultFieldsId: Option[Future[Result]] = route(app, requestFieldsId) Then(s"a response with a 200 status is received") - resultFieldsId shouldBe 'defined + resultFieldsId shouldBe defined val resultFieldsIdFuture = result.value status(resultFieldsIdFuture) shouldBe OK @@ -174,7 +178,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec sfrFieldsId.get shouldBe SubscriptionFields(FakeClientId, ApiContext("acontext"), ApiVersion("1.0.2"), fieldsId, SampleFields1) } - scenario("the API is called to GET existing subscription fields by application clientId") { + Scenario("the API is called to GET existing subscription fields by application clientId") { Given("a request with a known client identifier") createSubscriptionFields() @@ -185,7 +189,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value @@ -199,7 +203,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec sfr.get shouldBe BulkSubscriptionFieldsResponse(Seq(SubscriptionFields(FakeClientId, ApiContext("acontext"), ApiVersion("1.0.2"), fieldsId, SampleFields1))) } - scenario("the API is called to update existing subscription fields") { + Scenario("the API is called to update existing subscription fields") { Given("a request with valid payload") createSubscriptionFields() @@ -210,7 +214,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -223,7 +227,7 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec sfr.get shouldBe SubscriptionFields(FakeClientId, ApiContext("acontext"), ApiVersion("1.0.2"), fieldsId, SampleFields2) } - scenario("the API is called to DELETE existing subscription fields") { + Scenario("the API is called to DELETE existing subscription fields") { Given("a request with existing subscription fields") createSubscriptionFields() @@ -234,13 +238,13 @@ class ApiSubscriptionFieldsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 204 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NO_CONTENT And("the response body is empty") - contentAsString(resultFuture) shouldBe 'empty + contentAsString(resultFuture) shouldBe empty } } diff --git a/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsUnhappySpec.scala b/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsUnhappySpec.scala index 6cc713c..71fe4d9 100644 --- a/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsUnhappySpec.scala +++ b/acceptance/uk/gov/hmrc/apisubscriptionfields/ApiSubscriptionFieldsUnhappySpec.scala @@ -31,10 +31,10 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec with SubscriptionFieldsTestData with ApplicationLogger { - feature("Subscription-Fields") { + Feature("Subscription-Fields") { appLogger.logger.info(s"App.mode = ${app.mode.toString}") - scenario("the API is called to GET non-existing subscription fields") { + Scenario("the API is called to GET non-existing subscription fields") { Given("the API is called to GET non-existing subscription fields") val request = createRequest(GET, subscriptionFieldsEndpoint(fakeRawClientId, fakeRawContext, fakeRawVersion)) @@ -42,7 +42,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 404 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NOT_FOUND @@ -51,7 +51,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(NOT_FOUND_CODE, s"Subscription fields not found for ($fakeRawClientId, $fakeRawContext, $fakeRawVersion)") } - scenario("the API is called to GET with an unknown fieldsId") { + Scenario("the API is called to GET with an unknown fieldsId") { Given("the API is called to GET with an unknown fieldsId") val request = createRequest(GET, fieldsIdEndpoint(FakeRawFieldsId)) @@ -60,7 +60,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 404 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NOT_FOUND @@ -69,7 +69,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(NOT_FOUND_CODE, s"FieldsId (${FakeRawFieldsId.toString}) was not found") } - scenario("the API is called to GET an unknown application clientId") { + Scenario("the API is called to GET an unknown application clientId") { Given("the API is called to GET an unknown application clientId") val request = createRequest(GET, byClientIdEndpoint(fakeRawClientId)) @@ -78,7 +78,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 404 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NOT_FOUND @@ -87,7 +87,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(NOT_FOUND_CODE, s"ClientId ($fakeRawClientId) was not found") } - scenario("the API is called to DELETE an unknown subscription field") { + Scenario("the API is called to DELETE an unknown subscription field") { Given("a request with an unknown subscription field") val request = createRequest(DELETE, subscriptionFieldsEndpoint(fakeRawClientId, fakeRawContext, fakeRawVersion)) @@ -96,7 +96,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 404 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NOT_FOUND @@ -105,7 +105,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(NOT_FOUND_CODE, s"Subscription fields not found for ($fakeRawClientId, $fakeRawContext, $fakeRawVersion)") } - scenario("the API is called to PUT subscription fields with an invalid JSON payload") { + Scenario("the API is called to PUT subscription fields with an invalid JSON payload") { Given("the API is called to PUT subscription fields with an invalid JSON payload") val request = createRequest(PUT, subscriptionFieldsEndpoint(fakeRawClientId, fakeRawContext, fakeRawVersion)) @@ -115,7 +115,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 422 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe UNPROCESSABLE_ENTITY @@ -124,7 +124,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(INVALID_REQUEST_PAYLOAD, _: Json.JsValueWrapper) } - scenario("the API is called to PUT subscription fields with an invalid non JSON payload") { + Scenario("the API is called to PUT subscription fields with an invalid non JSON payload") { Given("the API is called to PUT subscription fields with an invalid non JSON payload") val request = createRequest(PUT, subscriptionFieldsEndpoint(fakeRawClientId, fakeRawContext, fakeRawVersion)) @@ -134,7 +134,7 @@ class ApiSubscriptionFieldsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 415 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe UNSUPPORTED_MEDIA_TYPE diff --git a/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsHappySpec.scala b/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsHappySpec.scala index d5e24e1..5ef543c 100644 --- a/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsHappySpec.scala +++ b/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsHappySpec.scala @@ -30,10 +30,10 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec with JsonFormatters { - feature("Fields-Definition") { + Feature("Fields-Definition") { - scenario("the API is called to store some new fields definitions") { + Scenario("the API is called to store some new fields definitions") { Given("Definitiions are created ") val putRequest = validDefinitionPutRequest(NelOfFieldDefinitions) .withTarget( RequestTarget(uriString="", path=definitionEndpoint(fakeRawContext, fakeRawVersion), queryString = Map.empty)) @@ -42,7 +42,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec val putResult: Option[Future[Result]] = route(app, putRequest) Then(s"a response with a 201 status is received") - putResult shouldBe 'defined + putResult shouldBe defined val putResultFuture = putResult.value status(putResultFuture) shouldBe CREATED @@ -57,7 +57,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec - scenario("the API is called to GET a known fields definition") { + Scenario("the API is called to GET a known fields definition") { Then("a request with a known fields definition") val request = ValidRequest @@ -68,7 +68,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -80,7 +80,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec fdr.get shouldBe FakeApiFieldDefinitionsResponse } - scenario("the API is called to GET all fields definitions") { + Scenario("the API is called to GET all fields definitions") { Given("a request for all fields definition") val request = ValidRequest @@ -91,7 +91,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -103,7 +103,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec allFdr.get shouldBe BulkApiFieldDefinitionsResponse(List(FakeApiFieldDefinitionsResponse)) } - scenario("the API is called to update some existing fields definitions") { + Scenario("the API is called to update some existing fields definitions") { Given("a request with valid payload") val request = validDefinitionPutRequest(NelOfFieldDefinitions) @@ -113,7 +113,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 200 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe OK @@ -124,7 +124,7 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec sfr.get shouldBe ApiFieldDefinitions(FakeContext, FakeVersion, NelOfFieldDefinitions) } - scenario("the API is called to delete some existing fields definitions") { + Scenario("the API is called to delete some existing fields definitions") { Given("a request with valid payload") val request = ValidRequest @@ -135,13 +135,13 @@ class SubscriptionFieldDefinitionsHappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 204 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NO_CONTENT And("the response body is empty") - contentAsString(resultFuture) shouldBe 'empty + contentAsString(resultFuture) shouldBe Symbol("empty") } } diff --git a/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsUnhappySpec.scala b/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsUnhappySpec.scala index 66aa264..05114c1 100644 --- a/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsUnhappySpec.scala +++ b/acceptance/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldDefinitionsUnhappySpec.scala @@ -30,8 +30,8 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec with OptionValues with SubscriptionFieldsTestData { - feature("Fields-Definition") { - scenario("the API is called to GET an unknown fields definition") { + Feature("Fields-Definition") { + Scenario("the API is called to GET an unknown fields definition") { Given("the API is called to GET an unknown fields definition") val request = ValidRequest.withTarget(RequestTarget(uriString = "", path = definitionEndpoint(fakeRawContext, "unknown"), queryString = Map.empty)) @@ -40,7 +40,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 404 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NOT_FOUND @@ -49,7 +49,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(NOT_FOUND_CODE, s"Fields definition not found for (${FakeContext.value}, unknown)") } - scenario("the API is called to PUT a fields definition with an invalid JSON payload") { + Scenario("the API is called to PUT a fields definition with an invalid JSON payload") { Given("the API is called to PUT a fields definition with an invalid JSON payload") val request = ValidRequest @@ -61,7 +61,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 422 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe UNPROCESSABLE_ENTITY @@ -70,7 +70,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(INVALID_REQUEST_PAYLOAD, _: Json.JsValueWrapper) } - scenario("the API is called to PUT a fields definition with an invalid field definition type") { + Scenario("the API is called to PUT a fields definition with an invalid field definition type") { val invalidFieldDefinition = """{ @@ -96,7 +96,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 422 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe UNPROCESSABLE_ENTITY @@ -105,7 +105,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(INVALID_REQUEST_PAYLOAD, _: Json.JsValueWrapper) } - scenario("the API is called to PUT a fields definition with an invalid non JSON payload") { + Scenario("the API is called to PUT a fields definition with an invalid non JSON payload") { Given("the API is called to PUT a fields definition with an invalid non JSON payload") @@ -118,7 +118,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 415 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe UNSUPPORTED_MEDIA_TYPE @@ -127,7 +127,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec contentAsJson(resultFuture) shouldBe JsErrorResponse(INVALID_REQUEST_PAYLOAD, _: Json.JsValueWrapper) } - scenario("the API is called to DELETE an unknown fields definition") { + Scenario("the API is called to DELETE an unknown fields definition") { Given("a request with an unknown fields definition") @@ -140,7 +140,7 @@ class SubscriptionFieldDefinitionsUnhappySpec extends AcceptanceTestSpec val result: Option[Future[Result]] = route(app, request) Then(s"a response with a 404 status is received") - result shouldBe 'defined + result shouldBe defined val resultFuture = result.value status(resultFuture) shouldBe NOT_FOUND diff --git a/app/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirements.scala b/app/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirements.scala index 4779a13..ae3d979 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirements.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirements.scala @@ -17,6 +17,7 @@ package uk.gov.hmrc.apisubscriptionfields.model sealed trait DevhubAccessRequirement + object DevhubAccessRequirement { final val Default: DevhubAccessRequirement = Anyone @@ -46,6 +47,7 @@ object DevhubAccessRequirements { } case class AccessRequirements(devhub: DevhubAccessRequirements) + object AccessRequirements { final val Default = AccessRequirements(devhub = DevhubAccessRequirements.Default) } @@ -53,11 +55,13 @@ object AccessRequirements { sealed trait DevhubAccessLevel { def satisfiesRequirement(requirement: DevhubAccessRequirement): Boolean = DevhubAccessLevel.satisfies(requirement)(this) } -object DevhubAccessLevel { + +object DevhubAccessLevel { case object Developer extends DevhubAccessLevel case object Admininstator extends DevhubAccessLevel import DevhubAccessRequirement._ + def satisfies(requirement: DevhubAccessRequirement)(actual: DevhubAccessLevel): Boolean = (requirement, actual) match { case (NoOne, _) => false case (AdminOnly, Developer) => false diff --git a/app/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatters.scala b/app/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatters.scala index e33fa37..dd599dd 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatters.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatters.scala @@ -74,6 +74,7 @@ trait AccessRequirementsFormatters { )(DevhubAccessRequirements.apply _) implicit val DevhubAccessRequirementsWrites: OWrites[DevhubAccessRequirements] = new OWrites[DevhubAccessRequirements] { + def writes(requirements: DevhubAccessRequirements) = { Json.obj( ( diff --git a/app/uk/gov/hmrc/apisubscriptionfields/model/Model.scala b/app/uk/gov/hmrc/apisubscriptionfields/model/Model.scala index 61806a4..94ff591 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/model/Model.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/model/Model.scala @@ -23,6 +23,7 @@ import uk.gov.hmrc.apisubscriptionfields.model.FieldDefinitionType.FieldDefiniti import uk.gov.hmrc.apisubscriptionfields.model.Types._ sealed trait ValidationRule { + def validate(value: FieldValue): Boolean = { if (value == "") true else validateAgainstRule(value) @@ -65,7 +66,7 @@ case class FieldDefinition( shortDescription: String, validation: Option[ValidationGroup] = None, access: AccessRequirements = AccessRequirements.Default -) + ) case class ApiFieldDefinitions(apiContext: ApiContext, apiVersion: ApiVersion, fieldDefinitions: NEL[FieldDefinition]) diff --git a/app/uk/gov/hmrc/apisubscriptionfields/model/Responses.scala b/app/uk/gov/hmrc/apisubscriptionfields/model/Responses.scala index daaaff4..cb3371a 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/model/Responses.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/model/Responses.scala @@ -47,6 +47,7 @@ object ErrorCode extends Enumeration { } object JsErrorResponse { + def apply(errorCode: ErrorCode.Value, message: JsValueWrapper): JsObject = Json.obj( "code" -> errorCode.toString, diff --git a/app/uk/gov/hmrc/apisubscriptionfields/model/Types.scala b/app/uk/gov/hmrc/apisubscriptionfields/model/Types.scala index 03c7569..26b268d 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/model/Types.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/model/Types.scala @@ -35,6 +35,7 @@ object Types { type FieldError = (FieldName, ErrorMessage) type FieldErrorMap = Map[FieldName, ErrorMessage] + object FieldErrorMap { val empty = Map.empty[FieldName, ErrorMessage] } diff --git a/app/uk/gov/hmrc/apisubscriptionfields/repository/FieldDefinitionRepository.scala b/app/uk/gov/hmrc/apisubscriptionfields/repository/FieldDefinitionRepository.scala index 9c4fd00..85839c2 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/repository/FieldDefinitionRepository.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/repository/FieldDefinitionRepository.scala @@ -84,7 +84,7 @@ class ApiFieldDefinitionsMongoRepository @Inject() (mongo: MongoComponent)(impli def save(definitions: ApiFieldDefinitions): Future[(ApiFieldDefinitions, IsInsert)] = { val query = and(equal("apiContext", Codecs.toBson(definitions.apiContext.value)), equal("apiVersion", Codecs.toBson(definitions.apiVersion.value))) - collection.find(query).headOption flatMap { + collection.find(query).headOption().flatMap { case Some(_: ApiFieldDefinitions) => for { updatedDefinitions <- collection diff --git a/app/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepository.scala b/app/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepository.scala index 00f3f1f..b7e2ae9 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepository.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepository.scala @@ -109,7 +109,7 @@ class SubscriptionFieldsMongoRepository @Inject() (mongo: MongoComponent, uuidCr equal("apiVersion", Codecs.toBson(apiVersion.value)) ) - collection.find(query).headOption flatMap { + collection.find(query).headOption().flatMap { case Some(subscription: SubscriptionFields) => val updatedSubscription = subscription.copy(fields = fields) for { diff --git a/app/uk/gov/hmrc/apisubscriptionfields/service/PushPullNotificationService.scala b/app/uk/gov/hmrc/apisubscriptionfields/service/PushPullNotificationService.scala index 5ec518b..d5a95b3 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/service/PushPullNotificationService.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/service/PushPullNotificationService.scala @@ -27,14 +27,21 @@ import uk.gov.hmrc.apisubscriptionfields.model.{FieldDefinition, _} @Singleton class PushPullNotificationService @Inject() (ppnsConnector: PushPullNotificationServiceConnector)(implicit ec: ExecutionContext) { + def makeBoxName(apiContext: ApiContext, apiVersion: ApiVersion, fieldDefinition: FieldDefinition): String = { val separator = "##" s"${apiContext.value}${separator}${apiVersion.value}${separator}${fieldDefinition.name.value}" } - def subscribeToPPNS(clientId: ClientId, apiContext: ApiContext, apiVersion: ApiVersion, oFieldValue: Option[FieldValue], fieldDefinition: FieldDefinition)(implicit + def subscribeToPPNS( + clientId: ClientId, + apiContext: ApiContext, + apiVersion: ApiVersion, + oFieldValue: Option[FieldValue], + fieldDefinition: FieldDefinition + )(implicit hc: HeaderCarrier - ): Future[PPNSCallBackUrlValidationResponse] = { + ): Future[PPNSCallBackUrlValidationResponse] = { for { boxId <- ppnsConnector.ensureBoxIsCreated(makeBoxName(apiContext, apiVersion, fieldDefinition), clientId) result <- oFieldValue match { diff --git a/app/uk/gov/hmrc/apisubscriptionfields/service/SubscriptionFieldsService.scala b/app/uk/gov/hmrc/apisubscriptionfields/service/SubscriptionFieldsService.scala index 605ec8b..553f62f 100644 --- a/app/uk/gov/hmrc/apisubscriptionfields/service/SubscriptionFieldsService.scala +++ b/app/uk/gov/hmrc/apisubscriptionfields/service/SubscriptionFieldsService.scala @@ -34,7 +34,8 @@ class SubscriptionFieldsService @Inject() ( repository: SubscriptionFieldsRepository, apiFieldDefinitionsService: ApiFieldDefinitionsService, pushPullNotificationService: PushPullNotificationService -)(implicit ec: ExecutionContext) { + )(implicit ec: ExecutionContext + ) { private def validate(fields: Fields, fieldDefinitions: NonEmptyList[FieldDefinition]): SubsFieldValidationResponse = { SubscriptionFieldsService.validateAgainstValidationRules(fieldDefinitions, fields) ++ SubscriptionFieldsService.validateFieldNamesAreDefined(fieldDefinitions, fields) match { @@ -49,9 +50,15 @@ class SubscriptionFieldsService @Inject() ( .map(result => SuccessfulSubsFieldsUpsertResponse(result._1, result._2)) } - def handlePPNS(clientId: ClientId, apiContext: ApiContext, apiVersion: ApiVersion, fieldDefinitions: NEL[FieldDefinition], fields: Fields)(implicit + def handlePPNS( + clientId: ClientId, + apiContext: ApiContext, + apiVersion: ApiVersion, + fieldDefinitions: NEL[FieldDefinition], + fields: Fields + )(implicit hc: HeaderCarrier - ): Future[SubsFieldsUpsertResponse] = { + ): Future[SubsFieldsUpsertResponse] = { val ppnsFieldDefinition: Option[FieldDefinition] = fieldDefinitions.find(_.`type` == FieldDefinitionType.PPNS_FIELD) ppnsFieldDefinition match { diff --git a/build.sbt b/build.sbt index 22b5aba..9f08ee1 100644 --- a/build.sbt +++ b/build.sbt @@ -28,25 +28,29 @@ import scala.language.postfixOps val appName = "api-subscription-fields" ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.6.0" - -inThisBuild( - List( - scalaVersion := "2.12.15", - semanticdbEnabled := true, - semanticdbVersion := scalafixSemanticdb.revision - ) -) +ThisBuild / semanticdbEnabled := true +ThisBuild / semanticdbVersion := scalafixSemanticdb.revision resolvers ++= Seq( Resolver.sonatypeRepo("releases"), Resolver.sonatypeRepo("snapshots") - ) +) lazy val plugins: Seq[Plugins] = Seq(PlayScala, SbtAutoBuildPlugin, SbtDistributablesPlugin) lazy val playSettings: Seq[Setting[_]] = Seq.empty lazy val AcceptanceTest = config("acceptance") extend Test +lazy val acceptanceTestSettings = + inConfig(AcceptanceTest)(Defaults.testSettings) ++ + inConfig(AcceptanceTest)(BloopDefaults.configSettings) ++ + Seq( + AcceptanceTest / unmanagedSourceDirectories := Seq(baseDirectory.value / "acceptance"), + AcceptanceTest / fork := false, + AcceptanceTest / parallelExecution := false, + addTestReportOption(AcceptanceTest, "acceptance-reports") + ) + lazy val microservice = Project(appName, file(".")) .enablePlugins(plugins: _*) .configs(AcceptanceTest) @@ -56,7 +60,7 @@ lazy val microservice = Project(appName, file(".")) .settings(defaultSettings(): _*) .settings(acceptanceTestSettings: _*) .settings(headerSettings(AcceptanceTest) ++ automateHeaderSettings(AcceptanceTest)) - .settings(scalaVersion := "2.12.15") + .settings(scalaVersion := "2.13.8") .settings(ScoverageSettings()) .settings( routesImport ++= Seq( @@ -74,17 +78,16 @@ lazy val microservice = Project(appName, file(".")) Test / parallelExecution := false ) .settings(majorVersion := 0) - .settings(scalacOptions ++= Seq("-Ypartial-unification")) - -lazy val acceptanceTestSettings = - inConfig(AcceptanceTest)(Defaults.testSettings) ++ - inConfig(AcceptanceTest)(BloopDefaults.configSettings) ++ - Seq( - AcceptanceTest / unmanagedSourceDirectories := Seq(baseDirectory.value / "acceptance"), - AcceptanceTest / fork := false, - AcceptanceTest / parallelExecution := false, - addTestReportOption(AcceptanceTest, "acceptance-reports") + .settings( + scalacOptions ++= Seq( + "-Wconf:cat=unused&src=.*RoutesPrefix\\.scala:s", + "-Wconf:cat=unused&src=.*Routes\\.scala:s", + "-Wconf:cat=unused&src=.*ReverseRoutes\\.scala:s" ) + ) + .settings( + commands += Command.command("testAll") { state => "test" :: "acceptance:test" :: state } + ) def onPackageName(rootPackage: String): String => Boolean = { testName => testName startsWith rootPackage } diff --git a/project/AppDependencies.scala b/project/AppDependencies.scala index cc1f64f..b4d7ab9 100644 --- a/project/AppDependencies.scala +++ b/project/AppDependencies.scala @@ -12,7 +12,7 @@ object AppDependencies { "uk.gov.hmrc.mongo" %% "hmrc-mongo-play-28" % "0.68.0", "org.julienrf" %% "play-json-derived-codecs" % "6.0.0", "com.typesafe.play" %% "play-json" % "2.9.2", - "uk.gov.hmrc" %% "http-metrics" % "2.5.0-play-28", + "uk.gov.hmrc" %% "http-metrics" % "2.7.0", "org.typelevel" %% "cats-core" % "2.6.1", "eu.timepit" %% "refined" % "0.9.13", "be.venneborg" %% "play28-refined" % "0.6.0", @@ -23,7 +23,7 @@ object AppDependencies { private lazy val testDependencies = Seq( "uk.gov.hmrc" %% "bootstrap-test-play-28" % bootstrapVersion, "uk.gov.hmrc.mongo" %% "hmrc-mongo-test-play-28" % "0.68.0", - "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.3", + "org.scalatestplus.play" %% "scalatestplus-play" % "5.1.0", "org.mockito" %% "mockito-scala-scalatest" % "1.16.42", "org.pegdown" % "pegdown" % "1.6.0", "com.typesafe.play" %% "play-test" % play.core.PlayVersion.current, diff --git a/project/plugins.sbt b/project/plugins.sbt index 52f3c1b..ba1a893 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,14 +1,12 @@ resolvers += "HMRC-open-artefacts-maven" at "https://open.artefacts.tax.service.gov.uk/maven2" resolvers += Resolver.url("HMRC-open-artefacts-ivy", url("https://open.artefacts.tax.service.gov.uk/ivy2"))(Resolver.ivyStylePatterns) -resolvers += "Typesafe Releases" at "https://repo.typesafe.com/typesafe/releases/" - -addSbtPlugin("uk.gov.hmrc" %% "sbt-auto-build" % "3.8.0") -addSbtPlugin("uk.gov.hmrc" %% "sbt-distributables" % "2.1.0") -addSbtPlugin("org.scoverage" %% "sbt-scoverage" % "2.0.0") +addSbtPlugin("uk.gov.hmrc" %% "sbt-auto-build" % "3.9.0") +addSbtPlugin("uk.gov.hmrc" %% "sbt-distributables" % "2.2.0") +addSbtPlugin("org.scoverage" %% "sbt-scoverage" % "1.9.3") addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0") addSbtPlugin("com.typesafe.play" %% "sbt-plugin" % "2.8.18") -addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.9") +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.5.6") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.2") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.4") diff --git a/test/uk/gov/hmrc/apisubscriptionfields/AsyncHmrcSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/AsyncHmrcSpec.scala index 13d3427..031104f 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/AsyncHmrcSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/AsyncHmrcSpec.scala @@ -17,11 +17,13 @@ package uk.gov.hmrc.apisubscriptionfields import org.mockito.{ArgumentMatchersSugar, MockitoSugar} -import org.scalatest.{Matchers, OptionValues, WordSpec} +import org.scalatest.OptionValues +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec import org.scalatestplus.play.WsScalaTestClient import play.api.test.{DefaultAwaitTimeout, FutureAwaits} -abstract class HmrcSpec extends WordSpec with Matchers with OptionValues with WsScalaTestClient with MockitoSugar with ArgumentMatchersSugar {} +abstract class HmrcSpec extends AnyWordSpec with Matchers with OptionValues with WsScalaTestClient with MockitoSugar with ArgumentMatchersSugar {} abstract class AsyncHmrcSpec extends HmrcSpec with DefaultAwaitTimeout with FutureAwaits {} diff --git a/test/uk/gov/hmrc/apisubscriptionfields/FieldDefinitionTestData.scala b/test/uk/gov/hmrc/apisubscriptionfields/FieldDefinitionTestData.scala index fa61b2f..edf7d3d 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/FieldDefinitionTestData.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/FieldDefinitionTestData.scala @@ -43,9 +43,10 @@ trait FieldDefinitionTestData extends TestData { final val FakeUrlValidation: ValidationGroup = ValidationGroup("error message", NonEmptyList.one(UrlValidationRule)) - final val FakeFieldDefinitionUrl = FieldDefinition(fieldN(1), "desc1", "hint1", FieldDefinitionType.URL, "short description", Some(FakeUrlValidation)) - final val FakeFieldDefinitionUrlValidationEmpty = FieldDefinition(fieldN(1), "desc1", "hint1", FieldDefinitionType.URL, "short description", None) - final val FakeFieldDefinitionString = FieldDefinition(fieldN(2), "desc2", "hint2", FieldDefinitionType.STRING, "short description", Some(FakeValidation)) + final val FakeFieldDefinitionUrl = FieldDefinition(fieldN(1), "desc1", "hint1", FieldDefinitionType.URL, "short description", Some(FakeUrlValidation)) + final val FakeFieldDefinitionUrlValidationEmpty = FieldDefinition(fieldN(1), "desc1", "hint1", FieldDefinitionType.URL, "short description", None) + final val FakeFieldDefinitionString = FieldDefinition(fieldN(2), "desc2", "hint2", FieldDefinitionType.STRING, "short description", Some(FakeValidation)) + final val FakeFieldDefinitionWithAccess: FieldDefinition = FakeFieldDefinitionString.copy(validation = None, access = AccessRequirements(devhub = DevhubAccessRequirements(read = AdminOnly))) final val FakeFieldDefinitionSecureToken = FieldDefinition(fieldN(3), "desc3", "hint3", FieldDefinitionType.SECURE_TOKEN, "short description", Some(FakeValidation)) @@ -57,9 +58,11 @@ trait FieldDefinitionTestData extends TestData { final val PasswordRegexRule: RegexValidationRule = RegexValidationRule("^(?=.{8,})(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$") final val CallBackUrlRegexRule: RegexValidationRule = RegexValidationRule("^https.*") final val FakeValidationForAlphanumeric: ValidationGroup = ValidationGroup("Needs to be alpha numeric", NonEmptyList.one(AlphaNumericRegexRule)) - final val FakeValidationForPassword: ValidationGroup = + + final val FakeValidationForPassword: ValidationGroup = ValidationGroup("Needs to be at least 8 chars with at least one lowercase, uppercase and special char", NonEmptyList.one(PasswordRegexRule)) - final val FakeValidationForPPNS: ValidationGroup = + + final val FakeValidationForPPNS: ValidationGroup = ValidationGroup("CallBackUrl Validation", NonEmptyList.one(CallBackUrlRegexRule)) final val FakeFieldDefinitionAlphnumericField = FieldDefinition( @@ -70,12 +73,14 @@ trait FieldDefinitionTestData extends TestData { "an alphanumeric field", Some(FakeValidationForAlphanumeric) ) - final val FakeFieldDefinitionPassword = + + final val FakeFieldDefinitionPassword = FieldDefinition("password", "password", "this is your password", FieldDefinitionType.SECURE_TOKEN, "password", Some(FakeValidationForPassword)) - final val FakeFieldDefinitionPPNSFields = + final val FakeFieldDefinitionPPNSFields = FieldDefinition("callbackurl", "callbackurl", "please enter a callback url", FieldDefinitionType.PPNS_FIELD, "callbackurl", Some(FakeValidationForPPNS)) - final val FakeApiFieldDefinitionssWithRegex = NonEmptyList.fromListUnsafe(List(FakeFieldDefinitionAlphnumericField, FakeFieldDefinitionPassword)) + final val FakeApiFieldDefinitionssWithRegex = NonEmptyList.fromListUnsafe(List(FakeFieldDefinitionAlphnumericField, FakeFieldDefinitionPassword)) + final val FakeApiFieldDefinitionsPPNSWithRegex = NonEmptyList.fromListUnsafe(List(FakeFieldDefinitionAlphnumericField, FakeFieldDefinitionPassword, FakeFieldDefinitionPPNSFields)) @@ -121,7 +126,7 @@ trait FieldDefinitionTestData extends TestData { apiContext: ApiContext = FakeContext, apiVersion: ApiVersion = FakeVersion, fieldDefinitions: NonEmptyList[FieldDefinition] = NelOfFieldDefinitions - ) = + ) = ApiFieldDefinitions(apiContext, apiVersion, fieldDefinitions) def uniqueApiContext = ApiContext(UUID.randomUUID().toString) diff --git a/test/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldsTestData.scala b/test/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldsTestData.scala index 75a2c88..f8bd79b 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldsTestData.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/SubscriptionFieldsTestData.scala @@ -28,10 +28,11 @@ trait SubscriptionFieldsTestData extends FieldDefinitionTestData with Validation final val FakeRawFieldsId = UUID.randomUUID() final val FakeFieldsId = SubscriptionFieldsId(FakeRawFieldsId) - final val EmptyResponse: Future[Option[SubscriptionFields]] = Future.successful(None) - final val FakeSubscriptionFields: Map[FieldName, String] = Map(fieldN(1) -> "X", fieldN(2) -> "Y") - final val SubscriptionFieldsMatchRegexValidation: Fields = Map(AlphanumericFieldName -> "ABC123ab", PasswordFieldName -> "Qw12@ert") - final val SubscriptionFieldsNonMatchRegexValidation: Fields = Map(AlphanumericFieldName -> "ABC123a", PasswordFieldName -> "Qw12@er") + final val EmptyResponse: Future[Option[SubscriptionFields]] = Future.successful(None) + final val FakeSubscriptionFields: Map[FieldName, String] = Map(fieldN(1) -> "X", fieldN(2) -> "Y") + final val SubscriptionFieldsMatchRegexValidation: Fields = Map(AlphanumericFieldName -> "ABC123ab", PasswordFieldName -> "Qw12@ert") + final val SubscriptionFieldsNonMatchRegexValidation: Fields = Map(AlphanumericFieldName -> "ABC123a", PasswordFieldName -> "Qw12@er") + final val SubscriptionFieldsMatchRegexValidationPPNS: Fields = Map(AlphanumericFieldName -> "ABC123abc", PasswordFieldName -> "Qw12@erty", PPNSFieldFieldName -> "https://www.mycallbackurl.com") final val SubscriptionFieldsDoNotMatchRegexValidationPPNS: Fields = Map(AlphanumericFieldName -> "ABC123abc", PasswordFieldName -> "Qw12@erty", PPNSFieldFieldName -> "foo") @@ -45,8 +46,9 @@ trait SubscriptionFieldsTestData extends FieldDefinitionTestData with Validation final val CallbackUrlFieldName: FieldName = "callbackUrl" final val FakeFieldErrorMessage1: FieldError = ((CallbackUrlFieldName, "Invalid Callback URL")) - final val EoriFieldName: FieldName = "EORI" - final val FakeFieldErrorMessage2 = ((EoriFieldName, "Invalid EORI")) + final val EoriFieldName: FieldName = "EORI" + final val FakeFieldErrorMessage2 = ((EoriFieldName, "Invalid EORI")) + final val FakeFieldErrorMessages = Map( (CallbackUrlFieldName -> FakeFieldErrorMessage1._2), (EoriFieldName -> FakeFieldErrorMessage2._2) @@ -55,7 +57,8 @@ trait SubscriptionFieldsTestData extends FieldDefinitionTestData with Validation final val FakeFieldErrorForAlphanumeric: FieldError = ((AlphanumericFieldName, "Needs to be alpha numeric")) final val FakeFieldErrorForPassword = ((PasswordFieldName, "Needs to be at least 8 chars with at least one lowercase, uppercase and special char")) - final val FakeInvalidSubsFieldValidationResponse2 = InvalidSubsFieldValidationResponse(errorResponses = + + final val FakeInvalidSubsFieldValidationResponse2 = InvalidSubsFieldValidationResponse(errorResponses = Map( (AlphanumericFieldName -> FakeFieldErrorForAlphanumeric._2), (PasswordFieldName -> FakeFieldErrorForPassword._2) diff --git a/test/uk/gov/hmrc/apisubscriptionfields/connector/PushPullNotificationServiceConnectorSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/connector/PushPullNotificationServiceConnectorSpec.scala index a549a74..fde32c0 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/connector/PushPullNotificationServiceConnectorSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/connector/PushPullNotificationServiceConnectorSpec.scala @@ -36,6 +36,8 @@ import uk.gov.hmrc.http.HeaderCarrier import uk.gov.hmrc.apisubscriptionfields.AsyncHmrcSpec import uk.gov.hmrc.apisubscriptionfields.model._ +import uk.gov.hmrc.apisubscriptionfields.connector.JsonFormatters + class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceOneAppPerSuite with JsonFormatters with BeforeAndAfterAll with BeforeAndAfterEach { private val stubPort = 11111 @@ -52,17 +54,21 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO // Run wiremock server on local machine with specified port. private val wireMockServer = new WireMockServer(wireMockConfig().port(stubPort)) - override def beforeAll() { + override def beforeAll(): Unit = { + super.beforeAll() + wireMockServer.start() WireMock.configureFor(stubHost, stubPort) } - override def beforeEach { + override def beforeEach(): Unit = { wireMockServer.resetAll() } - override def afterAll() { + override def afterAll(): Unit = { wireMockServer.stop() + + super.afterAll() } trait Setup { @@ -74,7 +80,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val connector: PushPullNotificationServiceConnector = app.injector.instanceOf[PushPullNotificationServiceConnector] - def primeStub(path: String, requestBody: String, responseBody: String) { + def primeStub(path: String, requestBody: String, responseBody: String): Unit = { wireMockServer.stubFor( put(path) .withRequestBody(equalTo(requestBody)) @@ -87,7 +93,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO ) } - def verifyMock(path: String) { + def verifyPath(path: String): Unit = { wireMockServer.verify( putRequestedFor(urlPathEqualTo(path)) .withHeader(CONTENT_TYPE, equalTo("application/json")) @@ -108,7 +114,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val ret: BoxId = await(connector.ensureBoxIsCreated(boxName, clientId)) ret shouldBe boxId - verifyMock(path) + verifyPath(path) } "send proper request to subscribe" in new Setup { @@ -122,7 +128,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val ret: Unit = await(connector.subscribe(boxId, callbackUrl)) ret shouldBe (()) - verifyMock(path) + verifyPath(path) } "send proper request to update callback and map response on success" in new Setup { @@ -136,7 +142,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val ret: PPNSCallBackUrlValidationResponse = await(connector.updateCallBackUrl(clientId, boxId, callbackUrl)) ret shouldBe PPNSCallBackUrlSuccessResponse - verifyMock(path) + verifyPath(path) } "send proper request to update callback (when callback is empty) and map response on success" in new Setup { @@ -150,7 +156,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val ret: PPNSCallBackUrlValidationResponse = await(connector.updateCallBackUrl(clientId, boxId, callbackUrl)) ret shouldBe PPNSCallBackUrlSuccessResponse - verifyMock(path) + verifyPath(path) } "send proper request to update callback and map response on failure" in new Setup { @@ -164,7 +170,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val ret: PPNSCallBackUrlValidationResponse = await(connector.updateCallBackUrl(clientId, boxId, callbackUrl)) ret shouldBe PPNSCallBackUrlFailedResponse("some error") - verifyMock(path) + verifyPath(path) } "send proper request to update callback and map response on failure with Unknown Error" in new Setup { @@ -178,7 +184,7 @@ class PushPullNotificationServiceConnectorSpec extends AsyncHmrcSpec with GuiceO val ret: PPNSCallBackUrlValidationResponse = await(connector.updateCallBackUrl(clientId, boxId, callbackUrl)) ret shouldBe PPNSCallBackUrlFailedResponse("Unknown Error") - verifyMock(path) + verifyPath(path) } } } diff --git a/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPostSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPostSpec.scala index 466f6cc..67c159f 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPostSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPostSpec.scala @@ -55,7 +55,7 @@ class ApiFieldDefinitionsControllerPostSpec extends AsyncHmrcSpec with FieldDefi } } - private def testSubmitResult(request: Request[JsValue])(test: Future[Result] => Unit) { + private def testSubmitResult(request: Request[JsValue])(test: Future[Result] => Unit): Unit = { val action: Action[JsValue] = controller.validateFieldsDefinition() val result: Future[Result] = action.apply(request) test(result) diff --git a/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPutSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPutSpec.scala index 2f6e434..2104b2d 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPutSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/controller/ApiFieldDefinitionsControllerPutSpec.scala @@ -61,7 +61,7 @@ class ApiFieldDefinitionsControllerPutSpec extends AsyncHmrcSpec with FieldDefin } } - private def testSubmitResult(request: Request[JsValue])(test: Future[Result] => Unit) { + private def testSubmitResult(request: Request[JsValue])(test: Future[Result] => Unit): Unit = { val action: Action[JsValue] = controller.upsertFieldsDefinition(FakeContext, FakeVersion) val result: Future[Result] = action.apply(request) test(result) diff --git a/test/uk/gov/hmrc/apisubscriptionfields/controller/SubscriptionFieldsControllerPutSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/controller/SubscriptionFieldsControllerPutSpec.scala index 369655c..b55faa4 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/controller/SubscriptionFieldsControllerPutSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/controller/SubscriptionFieldsControllerPutSpec.scala @@ -90,7 +90,7 @@ class SubscriptionFieldsControllerPutSpec extends AsyncHmrcSpec with Subscriptio } } - private def testSubmitResult(request: Request[JsValue])(test: Future[Result] => Unit) { + private def testSubmitResult(request: Request[JsValue])(test: Future[Result] => Unit): Unit = { val action: Action[JsValue] = controller.upsertSubscriptionFields(FakeClientId, FakeContext, FakeVersion) val result: Future[Result] = action.apply(request) test(result) diff --git a/test/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirementsSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirementsSpec.scala index f4e02fc..f5335bf 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirementsSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/model/AccessRequirementsSpec.scala @@ -16,12 +16,13 @@ package uk.gov.hmrc.apisubscriptionfields.model -import org.scalatest.{Matchers, WordSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec import uk.gov.hmrc.apisubscriptionfields.model.DevhubAccessLevel._ import uk.gov.hmrc.apisubscriptionfields.model.DevhubAccessRequirement._ -class AccessRequirementsSpec extends WordSpec with Matchers { +class AccessRequirementsSpec extends AnyWordSpec with Matchers { "DevhubRequirement" should { diff --git a/test/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatterSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatterSpec.scala index 46e61e5..2a6dd5f 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatterSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/model/JsonFormatterSpec.scala @@ -17,12 +17,13 @@ package uk.gov.hmrc.apisubscriptionfields.model import cats.data.NonEmptyList -import org.scalatest.{Matchers, WordSpec} +import org.scalatest.matchers.should.Matchers +import org.scalatest.wordspec.AnyWordSpec import uk.gov.hmrc.apisubscriptionfields.model.FieldDefinitionType._ import uk.gov.hmrc.apisubscriptionfields.{FieldDefinitionTestData, SubscriptionFieldsTestData} -class JsonFormatterSpec extends WordSpec with Matchers with JsonFormatters with SubscriptionFieldsTestData with FieldDefinitionTestData { +class JsonFormatterSpec extends AnyWordSpec with Matchers with JsonFormatters with SubscriptionFieldsTestData with FieldDefinitionTestData { import play.api.libs.json._ @@ -36,10 +37,12 @@ class JsonFormatterSpec extends WordSpec with Matchers with JsonFormatters with private def objectAsJsonString[A](a: A)(implicit t: Writes[A]) = Json.asciiStringify(Json.toJson(a)) - private val subscriptionFieldJson = + private val subscriptionFieldJson = s"""{"clientId":"$fakeRawClientId","apiContext":"$fakeRawContext","apiVersion":"$fakeRawVersion","fieldsId":"$FakeRawFieldsId","fields":{"fieldB":"v1"}}""" - private val fieldDefinitionJson = + + private val fieldDefinitionJson = s"""{"apiContext":"$fakeRawContext","apiVersion":"$fakeRawVersion","fieldDefinitions":[{"name":"fieldB","description":"desc1","hint":"hint1","type":"URL","shortDescription":"short description","validation":{"errorMessage":"error message","rules":[{"UrlValidationRule":{}}]}}]}""" + private val fieldDefinitionEmptyValidationJson = s"""{"apiContext":"$fakeRawContext","apiVersion":"$fakeRawVersion","fieldDefinitions":[{"name":"fieldB","description":"desc1","hint":"hint1","type":"URL","shortDescription":"short description"}]}""" diff --git a/test/uk/gov/hmrc/apisubscriptionfields/model/ModelSpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/model/ModelSpec.scala index 8a8327b..81eb9da 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/model/ModelSpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/model/ModelSpec.scala @@ -16,8 +16,6 @@ package uk.gov.hmrc.apisubscriptionfields.model -import org.scalatest.Matchers - import uk.gov.hmrc.apisubscriptionfields.{FieldDefinitionTestData, HmrcSpec, SubscriptionFieldsTestData} class ModelSpec extends HmrcSpec with SubscriptionFieldsTestData with FieldDefinitionTestData with ValidationRuleTestData { @@ -40,7 +38,7 @@ class ModelSpec extends HmrcSpec with SubscriptionFieldsTestData with FieldDefin } } -class UrlValidationRuleSpec extends HmrcSpec with ValidationRuleTestData with Matchers { +class UrlValidationRuleSpec extends HmrcSpec with ValidationRuleTestData { "url validation rule" should { "pass for a matching value" in { UrlValidationRule.validate(validUrl) shouldBe true diff --git a/test/uk/gov/hmrc/apisubscriptionfields/repository/ApiFieldDefinitionsRepositorySpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/repository/ApiFieldDefinitionsRepositorySpec.scala index 6b5e348..f92d130 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/repository/ApiFieldDefinitionsRepositorySpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/repository/ApiFieldDefinitionsRepositorySpec.scala @@ -39,14 +39,14 @@ class ApiFieldDefinitionsRepositorySpec private val repository = app.injector.instanceOf[ApiFieldDefinitionsMongoRepository] - override protected def beforeEach() { + override protected def beforeEach(): Unit = { super.beforeEach() - await(repository.collection.drop.toFuture()) + await(repository.collection.drop().toFuture()) } - override protected def afterEach() { + override protected def afterEach(): Unit = { super.afterEach() - await(repository.collection.drop.toFuture()) + await(repository.collection.drop().toFuture()) } def collectionSize: Long = { diff --git a/test/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepositorySpec.scala b/test/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepositorySpec.scala index 0069851..f65b68d 100644 --- a/test/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepositorySpec.scala +++ b/test/uk/gov/hmrc/apisubscriptionfields/repository/SubscriptionFieldsRepositorySpec.scala @@ -48,9 +48,9 @@ class SubscriptionFieldsRepositorySpec private val repository = app.injector.instanceOf[SubscriptionFieldsMongoRepository] - override def beforeEach() { + override def beforeEach(): Unit = { super.beforeEach() - await(repository.collection.drop.toFuture()) + await(repository.collection.drop().toFuture()) } private def createApiSubscriptionFields(clientId: ClientId = FakeClientId): SubscriptionFields = { @@ -156,7 +156,7 @@ class SubscriptionFieldsRepositorySpec val result = await(repository.fetch(FakeClientId, FakeContext, FakeVersion)) result match { - case None => fail + case None => fail() case Some(subscriptionFields: SubscriptionFields) => validateSubscriptionFields(subscriptionFields, apiSubscription) } } @@ -182,7 +182,7 @@ class SubscriptionFieldsRepositorySpec val result = await(repository.fetchByFieldsId(savedSubscriptionFields._1.fieldsId)) result match { - case None => fail + case None => fail() case Some(subscriptionFields: SubscriptionFields) => validateSubscriptionFields(subscriptionFields, apiSubscription) } }