Skip to content

Commit

Permalink
test: adding tests for BankController and ColaMixController
Browse files Browse the repository at this point in the history
  • Loading branch information
MoeQuadrat committed Oct 25, 2022
1 parent 17050da commit 66c55dc
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.innfactory.example.application.controller

import akka.http.scaladsl.model.HttpHeader.ParsingResult.Ok
import cats.data.{EitherT, Kleisli, RWS}
import cats.data.{EitherT, Kleisli, RWS, Validated}
import de.innfactory.play.controller.{ErrorResult, ResultStatus}
import de.innfactory.play.results.errors.Errors.Forbidden
import de.innfactory.play.smithy4play.{AbstractBaseController, ContextWithHeaders, HttpHeaders, ImplicitLogContext}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import cats.data.{EitherT, Validated}
import de.innfactory.example.bank.domain.interfaces.BankService
import de.innfactory.play.controller.ResultStatus
import de.innfactory.play.results.errors.Errors.BadRequest
import playSmithy.{CreateDeleteAccountOutput, GetAllAccountsOutput, TransferOutput}
import playSmithy.{
CreateDeleteAccountOutput,
GetAllAccountsOutput,
TransferOutput
}
import de.innfactory.play.results.errors.Errors.NotFound

import javax.inject.{Inject, Singleton}
Expand Down Expand Up @@ -62,16 +66,16 @@ class BankServiceImpl @Inject()()(implicit ec: ExecutionContext)
): EitherT[Future, ResultStatus, CreateDeleteAccountOutput] =
for {
value <- EitherT.fromOptionF[Future, ResultStatus, Double](
Future(
{println(database)
database.get(key)}),
Future(database.get(key)),
NotFound("No Bank Account for this User")
)
} yield CreateDeleteAccountOutput(value, key)

override def getAllAccounts()
: EitherT[Future, ResultStatus, GetAllAccountsOutput] =
EitherT.rightT[Future, ResultStatus](GetAllAccountsOutput(
database.map(acc => CreateDeleteAccountOutput(acc._2, acc._1) ).toList)
EitherT.rightT[Future, ResultStatus](
GetAllAccountsOutput(
database.map(acc => CreateDeleteAccountOutput(acc._2, acc._1)).toList
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use smithy4s.api#simpleRestJson
@httpBearerAuth
service BankAPIService {
version: "1.0.0",
operations: [CreateAccount, DeleteAccount, Transfer, GetAllAccounts]
operations: [CreateAccount DeleteAccount Transfer GetAllAccounts]
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ service ColaMixAPIService {
}



@auth([])
@http(method: "POST", uri: "/buy", code: 200)
operation BuyCola {
Expand Down
60 changes: 60 additions & 0 deletions test/controller/BankControllerTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package controller

import de.innfactory.smithy4play.client.GenericAPIClient.EnhancedGenericAPIClient
import de.innfactory.smithy4play.client.SmithyPlayTestUtils._
import org.scalatestplus.play.{BaseOneAppPerSuite, PlaySpec}
import playSmithy.{BankAPIServiceGen, ColaMixAPIServiceGen}
import utils.FakeRequestClient

class BankControllerTest
extends PlaySpec
with BaseOneAppPerSuite
with TestApplicationFactory {

val bankClient = BankAPIServiceGen.withClient(new FakeRequestClient)
val accountName = "Tommy McFlommy"

"BankController" must {

"create Account " in {
val startingBalance = 10
val result = bankClient
.createAccount(startingBalance, accountName)
.run(None)
.awaitRight

result.body.get.name mustBe accountName
result.body.get.balance mustBe startingBalance
result.statusCode mustBe result.expectedStatusCode
}
"delete Account" in {
val result = bankClient.deleteAccount(accountName).run(None).awaitRight

result.body.get.name mustBe accountName
result.statusCode mustBe result.expectedStatusCode
}

"transfer money to account" in {
val name = "McFloppy"
val startingBalance = 10.0
val transferAmount = 20.0
bankClient.createAccount(startingBalance, name).run(None).awaitRight
val result =
bankClient.transfer(transferAmount, name).run(None).awaitRight

result.body.get.name mustBe name
result.body.get.balance mustBe startingBalance + transferAmount
result.statusCode mustBe result.expectedStatusCode
}

"get all Accounts" in {
bankClient.createAccount(10.0, "Randy").run(None).awaitRight
val result = bankClient
.getAllAccounts()
.run(Some(Map("Authorization" -> Seq("ADMIN")))).awaitRight

result.statusCode mustBe result.expectedStatusCode
result.body.get.body.nonEmpty mustBe true
}
}
}
55 changes: 55 additions & 0 deletions test/controller/ColaMixControllerTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package controller

import de.innfactory.smithy4play.client.SmithyPlayTestUtils._
import de.innfactory.smithy4play.client.GenericAPIClient.EnhancedGenericAPIClient
import org.scalatestplus.play.{BaseOneAppPerSuite, PlaySpec}
import playSmithy.{BankAPIServiceGen, ColaMixAPIServiceGen}
import utils.FakeRequestClient

class ColaMixControllerTest extends PlaySpec with BaseOneAppPerSuite with TestApplicationFactory {

val client = ColaMixAPIServiceGen.withClient(new FakeRequestClient)
val bankClient = BankAPIServiceGen.withClient(new FakeRequestClient)

"ColaMixController" must {


"get ColaServiceInformations" in {
val result = client.getColaMixInfo().run(None).awaitRight
println(result)
result.statusCode mustBe result.expectedStatusCode
}

"post deliverCola with Authorization" in {
val amount = 10000
val colaInfoBefore = client.getColaMixInfo().run(None).awaitRight
val result = client.deliverCola(10000).run(Some(Map("Authorization" -> Seq("ADMIN")))).awaitRight

result.statusCode mustBe result.expectedStatusCode
result.body.get.newStorage mustBe colaInfoBefore.body.get.amount + amount
}

"post deliverCola without Authorization" in {
val result = client.deliverCola(10000).run(None).awaitLeft

result.statusCode must not be result.expectedStatusCode
result.statusCode mustBe 401
}

"buy ColaMix with no existing BankAccount" in {
val result = client.buyCola(100, "Hans").run(None).awaitLeft

result.statusCode must not be result.expectedStatusCode
result.statusCode mustBe 404
}

"buy ColaMix with existing BankAccount" in {
val account = bankClient.createAccount(1000000.0, "Hans").run(None).awaitRight.body.get
val result = client.buyCola(100, account.name).run(None).awaitRight

result.statusCode mustBe result.expectedStatusCode
result.body.get.newBankBalance must not be account.balance
}
}

}
23 changes: 23 additions & 0 deletions test/controller/TestApplicationFactory.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package controller

import akka.stream.Materializer
import org.scalatestplus.play.FakeApplicationFactory
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder

import scala.concurrent.ExecutionContext

trait TestApplicationFactory extends FakeApplicationFactory {
implicit var ec: ExecutionContext = _
implicit var mat: Materializer = _

def fakeApplication(): Application = {
val app = GuiceApplicationBuilder()
.build()

ec = app.injector.instanceOf[ExecutionContext]
mat = app.injector.instanceOf[Materializer]

app
}
}
39 changes: 39 additions & 0 deletions test/utils/FakeRequestClient.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package utils

import akka.stream.Materializer
import de.innfactory.smithy4play.client.{RequestClient, SmithyClientResponse}
import play.api.Application
import play.api.mvc.AnyContentAsEmpty
import play.api.test.FakeRequest
import play.api.test.Helpers._

import scala.concurrent.{ExecutionContext, Future}

class FakeRequestClient(implicit application: Application, ec: ExecutionContext, mat: Materializer) extends RequestClient {
override def send(
method: String,
path: String,
headers: Map[String, Seq[String]],
body: Option[Array[Byte]]
): Future[SmithyClientResponse] = {
val baseRequest: FakeRequest[AnyContentAsEmpty.type] = FakeRequest(method, path)
.withHeaders(headers.toList.flatMap(headers => headers._2.map(v => (headers._1, v))): _*)
val res =
if (body.isDefined) route(application, baseRequest.withBody(body.get)).get
else
route(
application,
baseRequest
).get

for {
result <- res
headers = result.header.headers.map(v => (v._1, Seq(v._2)))
body <- result.body.consumeData.map(_.toArrayUnsafe())
bodyConsumed = if (result.body.isKnownEmpty) None else Some(body)
contentType = result.body.contentType
headersWithContentType =
if (contentType.isDefined) headers + ("Content-Type" -> Seq(contentType.get)) else headers
} yield SmithyClientResponse(bodyConsumed, headersWithContentType, result.header.status)
}
}

0 comments on commit 66c55dc

Please sign in to comment.