Browse Source

server: Add GET /addresses/:address

scalafmt-draft
Alexis Hernandez 7 years ago
parent
commit
3270f9274c
  1. 28
      server/app/com/xsn/explorer/services/AddressService.scala
  2. 16
      server/app/controllers/AddressesController.scala
  3. 2
      server/conf/routes
  4. 80
      server/test/controllers/AddressesTransactionSpec.scala

28
server/app/com/xsn/explorer/services/AddressService.scala

@ -0,0 +1,28 @@
package com.xsn.explorer.services
import javax.inject.Inject
import com.alexitc.playsonify.core.FutureApplicationResult
import com.alexitc.playsonify.core.FutureOr.Implicits.{FutureOps, OrOps}
import com.xsn.explorer.errors.AddressFormatError
import com.xsn.explorer.models.{Address, AddressDetails}
import org.scalactic.{One, Or}
import scala.concurrent.ExecutionContext
class AddressService @Inject() (xsnService: XSNService)(implicit ec: ExecutionContext) {
def getDetails(addressString: String): FutureApplicationResult[AddressDetails] = {
val result = for {
address <- {
val maybe = Address.from(addressString)
Or.from(maybe, One(AddressFormatError)).toFutureOr
}
balance <- xsnService.getAddressBalance(address).toFutureOr
transactionCount <- xsnService.getTransactionCount(address).toFutureOr
} yield AddressDetails(balance, transactionCount)
result.toFuture
}
}

16
server/app/controllers/AddressesController.scala

@ -0,0 +1,16 @@
package controllers
import javax.inject.Inject
import com.xsn.explorer.services.AddressService
import controllers.common.{MyJsonController, MyJsonControllerComponents}
class AddressesController @Inject() (
addressService: AddressService,
cc: MyJsonControllerComponents)
extends MyJsonController(cc) {
def getDetails(address: String) = publicNoInput { _ =>
addressService.getDetails(address)
}
}

2
server/conf/routes

@ -4,3 +4,5 @@
# ~~~~
GET /transactions/:txid controllers.TransactionsController.getTransaction(txid: String)
GET /addresses/:address controllers.AddressesController.getDetails(address: String)

80
server/test/controllers/AddressesTransactionSpec.scala

@ -0,0 +1,80 @@
package controllers
import com.alexitc.playsonify.PublicErrorRenderer
import com.alexitc.playsonify.core.FutureApplicationResult
import com.xsn.explorer.errors.AddressFormatError
import com.xsn.explorer.helpers.DummyXSNService
import com.xsn.explorer.models._
import com.xsn.explorer.services.XSNService
import controllers.common.MyAPISpec
import org.scalactic.{One, Or}
import play.api.inject.bind
import play.api.libs.json.JsValue
import play.api.test.Helpers._
import scala.concurrent.Future
class AddressesTransactionSpec extends MyAPISpec {
def addressDetails(balance: Int, received: Int, txCount: Int) = {
AddressDetails(AddressBalance(BigInt(balance), BigInt(received)), txCount)
}
val addressEmpty = addressDetails(0, 0, 0)
val addressFilled = addressDetails(100, 200, 25)
val customXSNService = new DummyXSNService {
val map = Map(
"Xi3sQfMQsy2CzMZTrnKW6HFGp1VqFThdLw" -> addressEmpty,
"XnH3bC9NruJ4wnu4Dgi8F3wemmJtcxpKp6" -> addressFilled
)
override def getAddressBalance(address: Address): FutureApplicationResult[AddressBalance] = {
val maybe = map.get(address.string).map(_.balance)
val result = Or.from(maybe, One(AddressFormatError))
Future.successful(result)
}
override def getTransactionCount(address: Address): FutureApplicationResult[Int] = {
val maybe = map.get(address.string).map(_.transactionCount)
val result = Or.from(maybe, One(AddressFormatError))
Future.successful(result)
}
}
override val application = guiceApplicationBuilder
.overrides(bind[XSNService].to(customXSNService))
.build()
"GET /addresses/:address" should {
def url(address: String) = s"/addresses/$address"
"retrieve address information" in {
val address = addressFilled
val response = GET(url("XnH3bC9NruJ4wnu4Dgi8F3wemmJtcxpKp6"))
status(response) mustEqual OK
val json = contentAsJson(response)
(json \ "balance").as[Int] mustEqual address.balance.balance.intValue()
(json \ "received").as[Int] mustEqual address.balance.received.intValue()
(json \ "transactionCount").as[Int] mustEqual address.transactionCount
}
"fail on bad address format" in {
val address = "XnH3bC9NruJ4wnu4Dgi8F3wemmJtcxpKp"
val response = GET(url(address))
status(response) mustEqual BAD_REQUEST
val json = contentAsJson(response)
val errorList = (json \ "errors").as[List[JsValue]]
errorList.size mustEqual 1
val error = errorList.head
(error \ "type").as[String] mustEqual PublicErrorRenderer.FieldValidationErrorType
(error \ "field").as[String] mustEqual "address"
}
}
}
Loading…
Cancel
Save