diff --git a/alerts-server/build.sbt b/alerts-server/build.sbt index 7b17c95..e76115e 100644 --- a/alerts-server/build.sbt +++ b/alerts-server/build.sbt @@ -52,6 +52,7 @@ libraryDependencies += "com.github.bitsoex" % "bitso-java" % "v3.0.5" libraryDependencies += "com.pauldijou" %% "jwt-core" % "0.14.1" libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.0" % Test +libraryDependencies += "com.alexitc" %% "playsonifytest" % "1.0.0" % Test libraryDependencies ++= Seq( "com.spotify" % "docker-client" % "8.9.1", diff --git a/alerts-server/test/com/alexitc/coinalerts/commons/PlayAPISpec.scala b/alerts-server/test/com/alexitc/coinalerts/commons/CustomPlayAPISpec.scala similarity index 57% rename from alerts-server/test/com/alexitc/coinalerts/commons/PlayAPISpec.scala rename to alerts-server/test/com/alexitc/coinalerts/commons/CustomPlayAPISpec.scala index dff7eb2..b3faa71 100644 --- a/alerts-server/test/com/alexitc/coinalerts/commons/PlayAPISpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/commons/CustomPlayAPISpec.scala @@ -1,14 +1,11 @@ package com.alexitc.coinalerts.commons -import java.net.URLEncoder - import com.alexitc.coinalerts.core.{AuthorizationToken, PaginatedQuery} import com.alexitc.coinalerts.data._ import com.alexitc.coinalerts.modules.{ExchangeCurrencySeederTaskModule, FixedPriceAlertsTaskModule} import com.alexitc.coinalerts.services.external.ReCaptchaService import com.alexitc.coinalerts.services.{EmailServiceTrait, JWTService} -import org.scalatest.concurrent.ScalaFutures -import org.scalatestplus.play.PlaySpec +import com.alexitc.playsonify.test.PlayAPISpec import org.slf4j.LoggerFactory import play.api.db.{DBApi, Database, Databases} import play.api.inject.bind @@ -16,7 +13,7 @@ import play.api.inject.guice.GuiceApplicationBuilder import play.api.mvc.Result import play.api.test.FakeRequest import play.api.test.Helpers._ -import play.api.{Application, Configuration, Environment, Mode} +import play.api.{Configuration, Environment, Mode} import scala.concurrent.Future @@ -25,7 +22,7 @@ import scala.concurrent.Future * without depending on a database but custom implementations * for the data layer. */ -trait PlayAPISpec extends PlaySpec with ScalaFutures { +trait CustomPlayAPISpec extends PlayAPISpec { private val logger = LoggerFactory.getLogger(this.getClass) @@ -60,7 +57,7 @@ trait PlayAPISpec extends PlaySpec with ScalaFutures { implicit val exchangeCurrencyDataHandler: ExchangeCurrencyBlockingDataHandler = new ExchangeCurrencyInMemoryDataHandler {} CurrencySeeder.seed - val guiceApplicationBuilder: GuiceApplicationBuilder = GuiceApplicationBuilder(loadConfiguration = loadConfigWithoutEvolutions) + override val guiceApplicationBuilder: GuiceApplicationBuilder = GuiceApplicationBuilder(loadConfiguration = loadConfigWithoutEvolutions) .in(Mode.Test) .disable(classOf[FixedPriceAlertsTaskModule]) .disable(classOf[ExchangeCurrencySeederTaskModule]) @@ -71,88 +68,21 @@ trait PlayAPISpec extends PlaySpec with ScalaFutures { .overrides(bind[UserBlockingDataHandler].to(userDataHandler)) .overrides(bind[ExchangeCurrencyBlockingDataHandler].to(exchangeCurrencyDataHandler)) - def application: Application - lazy val jwtService = application.injector.instanceOf[JWTService] - - /***********************************************************************/ - - private val JsonHeader = CONTENT_TYPE -> "application/json" - private val EmptyJson = "{}" - - private def logRequestResponse[T](request: FakeRequest[T], response: Future[Result]) = { + override protected def log[T](request: FakeRequest[T], response: Future[Result]) = { logger.info(s"REQUEST > $request, headers = ${request.headers}; RESPONSE < status = ${status(response)}, body = ${contentAsString(response)}") } +} - /** Syntactic sugar for calling APIs **/ - def POST(url: String, jsonBody: Option[String], extraHeaders: (String, String)*): Future[Result] = { - val headers = JsonHeader :: extraHeaders.toList - val json = jsonBody.getOrElse(EmptyJson) - val request = FakeRequest("POST", url) - .withHeaders(headers: _*) - .withBody(json) - - val response = route(application, request).get - logRequestResponse(request, response) - response - } - - def POST(url: String, extraHeaders: (String, String)*): Future[Result] = { - POST(url, None, extraHeaders: _*) - } - - def GET(url: String, extraHeaders: (String, String)*): Future[Result] = { - val headers = JsonHeader :: extraHeaders.toList - val request = FakeRequest("GET", url) - .withHeaders(headers: _*) - - val response = route(application, request).get - logRequestResponse(request, response) - response - } - - def DELETE(url: String, extraHeaders: (String, String)*): Future[Result] = { - val headers = JsonHeader :: extraHeaders.toList - val request = FakeRequest("DELETE", url) - .withHeaders(headers: _*) - - val response = route(application, request).get - logRequestResponse(request, response) - - response - } +object CustomPlayAPISpec { - def PUT(url: String, jsonBody: Option[String], extraHeaders: (String, String)*): Future[Result] = { - val headers = JsonHeader :: extraHeaders.toList - val json = jsonBody.getOrElse(EmptyJson) - val request = FakeRequest("PUT", url) - .withHeaders(headers: _*) - .withBody(json) + import PlayAPISpec.Implicits._ - val response = route(application, request).get - logRequestResponse(request, response) - response - } -} - -object PlayAPISpec { implicit class AuthorizationTokenExt(val token: AuthorizationToken) extends AnyVal { def toHeader: (String, String) = AUTHORIZATION -> s"Bearer ${token.string}" } - implicit class HttpExt(val params: List[(String, String)]) extends AnyVal { - def toQueryString: String = { - params - .map { case (key, value) => - val encodedKey = URLEncoder.encode(key, "UTF-8") - val encodedValue = URLEncoder.encode(value, "UTF-8") - List(encodedKey, encodedValue).mkString("=") - } - .mkString("&") - } - } - implicit class PaginatedQueryExt(val query: PaginatedQuery) extends AnyVal { def toHttpQueryString: String = { val params = List( diff --git a/alerts-server/test/com/alexitc/coinalerts/controllers/DailyPriceAlertsControllerSpec.scala b/alerts-server/test/com/alexitc/coinalerts/controllers/DailyPriceAlertsControllerSpec.scala index 6fa1a29..a455648 100644 --- a/alerts-server/test/com/alexitc/coinalerts/controllers/DailyPriceAlertsControllerSpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/controllers/DailyPriceAlertsControllerSpec.scala @@ -2,7 +2,7 @@ package com.alexitc.coinalerts.controllers import java.time.OffsetDateTime -import com.alexitc.coinalerts.commons.{DataHelper, PlayAPISpec, RandomDataGenerator} +import com.alexitc.coinalerts.commons.{CustomPlayAPISpec, DataHelper, RandomDataGenerator} import com.alexitc.coinalerts.core.{Limit, Offset, PaginatedQuery} import com.alexitc.coinalerts.data.{DailyPriceAlertBlockingDataHandler, DailyPriceAlertInMemoryDataHandler} import com.alexitc.coinalerts.models._ @@ -11,9 +11,9 @@ import play.api.inject.bind import play.api.libs.json.JsValue import play.api.test.Helpers._ -class DailyPriceAlertsControllerSpec extends PlayAPISpec { +class DailyPriceAlertsControllerSpec extends CustomPlayAPISpec { - import PlayAPISpec._ + import CustomPlayAPISpec._ implicit val dailyPriceAlertDataHandler: DailyPriceAlertBlockingDataHandler = new DailyPriceAlertInMemoryDataHandler {} diff --git a/alerts-server/test/com/alexitc/coinalerts/controllers/ExchangeCurrenciesControllerSpec.scala b/alerts-server/test/com/alexitc/coinalerts/controllers/ExchangeCurrenciesControllerSpec.scala index cc1ce59..cc93990 100644 --- a/alerts-server/test/com/alexitc/coinalerts/controllers/ExchangeCurrenciesControllerSpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/controllers/ExchangeCurrenciesControllerSpec.scala @@ -1,12 +1,12 @@ package com.alexitc.coinalerts.controllers -import com.alexitc.coinalerts.commons.PlayAPISpec +import com.alexitc.coinalerts.commons.CustomPlayAPISpec import com.alexitc.coinalerts.models.{Exchange, ExchangeCurrencyId, Market} import play.api.Application import play.api.libs.json.JsValue import play.api.test.Helpers._ -class ExchangeCurrenciesControllerSpec extends PlayAPISpec { +class ExchangeCurrenciesControllerSpec extends CustomPlayAPISpec { val application: Application = guiceApplicationBuilder .build() diff --git a/alerts-server/test/com/alexitc/coinalerts/controllers/FixedPriceAlertsControllerSpec.scala b/alerts-server/test/com/alexitc/coinalerts/controllers/FixedPriceAlertsControllerSpec.scala index 77c3043..645cec6 100644 --- a/alerts-server/test/com/alexitc/coinalerts/controllers/FixedPriceAlertsControllerSpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/controllers/FixedPriceAlertsControllerSpec.scala @@ -3,7 +3,7 @@ package com.alexitc.coinalerts.controllers import java.time.OffsetDateTime import com.alexitc.coinalerts.commons.DataHelper._ -import com.alexitc.coinalerts.commons.{PlayAPISpec, RandomDataGenerator} +import com.alexitc.coinalerts.commons.{CustomPlayAPISpec, RandomDataGenerator} import com.alexitc.coinalerts.core.{Limit, Offset, PaginatedQuery} import com.alexitc.coinalerts.data.{FixedPriceAlertBlockingDataHandler, FixedPriceAlertInMemoryDataHandler} import com.alexitc.coinalerts.models.FixedPriceAlertId @@ -12,9 +12,9 @@ import play.api.inject.bind import play.api.libs.json.JsValue import play.api.test.Helpers._ -class FixedPriceAlertsControllerSpec extends PlayAPISpec { +class FixedPriceAlertsControllerSpec extends CustomPlayAPISpec { - import PlayAPISpec._ + import CustomPlayAPISpec._ implicit val alertDataHandler: FixedPriceAlertBlockingDataHandler = new FixedPriceAlertInMemoryDataHandler { override def exchangeCurrencyBlocingDataHandler = Some(exchangeCurrencyDataHandler) diff --git a/alerts-server/test/com/alexitc/coinalerts/controllers/HealthControllerSpec.scala b/alerts-server/test/com/alexitc/coinalerts/controllers/HealthControllerSpec.scala index 58067ac..7de8cdc 100644 --- a/alerts-server/test/com/alexitc/coinalerts/controllers/HealthControllerSpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/controllers/HealthControllerSpec.scala @@ -1,10 +1,10 @@ package com.alexitc.coinalerts.controllers -import com.alexitc.coinalerts.commons.PlayAPISpec +import com.alexitc.coinalerts.commons.CustomPlayAPISpec import play.api.Application import play.api.test.Helpers._ -class HealthControllerSpec extends PlayAPISpec { +class HealthControllerSpec extends CustomPlayAPISpec { val application: Application = guiceApplicationBuilder.build() diff --git a/alerts-server/test/com/alexitc/coinalerts/controllers/NewCurrencyAlertsControllerSpec.scala b/alerts-server/test/com/alexitc/coinalerts/controllers/NewCurrencyAlertsControllerSpec.scala index 9c99819..83945f1 100644 --- a/alerts-server/test/com/alexitc/coinalerts/controllers/NewCurrencyAlertsControllerSpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/controllers/NewCurrencyAlertsControllerSpec.scala @@ -1,6 +1,6 @@ package com.alexitc.coinalerts.controllers -import com.alexitc.coinalerts.commons.{DataHelper, PlayAPISpec} +import com.alexitc.coinalerts.commons.{CustomPlayAPISpec, DataHelper} import com.alexitc.coinalerts.data.{NewCurrencyAlertBlockingDataHandler, NewCurrencyAlertInMemoryDataHandler} import com.alexitc.coinalerts.models.Exchange import play.api.Application @@ -8,9 +8,9 @@ import play.api.inject.bind import play.api.libs.json.JsValue import play.api.test.Helpers._ -class NewCurrencyAlertsControllerSpec extends PlayAPISpec { +class NewCurrencyAlertsControllerSpec extends CustomPlayAPISpec { - import PlayAPISpec._ + import CustomPlayAPISpec._ val dataHandler = new NewCurrencyAlertInMemoryDataHandler {} diff --git a/alerts-server/test/com/alexitc/coinalerts/controllers/UsersControllerSpec.scala b/alerts-server/test/com/alexitc/coinalerts/controllers/UsersControllerSpec.scala index 5d80170..9dd781f 100644 --- a/alerts-server/test/com/alexitc/coinalerts/controllers/UsersControllerSpec.scala +++ b/alerts-server/test/com/alexitc/coinalerts/controllers/UsersControllerSpec.scala @@ -1,14 +1,15 @@ package com.alexitc.coinalerts.controllers -import com.alexitc.coinalerts.commons.PlayAPISpec.AuthorizationTokenExt -import com.alexitc.coinalerts.commons.{DataHelper, PlayAPISpec, RandomDataGenerator} +import com.alexitc.coinalerts.commons.{CustomPlayAPISpec, DataHelper, RandomDataGenerator} import com.alexitc.coinalerts.models._ import play.api.Application import play.api.i18n.Lang import play.api.libs.json.JsValue import play.api.test.Helpers._ -class UsersControllerSpec extends PlayAPISpec { +class UsersControllerSpec extends CustomPlayAPISpec { + + import CustomPlayAPISpec._ val application: Application = guiceApplicationBuilder.build()