Alexis Hernandez
7 years ago
4 changed files with 126 additions and 0 deletions
@ -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 |
|||
} |
|||
} |
@ -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) |
|||
} |
|||
} |
@ -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…
Reference in new issue