org.specs2.mutable.Specification Scala Examples

The following examples show how to use org.specs2.mutable.Specification. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: NomadServiceSpec.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.services

import java.util.concurrent.TimeUnit

import de.frosner.broccoli.controllers.ServiceMocks
import de.frosner.broccoli.nomad.NomadConfiguration
import de.frosner.broccoli.nomad.models.Job.jobFormat
import de.frosner.broccoli.nomad.models._
import org.mockito.Mockito._
import org.specs2.mutable.Specification
import play.api.libs.json._
import play.api.mvc._
import play.api.routing.sird._
import play.api.test._
import play.core.server.Server
import squants.information.InformationConversions._
import squants.time.FrequencyConversions._

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.concurrent.duration.Duration

class NomadServiceSpec extends Specification with ServiceMocks {

  sequential

  "Requesting services for specific job" should {

    "ask consul for the services that nomad returns" in {
      val service = Service("my-service")
      val resources = Resources(
        shapeless.tag[Resources.CPU](20.megahertz),
        shapeless.tag[Resources.Memory](1.gigabytes)
      )
      val task = Task(shapeless.tag[Task.Name]("foo"), resources, Some(Seq(service)))
      val taskGroup = TaskGroup(Seq(task))
      val job = Job(Seq(taskGroup))
      val jobId = "my-job"
      Server.withRouter() {
        case GET(p"/v1/job/my-job") =>
          Action {
            Results.Ok(Json.toJson(job))
          }
      } { implicit port =>
        WsTestClient.withClient { client =>
          val configuration = NomadConfiguration(url = s"http://localhost:$port")
          val nomadService = new NomadService(configuration, client)
          val result = Await.result(nomadService.requestServices(jobId), Duration(5, TimeUnit.SECONDS))
          result === Seq(service.name)
        }
      }
    }

    "not explode when receiving tasks without services" in {
      val service1 = Service("my-service")
      val resources = Resources(
        shapeless.tag[Resources.CPU](100.megahertz),
        shapeless.tag[Resources.Memory](100.megabytes)
      )
      val task1 = Task(shapeless.tag[Task.Name]("foo1"), resources, Some(Seq(service1)))
      val task2 = Task(shapeless.tag[Task.Name]("foo2"), resources, None)
      val taskGroup1 = TaskGroup(Seq(task1))
      val taskGroup2 = TaskGroup(Seq(task2))
      val job = Job(Seq(taskGroup1, taskGroup2))
      val jobId = "my-job"
      Server.withRouter() {
        case GET(p"/v1/job/my-job") =>
          Action {
            Results.Ok(Json.toJson(job))
          }
      } { implicit port =>
        WsTestClient.withClient { client =>
          val configuration = NomadConfiguration(url = s"http://localhost:$port")
          val nomadService = new NomadService(configuration, client)
          val result = Await.result(nomadService.requestServices(jobId), Duration(5, TimeUnit.SECONDS))
          result === Seq(service1.name)
        }
      }
    }

  }

} 
Example 2
Source File: SecurityServiceSpec.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.services

import cats.data.OptionT
import com.mohiva.play.silhouette.api.LoginInfo
import com.mohiva.play.silhouette.api.services.IdentityService
import com.mohiva.play.silhouette.api.util.Credentials
import com.mohiva.play.silhouette.impl.exceptions.InvalidPasswordException
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import de.frosner.broccoli.auth.{Account, AuthConfiguration, AuthMode, Role}
import org.mockito.Mock
import org.specs2.concurrent.ExecutionEnv
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import org.specs2.specification.mutable.ExecutionEnvironment

import scala.concurrent.Future
import scala.concurrent.duration.Duration

class SecurityServiceSpec extends Specification with Mockito with ExecutionEnvironment {

  def configWithAccounts(accounts: Seq[Account]): AuthConfiguration =
    AuthConfiguration(
      mode = AuthMode.Conf,
      session = AuthConfiguration.Session(timeout = Duration(1, "hour"), allowMultiLogin = true),
      cookie = AuthConfiguration.Cookie(secure = true),
      conf = AuthConfiguration.Conf(
        accounts = accounts
          .map(
            a =>
              AuthConfiguration.ConfAccount(
                a.name,
                "",
                a.instanceRegex,
                a.role
            ))
          .toList),
      allowedFailedLogins = 3
    )

  val identityService = mock[IdentityService[Account]]

  val account = Account("frank", "^test.*", Role.Administrator)

  override def is(implicit executionEnv: ExecutionEnv): Any =
    "An authentication check" should {

      "succeed if the credentials provider authenticates" in {
        val login = LoginInfo(CredentialsProvider.ID, account.name)
        val credentials = Credentials(account.name, "pass")

        val credentialsProvider = mock[CredentialsProvider]
        credentialsProvider.authenticate(credentials) returns Future.successful(login)

        SecurityService(configWithAccounts(List(account)), credentialsProvider, identityService)
          .authenticate(credentials) must beSome(login).await
      }

      "fail if the credentials provider fails to authenticate" in {
        val credentials = Credentials(account.name, "pass")

        val credentialsProvider = mock[CredentialsProvider]
        credentialsProvider.authenticate(credentials) returns Future.failed(new InvalidPasswordException("foo"))

        SecurityService(configWithAccounts(List(account)), credentialsProvider, identityService)
          .authenticate(credentials) must beNone.await
      }

      "succeed if the number of failed logins is equal to the allowed ones" in {
        val credentials = Credentials(account.name, "pass")
        val failedCredentials = credentials.copy(password = "foo")
        val login = LoginInfo(CredentialsProvider.ID, credentials.identifier)

        val credentialsProvider = mock[CredentialsProvider]
        credentialsProvider.authenticate(failedCredentials) returns Future.failed(new InvalidPasswordException("foo"))
        credentialsProvider.authenticate(credentials) returns Future.successful(login)

        val service = SecurityService(configWithAccounts(List(account)), credentialsProvider, identityService)
        val failedAttempts = for (attemptNo <- 1 to service.allowedFailedLogins) {
          service.authenticate(failedCredentials) must beNone.await
        }
        service.authenticate(credentials) must beSome(login).await
      }

      "fail if the number of failed logins is greater than the allowed number" in {
        val credentials = Credentials(account.name, "password")
        val failedCredentials = credentials.copy(password = "foo")
        val login = LoginInfo(CredentialsProvider.ID, credentials.identifier)

        val credentialsProvider = mock[CredentialsProvider]
        credentialsProvider.authenticate(failedCredentials) returns Future.failed(new InvalidPasswordException("foo"))
        credentialsProvider.authenticate(credentials) returns Future.successful(login)

        val service = SecurityService(configWithAccounts(List(account)), credentialsProvider, identityService)
        val failedAttempts = for (attemptNo <- 0 to service.allowedFailedLogins) {
          service.authenticate(failedCredentials) must beNone.await
        }
        service.authenticate(credentials) must beNone.await
      }

    }
} 
Example 3
Source File: InstanceStorageSpec.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.instances.storage

import de.frosner.broccoli.models._
import org.specs2.mutable.Specification
import play.api.Logger

import scala.util.{Failure, Try}

class InstanceStorageSpec extends Specification {

  "Any instance storage" should {

    def testStorage = new InstanceStorage {
      protected override val log = Logger(getClass)
      protected override def readInstancesImpl: Try[Set[Instance]] = Failure(new Exception())
      override def readInstancesImpl(idFilter: (String) => Boolean): Try[Set[Instance]] = Failure(new Exception())
      override def readInstanceImpl(id: String): Try[Instance] = Failure(new Exception())
      override def deleteInstanceImpl(toDelete: Instance): Try[Instance] = Failure(new Exception())
      override def writeInstanceImpl(instance: Instance): Try[Instance] = Failure(new Exception())
      override def closeImpl(): Unit = {}
    }

    "be closed after closing" in {
      val storage = testStorage
      storage.close()
      storage.isClosed === true
    }

    "not be closed before closing" in {
      testStorage.isClosed === false
    }

    "should not allow readInstances if closed" in {
      val storage = testStorage
      storage.close()
      storage.readInstances should throwA[IllegalStateException]
    }

    "should not allow readInstances(filter) if closed" in {
      val storage = testStorage
      storage.close()
      storage.readInstances(_ => true) should throwA[IllegalStateException]
    }

    "should not allow readInstance if closed" in {
      val storage = testStorage
      storage.close()
      storage.readInstance("id") should throwA[IllegalStateException]
    }

    "should not allow deleteInstance if closed" in {
      val storage = testStorage
      storage.close()
      val instance = Instance(
        id = "1",
        template = Template(
          id = "1",
          template = "\"{{id}} {{age}}\"",
          description = "desc",
          parameterInfos = Map(
            "id" -> ParameterInfo("id", None, None, None, ParameterType.Raw, None),
            "age" -> ParameterInfo("age",
                                   None,
                                   None,
                                   secret = Some(false),
                                   `type` = ParameterType.Integer,
                                   orderIndex = None)
          )
        ),
        parameterValues = Map("id" -> StringParameterValue("Frank"), "age" -> IntParameterValue(50))
      )
      storage.deleteInstance(instance) should throwA[IllegalStateException]
    }

    "should not allow writeInstance if closed" in {
      val storage = testStorage
      storage.close()
      val instance = Instance(
        id = "1",
        template = Template(
          id = "1",
          template = "\"{{id}} {{age}}\"",
          description = "desc",
          parameterInfos = Map(
            "id" -> ParameterInfo("id", None, None, None, ParameterType.Raw, None),
            "age" -> ParameterInfo("age",
                                   None,
                                   None,
                                   secret = Some(false),
                                   `type` = ParameterType.Integer,
                                   orderIndex = None)
          )
        ),
        parameterValues = Map("id" -> StringParameterValue("Frank"), "age" -> IntParameterValue(50))
      )
      storage.writeInstance(instance) should throwA[IllegalStateException]
    }

  }

} 
Example 4
Source File: LoggingSpec.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli

import org.mockito.{ArgumentCaptor, Matchers}
import org.scalacheck.Gen
import org.specs2.ScalaCheck
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification

import scala.util.matching.Regex

class LoggingSpec extends Specification with Mockito with ScalaCheck {
  import logging._

  trait F[T] {
    def body(): T

    def log(message: String): Unit
  }

  "logging the execution time" should {

    "execute the block just once" in {
      val f = mock[F[Unit]]

      logExecutionTime("foo") {
        f.body()
      }(Function.const(()))

      there was one(f).body()
      there was no(f).log(Matchers.any[String]())
    }

    "invokes the log function" in prop { label: String =>
      val f = mock[F[Int]]

      logExecutionTime(label) {
        42
      }(f.log(_))

      val message = ArgumentCaptor.forClass(classOf[String])
      there was one(f).log(message.capture())
      message.getValue must beMatching(s"${Regex.quote(label)} took \\d+ ms")

      there was no(f).body()
    }.setGen(Gen.identifier.label("label"))

    "returns the result of the body" in prop { ret: Int =>
      logExecutionTime("foo") {
        ret
      }(Function.const(())) === ret
    }
  }

} 
Example 5
Source File: NodeSpec.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.nomad.models

import de.frosner.broccoli.util
import org.specs2.mutable.Specification
import play.api.libs.json.Json

class NodeSpec extends Specification {
  "Node" should {
    "decode from JSON" in {
      val node = Json
        .parse(util.Resources.readAsString("/de/frosner/broccoli/services/nomad/node.json"))
        .validate[Node]
        .asEither

      node should beRight(
        Node(
          id = shapeless.tag[Node.Id]("4beac5b7-3974-3ddf-b572-9db5906fb891"),
          name = shapeless.tag[Node.Name]("vc31"),
          httpAddress = shapeless.tag[Node.HttpAddress]("127.0.0.1:4646")
        ))
    }
  }
} 
Example 6
Source File: AllocationSpec.scala    From cluster-broccoli   with Apache License 2.0 5 votes vote down vote up
package de.frosner.broccoli.nomad.models

import de.frosner.broccoli.util
import org.specs2.mutable.Specification
import play.api.libs.json.Json

class AllocationSpec extends Specification {

  "Allocation" should {

    "decode from JSON" in {
      val allocations = Json
        .parse(util.Resources.readAsString("/de/frosner/broccoli/services/nomad/allocations.json"))
        .validate[List[Allocation]]
        .asEither

      allocations should beRight(
        List(Allocation(
          id = shapeless.tag[Allocation.Id]("520bc6c3-53c9-fd2e-5bea-7d0b9dbef254"),
          jobId = shapeless.tag[Job.Id]("tvftarcxrPoy9wNhghqQogihjha"),
          nodeId = shapeless.tag[Node.Id]("cf3338e9-5ed0-88ef-df7b-9dd9708130c8"),
          clientStatus = ClientStatus.Running,
          taskStates = Map(shapeless.tag[Task.Name]("http-task") -> TaskStateEvents(TaskState.Running))
        )))
    }
  }
} 
Example 7
Source File: GeohashTest.scala    From sfseize   with Apache License 2.0 5 votes vote down vote up
package org.eichelberger.sfc.examples

import com.typesafe.scalalogging.slf4j.LazyLogging
import org.eichelberger.sfc.SpaceFillingCurve._
import org.eichelberger.sfc.study.composition.CompositionSampleData._
import org.eichelberger.sfc.utils.Timing
import org.eichelberger.sfc.{DefaultDimensions, Dimension}
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class GeohashTest extends Specification with LazyLogging {
  val xCville = -78.488407
  val yCville = 38.038668

  "Geohash example" should {
    val geohash = new Geohash(35)

    "encode/decode round-trip for an interior point" >> {
      // encode
      val hash = geohash.pointToHash(Seq(xCville, yCville))
      hash must equalTo("dqb0muw")

      // decode
      val cell = geohash.hashToCell(hash)
      println(s"[Geohash example, Charlottesville] POINT($xCville $yCville) -> $hash -> $cell")
      cell(0).containsAny(xCville) must beTrue
      cell(1).containsAny(yCville) must beTrue
    }

    "encode/decode properly at the four corners and the center" >> {
      for (x <- Seq(-180.0, 0.0, 180.0); y <- Seq(-90.0, 0.0, 90.0)) {
        // encode
        val hash = geohash.pointToHash(Seq(x, y))

        // decode
        val cell = geohash.hashToCell(hash)
        println(s"[Geohash example, extrema] POINT($x $y) -> $hash -> $cell")
        cell(0).containsAny(x) must beTrue
        cell(1).containsAny(y) must beTrue
      }

      // degenerate test outcome
      1 must equalTo(1)
    }

    def getCvilleRanges(curve: Geohash): (OrdinalPair, OrdinalPair, Iterator[OrdinalPair]) = {
      val lonIdxRange = OrdinalPair(
        curve.children(0).asInstanceOf[Dimension[Double]].index(bboxCville._1),
        curve.children(1).asInstanceOf[Dimension[Double]].index(bboxCville._3)
      )
      val latIdxRange = OrdinalPair(
        curve.children(0).asInstanceOf[Dimension[Double]].index(bboxCville._2),
        curve.children(1).asInstanceOf[Dimension[Double]].index(bboxCville._4)
      )
      val query = Query(Seq(OrdinalRanges(lonIdxRange), OrdinalRanges(latIdxRange)))
      val cellQuery = Cell(Seq(
        DefaultDimensions.createDimension("x", bboxCville._1, bboxCville._3, 0),
        DefaultDimensions.createDimension("y", bboxCville._2, bboxCville._4, 0)
      ))
      (lonIdxRange, latIdxRange, curve.getRangesCoveringCell(cellQuery))
    }
    
    "generate valid selection indexes" >> {
      val (_, _, ranges) = getCvilleRanges(geohash)

      ranges.size must equalTo(90)
    }
    
    "report range efficiency" >> {
      def atPrecision(xBits: OrdinalNumber, yBits: OrdinalNumber): (Long, Long) = {
        val curve = new Geohash(xBits + yBits)
        val (lonRange, latRange, ranges) = getCvilleRanges(curve)
        (lonRange.size * latRange.size, ranges.size.toLong)
      }

      for (dimPrec <- 10 to 25) {
        val ((numCells, numRanges), ms) = Timing.time{ () => atPrecision(dimPrec, dimPrec - 1) }
        println(s"[ranges across scales, Charlottesville] precision ($dimPrec, ${dimPrec - 1}) -> $numCells / $numRanges = ${numCells / numRanges} in $ms milliseconds")
      }

      1 must equalTo(1)
    }
  }

} 
Example 8
Source File: LexicographicTest.scala    From sfseize   with Apache License 2.0 5 votes vote down vote up
package org.eichelberger.sfc.utils

import com.typesafe.scalalogging.slf4j.LazyLogging
import org.eichelberger.sfc.SpaceFillingCurve.{OrdinalVector, ords2ordvec}
import org.eichelberger.sfc.{DefaultDimensions, ZCurve}
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class LexicographicTest extends Specification with LazyLogging {
  sequential
  
  "Lexicographical encoding" should {
    val precisions = new ords2ordvec(Seq(18L, 17L)).toOrdinalVector

    val sfc = ZCurve(precisions)

    val Longitude = DefaultDimensions.createLongitude(18L)
    val Latitude = DefaultDimensions.createLatitude(17L)

    "work for a known point" >> {
      val x = -78.488407
      val y = 38.038668

      val point = OrdinalVector(Longitude.index(x), Latitude.index(y))
      val idx = sfc.index(point)
      val gh = sfc.lexEncodeIndex(idx)

      gh must equalTo("dqb0muw")
    }

    "be consistent round-trip" >> {
      val xs = (-180.0 to 180.0 by 33.3333).toSeq ++ Seq(180.0)
      val ys = (-90.0 to 90.0 by 33.3333).toSeq ++ Seq(90.0)
      for (x <- xs; y <- ys) {
        val ix = Longitude.index(x)
        val iy = Latitude.index(y)
        val point = OrdinalVector(ix, iy)
        val idx = sfc.index(point)
        val gh = sfc.lexEncodeIndex(idx)
        val idx2 = sfc.lexDecodeIndex(gh)
        idx2 must equalTo(idx)
        val point2 = sfc.inverseIndex(idx2)
        point2(0) must equalTo(ix)
        point2(1) must equalTo(iy)
        val rx = Longitude.inverseIndex(ix)
        val ry = Latitude.inverseIndex(iy)

        val sx = x.formatted("%8.3f")
        val sy = y.formatted("%8.3f")
        val sidx = idx.formatted("%20d")
        println(s"[LEXI ROUND-TRIP] POINT($sx $sy) -> $sidx = $gh -> ($rx, $ry)")
      }

      // degenerate
      1 must equalTo(1)
    }
  }

  "multiple lexicographical encoders" should {
    "return different results for different base resolutions" >> {
      val x = -78.488407
      val y = 38.038668

      for (xBits <- 1 to 30; yBits <- xBits - 1 to xBits if yBits > 0) {
        val precisions = new ords2ordvec(Seq(xBits, yBits)).toOrdinalVector
        val sfc = ZCurve(precisions)

        val Longitude = DefaultDimensions.createLongitude(xBits)
        val Latitude = DefaultDimensions.createLatitude(yBits)

        val idx = sfc.index(OrdinalVector(Longitude.index(x), Latitude.index(y)))
        val gh = sfc.lexEncodeIndex(idx)
        val idx2 = sfc.lexDecodeIndex(gh)

        idx2 must equalTo(idx)

        println(s"[LEXI ACROSS RESOLUTIONS] mx $xBits + my $yBits = base ${sfc.alphabet.size}, idx $idx -> gh $gh -> $idx2")
      }

      // degenerate
      1 must equalTo(1)
    }
  }
} 
Example 9
Source File: BitManipulationsTest.scala    From sfseize   with Apache License 2.0 5 votes vote down vote up
package org.eichelberger.sfc.utils

import com.typesafe.scalalogging.slf4j.LazyLogging
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

import BitManipulations._

@RunWith(classOf[JUnitRunner])
class BitManipulationsTest extends Specification with LazyLogging {
  "static methods" should {
    "usedMask" >> {
      // single bits
      for (pos <- 0 to 62) {
        val v = 1L << pos.toLong
        val actual = usedMask(v)
        val expected = (1L << (pos + 1L)) - 1L
        println(s"[usedMask single bit]  pos $pos, value $v, actual $actual, expected $expected")
        actual must equalTo(expected)
      }

      // full bit masks
      for (pos <- 0 to 62) {
        val expected = (1L << (pos.toLong + 1L)) - 1L
        val actual = usedMask(expected)
        println(s"[usedMask full bit masks]  pos $pos, value $expected, actual $actual, expected $expected")
        actual must equalTo(expected)
      }

      usedMask(0) must equalTo(0)
    }

    "sharedBitPrefix" >> {
      sharedBitPrefix(2, 3) must equalTo(2)
      sharedBitPrefix(178, 161) must equalTo(160)
    }

    "common block extrema" >> {
      commonBlockMin(178, 161) must equalTo(160)
      commonBlockMax(178, 161) must equalTo(191)
    }
  }
} 
Example 10
Source File: CompositionParserTest.scala    From sfseize   with Apache License 2.0 5 votes vote down vote up
package org.eichelberger.sfc.utils

import com.typesafe.scalalogging.slf4j.LazyLogging
import org.eichelberger.sfc.SpaceFillingCurve.SpaceFillingCurve
import org.eichelberger.sfc.SpaceFillingCurve.SpaceFillingCurve
import org.eichelberger.sfc._
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class CompositionParserTest extends Specification {
  sequential

  def parsableCurve(curve: SpaceFillingCurve): String = curve match {
    case c: ComposedCurve =>
      c.delegate.name.charAt(0).toString + c.children.map {
        case d: Dimension[_]      => d.precision
        case s: SubDimension[_]   => s.precision
        case c: SpaceFillingCurve => parsableCurve(c)
      }.mkString("(", ", ", ")")
    case s =>
      s.name.charAt(0).toString + s.precisions.toSeq.map(_.toString).mkString("(", ", ", ")")
  }

  def eval(curve: ComposedCurve): Boolean = {
    val toParse: String = parsableCurve(curve)
    val parsed: ComposedCurve = CompositionParser.buildWholeNumberCurve(toParse)
    val fromParse: String = parsableCurve(parsed)
    println(s"[CURVE PARSER]\n  Input:  $toParse\n  Output:  $fromParse")
    toParse == fromParse
  }

  "simple expressions" should {
    val R23 = new ComposedCurve(
      RowMajorCurve(2, 3),
      Seq(
        DefaultDimensions.createIdentityDimension(2),
        DefaultDimensions.createIdentityDimension(3)
      )
    )
    val H_2_R23 = new ComposedCurve(
      CompactHilbertCurve(2),
      Seq(
        DefaultDimensions.createIdentityDimension(2),
        R23
      )
    )
    val Z_R23_2 = new ComposedCurve(
      ZCurve(2),
      Seq(
        R23,
        DefaultDimensions.createIdentityDimension(2)
      )
    )

    "parse correctly" >> {
      eval(R23) must beTrue
      eval(H_2_R23) must beTrue
      eval(Z_R23_2) must beTrue
    }
  }
} 
Example 11
Source File: LocalityEstimatorTest.scala    From sfseize   with Apache License 2.0 5 votes vote down vote up
package org.eichelberger.sfc.utils

import com.typesafe.scalalogging.slf4j.LazyLogging
import org.eichelberger.sfc.{CompactHilbertCurve, RowMajorCurve, ZCurve}
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class LocalityEstimatorTest extends Specification with LazyLogging {
  sequential

  "locality" should {
    "evaluate on square 2D curves" >> {
      (1 to 6).foreach { p =>
        val locR = LocalityEstimator(RowMajorCurve(p, p)).locality
        println(s"[LOCALITY R($p, $p)] $locR")

        val locZ = LocalityEstimator(ZCurve(p, p)).locality
        println(s"[LOCALITY Z($p, $p)] $locZ")

        val locH = LocalityEstimator(CompactHilbertCurve(p, p)).locality
        println(s"[LOCALITY H($p, $p)] $locH")
      }

      1 must beEqualTo(1)
    }

    "evaluate on non-square 2D curves" >> {
      (1 to 6).foreach { p =>
        val locR = LocalityEstimator(RowMajorCurve(p << 1L, p)).locality
        println(s"[LOCALITY R(${p*2}, $p)] $locR")

        val locZ = LocalityEstimator(ZCurve(p << 1L, p)).locality
        println(s"[LOCALITY Z(${p*2}, $p)] $locZ")

        val locH = LocalityEstimator(CompactHilbertCurve(p << 1L, p)).locality
        println(s"[LOCALITY H(${p*2}, $p)] $locH")
      }

      1 must beEqualTo(1)
    }
  }
} 
Example 12
Source File: RowMajorCurveTest.scala    From sfseize   with Apache License 2.0 5 votes vote down vote up
package org.eichelberger.sfc

import com.typesafe.scalalogging.slf4j.LazyLogging
import org.eichelberger.sfc.CompactHilbertCurve.Mask
import org.eichelberger.sfc.SpaceFillingCurve.{OrdinalVector, SpaceFillingCurve, _}
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class RowMajorCurveTest extends Specification with GenericCurveValidation with LazyLogging {
  sequential

  def curveName = "RowmajorCurve"

  def createCurve(precisions: OrdinalNumber*): SpaceFillingCurve =
    RowMajorCurve(precisions.toOrdinalVector)

  "rowmajor space-filling curves" should {
    "satisfy the ordering constraints" >> {
      timeTestOrderings() must beTrue
    }

    "identify sub-ranges correctly" >> {
      val sfc = createCurve(3, 3)
      val query = Query(Seq(OrdinalRanges(OrdinalPair(1, 2)), OrdinalRanges(OrdinalPair(1, 3))))
      val ranges = sfc.getRangesCoveringQuery(query).toList

      for (i <- 0 until ranges.size) {
        println(s"[rowmajor ranges:  query $query] range $i = ${ranges(i)}")
      }

      ranges(0) must equalTo(OrdinalPair(9, 11))
      ranges(1) must equalTo(OrdinalPair(17, 19))
    }
  }
} 
Example 13
Source File: ApiToEndpointLinkSpec.scala    From typedapi   with MIT License 5 votes vote down vote up
package typedapi.server

import typedapi.dsl._
import shapeless._

import org.specs2.mutable.Specification

final class ApiToEndpointLinkSpec extends Specification {

  import StatusCodes._

  case class Foo(name: String)

  "link api definitions to endpoint functions" >> { 
    val Api = := :> "find" :> typedapi.dsl.Segment[String]('name) :> 
                    Query[Int]('limit) :> 
                    Client.Header('hello, 'world) :> 
                    Server.Send('foo, 'bar) :> Server.Match[String]("hi") :>
                    Get[Json, List[Foo]]

    val endpoint0 = derive[Option](Api).from((name, limit, hi) => Some(successWith(Ok)(List(Foo(name)).take(limit))))
    endpoint0("john" :: 10 :: Map("hi" -> "whats", "hi-ho" -> "up") :: HNil) === Some(Right(Ok -> List(Foo("john"))))
    endpoint0.headers == Map("foo" -> "bar")
    endpoint0.method == "GET"
  }
} 
Example 14
Source File: AkkaHttpClientSupportSpec.scala    From typedapi   with MIT License 5 votes vote down vote up
package http.support.tests.client

import http.support.tests.{User, UserCoding, Api}
import typedapi.client._
import typedapi.client.akkahttp._
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.http.scaladsl.Http
import de.heikoseeberger.akkahttpcirce.FailFastCirceSupport
import org.specs2.mutable.Specification
import org.specs2.concurrent.ExecutionEnv

import scala.concurrent.duration._
import scala.concurrent.{Future, Await}

final class AkkaHttpClientSupportSpec(implicit ee: ExecutionEnv) extends Specification {

  import UserCoding._
  import FailFastCirceSupport._

  sequential

  implicit val timeout = 5.second
  implicit val system  = ActorSystem("akka-http-client-spec", defaultExecutionContext = Some(ee.ec))
  implicit val mat     = ActorMaterializer()

  import system.dispatcher

  val cm     = ClientManager(Http(), "http://localhost", 9001)
  val server = TestServer.start()

  "akka http client support" >> {
    val (p, s, q, header, fixed, clInH, clFixH, clColl, serMatchH, serSendH, m0, m1, m2, m3, m4, m5, _, _, _) = deriveAll(Api)

    "paths and segments" >> {
      p().run[Future](cm) must beEqualTo(User("foo", 27)).awaitFor(timeout)
      s("jim").run[Future](cm) must beEqualTo(User("jim", 27)).awaitFor(timeout)
    }
    
    "queries" >> {
      q(42).run[Future](cm) must beEqualTo(User("foo", 42)).awaitFor(timeout)
    }
    
    "headers" >> {
      header(42).run[Future](cm) must beEqualTo(User("foo", 42)).awaitFor(timeout)
      fixed().run[Future](cm) must beEqualTo(User("joe", 27)).awaitFor(timeout)
      clInH("jim").run[Future](cm) must beEqualTo(User("jim", 27)).awaitFor(timeout)
      clFixH().run[Future](cm) must beEqualTo(User("joe", 27)).awaitFor(timeout)
      clColl(Map("coll" -> "joe", "collect" -> "jim")).run[Future](cm) must beEqualTo(User("coll: joe,collect: jim", 27)).awaitFor(timeout)
      serMatchH().run[Future](cm) must beEqualTo(User("joe", 27)).awaitFor(timeout)
      serSendH().run[Future](cm) must beEqualTo(User("joe", 27)).awaitFor(timeout)
    }

    "methods" >> {
      m0().run[Future](cm) must beEqualTo(User("foo", 27)).awaitFor(timeout)
      m1().run[Future](cm) must beEqualTo(User("foo", 27)).awaitFor(timeout)
      m2(User("jim", 42)).run[Future](cm) must beEqualTo(User("jim", 42)).awaitFor(timeout)
      m3().run[Future](cm) must beEqualTo(User("foo", 27)).awaitFor(timeout)
      m4(User("jim", 42)).run[Future](cm) must beEqualTo(User("jim", 42)).awaitFor(timeout)
      m5(List("because")).run[Future](cm) must beEqualTo(User("foo", 27)).awaitFor(timeout)
    }

    step {
      server.shutdown.unsafeRunSync()
      Await.ready(system.terminate, timeout)
    }
  }
} 
Example 15
Source File: ScalajHttpClientSupportSpec.scala    From typedapi   with MIT License 5 votes vote down vote up
package http.support.tests.client

import http.support.tests.{UserCoding, User, Api}
import typedapi.client._
import typedapi.client.scalajhttp._
import scalaj.http.Http
import io.circe.parser._
import io.circe.syntax._
import org.specs2.mutable.Specification

final class ScalajHttpClientSupportSpec extends Specification {

  import UserCoding._

  sequential

  case class DecodeException(msg: String) extends Exception

  implicit val decoder = typedapi.util.Decoder[Id, User](json => decode[User](json).fold(
    error => Left(DecodeException(error.toString())),
    user  => Right(user)
  ))
  implicit val encoder = typedapi.util.Encoder[Id, User](user => user.asJson.noSpaces)

  val cm = ClientManager(Http, "http://localhost", 9001)

  val server = TestServer.start()

  "http4s client support" >> {
    val (p, s, q, header, fixed, clInH, clFixH, clColl, serMatchH, serSendH, m0, m1, m2, m3, m4, m5, _, _, _) = deriveAll(Api)

    "paths and segments" >> {
      p().run[Blocking](cm) === Right(User("foo", 27))
      s("jim").run[Blocking](cm) === Right(User("jim", 27))
    }
    
    "queries" >> {
      q(42).run[Blocking](cm) === Right(User("foo", 42))
    }
    
    "headers" >> {
      header(42).run[Blocking](cm) === Right(User("foo", 42))
      fixed().run[Blocking](cm) === Right(User("joe", 27))
      clInH("jim").run[Blocking](cm) === Right(User("jim", 27))
      clFixH().run[Blocking](cm) === Right(User("joe", 27))
      clColl(Map("coll" -> "joe", "collect" -> "jim")).run[Blocking](cm) === Right(User("collect: jim,coll: joe", 27))
      serMatchH().run[Blocking](cm) === Right(User("joe", 27))
      serSendH().run[Blocking](cm) === Right(User("joe", 27))
    }

    "methods" >> {
      m0().run[Blocking](cm) === Right(User("foo", 27))
      m1().run[Blocking](cm) === Right(User("foo", 27))
      m2(User("jim", 42)).run[Blocking](cm) === Right(User("jim", 42))
      m3().run[Blocking](cm) === Right(User("foo", 27))
      m4(User("jim", 42)).run[Blocking](cm) === Right(User("jim", 42))
      m5(List("because")).run[Blocking](cm) === Right(User("foo", 27))
    }

    "raw" >> {
      m0().run[Id].raw(cm).body === """{"name":"foo","age":27}"""
    }

    step {
      server.shutdown.unsafeRunSync()
    }
  }
} 
Example 16
Source File: Http4sClientSupportSpec.scala    From typedapi   with MIT License 5 votes vote down vote up
package http.support.tests.client

import http.support.tests.{UserCoding, User, Api}
import typedapi.client._
import typedapi.client.http4s._
import cats.effect.IO
import org.http4s.client.blaze.Http1Client
import org.specs2.mutable.Specification

final class Http4sClientSupportSpec extends Specification {

  import UserCoding._

  sequential

  val cm = ClientManager(Http1Client[IO]().unsafeRunSync, "http://localhost", 9001)

  val server = TestServer.start()

  "http4s client support" >> {
    val (p, s, q, header, fixed, clInH, clFixH, clColl, serMatchH, serSendH, m0, m1, m2, m3, m4, m5, _, _, _) = deriveAll(Api)

    "paths and segments" >> {
      p().run[IO](cm).unsafeRunSync() === User("foo", 27)
      s("jim").run[IO](cm).unsafeRunSync() === User("jim", 27)
    }
    
    "queries" >> {
      q(42).run[IO](cm).unsafeRunSync() === User("foo", 42)
    }
    
    "headers" >> {
      header(42).run[IO](cm).unsafeRunSync() === User("foo", 42)
      fixed().run[IO](cm).unsafeRunSync() === User("joe", 27)
      clInH("jim").run[IO](cm).unsafeRunSync === User("jim", 27)
      clFixH().run[IO](cm).unsafeRunSync() === User("joe", 27)
      clColl(Map("coll" -> "joe", "collect" -> "jim")).run[IO](cm).unsafeRunSync === User("coll: joe,collect: jim", 27)
      serMatchH().run[IO](cm).unsafeRunSync() === User("joe", 27)
      serSendH().run[IO](cm).unsafeRunSync() === User("joe", 27)
    }

    "methods" >> {
      m0().run[IO](cm).unsafeRunSync() === User("foo", 27)
      m1().run[IO](cm).unsafeRunSync() === User("foo", 27)
      m2(User("jim", 42)).run[IO](cm).unsafeRunSync() === User("jim", 42)
      m3().run[IO](cm).unsafeRunSync() === User("foo", 27)
      m4(User("jim", 42)).run[IO](cm).unsafeRunSync() === User("jim", 42)
      m5(List("because")).run[IO](cm).unsafeRunSync() === User("foo", 27)
    }

    step {
      server.shutdown.unsafeRunSync()
    }
  }
} 
Example 17
Source File: StubDslSpec.scala    From graphcool-framework   with Apache License 2.0 5 votes vote down vote up
package cool.graph.stub

import cool.graph.stub.StubDsl.Default.Request
import org.specs2.mutable.Specification

class StubDslSpec extends Specification {

  val path   = "some/freaking/path"
  val params = Map("a" -> 1)

  val responseBody = "the body"
  val response     = StaticStubResponse(333, responseBody)

  "using the default stub DSL" should {
    "produce a stub response with headers" in {
      val stub: Stub = Request("POST", path).stub(200, responseBody, Map("X-Test" -> "Test"))
      stub.stubbedResponse.headers("X-Test") must equalTo("Test")
      stub.stubbedResponse.body must equalTo(responseBody)
    }
  }
} 
Example 18
Source File: MultigetSpec.scala    From doobie-codegen   with MIT License 5 votes vote down vote up
package mdmoss.doobiegen.queries

import doobie.imports._
import mdmoss.doobiegen.db.gen
import org.specs2.matcher.ThrownExpectations
import org.specs2.mutable.Specification
import scalaz.concurrent.Task

object MultigetSpec extends Specification with ThrownExpectations {

  val xa = DriverManagerTransactor[Task]("org.postgresql.Driver", "jdbc:postgresql:gen", "test", "test")

  val Fk1RowCount       = 3
  val Fk2RowPerFk1Count = 3

  "multiget query functions" >> {
    val (fk1Rows, fk2Rows) = {
      for {
        fk1 <- gen.TestFk_1.createMany(List.fill(Fk1RowCount)(gen.TestFk_1.Shape()))
        fk2 <- gen.TestFk_2.createMany(fk1.flatMap(fkRow => List.fill(Fk2RowPerFk1Count)(gen.TestFk_2.Shape(fkRow.id))))
      } yield (fk1, fk2)
    }.transact(xa).unsafePerformSync

    "over primary keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).unsafePerformSync
        }
      }

      "return the same row multiple times if a duplicate primary key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).unsafePerformSync
        }
      }
    }

    "over foreign keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).unsafePerformSync.map(_.fk)
        }
      }

      "return the same matching set of rows multiple times if a duplicate foreign key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).unsafePerformSync.map(_.fk)
        }
      }

      "only return all matching rows" >> {
        val fk2RowsByFk = fk2Rows.groupBy(_.fk).mapValues(_.toSet)
        val fkToQuery = fk1Rows.tail.map(_.id)
        val expectedResult = fkToQuery.toSet.flatMap(fk2RowsByFk)
        expectedResult must_=== gen.TestFk_2.multigetByFk(fkToQuery).transact(xa).unsafePerformSync.toSet
      }
    }
  }
} 
Example 19
Source File: MultigetSpec.scala    From doobie-codegen   with MIT License 5 votes vote down vote up
package mdmoss.doobiegen.queries

import doobie.imports._
import mdmoss.doobiegen.db.gen
import org.specs2.matcher.ThrownExpectations
import org.specs2.mutable.Specification
import scalaz.concurrent.Task

object MultigetSpec extends Specification with ThrownExpectations {

  val xa = DriverManagerTransactor[Task]("org.postgresql.Driver", "jdbc:postgresql:gen", "test", "test")

  val Fk1RowCount       = 3
  val Fk2RowPerFk1Count = 3

  "multiget query functions" >> {
    val (fk1Rows, fk2Rows) = {
      for {
        fk1 <- gen.TestFk_1.createMany(List.fill(Fk1RowCount)(gen.TestFk_1.Shape()))
        fk2 <- gen.TestFk_2.createMany(fk1.flatMap(fkRow => List.fill(Fk2RowPerFk1Count)(gen.TestFk_2.Shape(fkRow.id))))
      } yield (fk1, fk2)
    }.transact(xa).run

    "over primary keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).run
        }
      }

      "return the same row multiple times if a duplicate primary key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).run
        }
      }
    }

    "over foreign keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).run.map(_.fk)
        }
      }

      "return the same matching set of rows multiple times if a duplicate foreign key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).run.map(_.fk)
        }
      }

      "only return all matching rows" >> {
        val fk2RowsByFk = fk2Rows.groupBy(_.fk).mapValues(_.toSet)
        val fkToQuery = fk1Rows.tail.map(_.id)
        val expectedResult = fkToQuery.toSet.flatMap(fk2RowsByFk)
        expectedResult must_=== gen.TestFk_2.multigetByFk(fkToQuery).transact(xa).run.toSet
      }
    }
  }
} 
Example 20
Source File: MultigetSpec.scala    From doobie-codegen   with MIT License 5 votes vote down vote up
package mdmoss.doobiegen.queries

import doobie.imports._
import mdmoss.doobiegen.db.gen
import org.specs2.matcher.ThrownExpectations
import org.specs2.mutable.Specification
import scalaz.concurrent.Task

object MultigetSpec extends Specification with ThrownExpectations {

  val xa = DriverManagerTransactor[Task]("org.postgresql.Driver", "jdbc:postgresql:gen", "test", "test")

  val Fk1RowCount       = 3
  val Fk2RowPerFk1Count = 3

  "multiget query functions" >> {
    val (fk1Rows, fk2Rows) = {
      for {
        fk1 <- gen.TestFk_1.createMany(List.fill(Fk1RowCount)(gen.TestFk_1.Shape()))
        fk2 <- gen.TestFk_2.createMany(fk1.flatMap(fkRow => List.fill(Fk2RowPerFk1Count)(gen.TestFk_2.Shape(fkRow.id))))
      } yield (fk1, fk2)
    }.transact(xa).unsafePerformSync

    "over primary keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).unsafePerformSync
        }
      }

      "return the same row multiple times if a duplicate primary key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).unsafePerformSync
        }
      }
    }

    "over foreign keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).unsafePerformSync.map(_.fk)
        }
      }

      "return the same matching set of rows multiple times if a duplicate foreign key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).unsafePerformSync.map(_.fk)
        }
      }

      "only return all matching rows" >> {
        val fk2RowsByFk = fk2Rows.groupBy(_.fk).mapValues(_.toSet)
        val fkToQuery = fk1Rows.tail.map(_.id)
        val expectedResult = fkToQuery.toSet.flatMap(fk2RowsByFk)
        expectedResult must_=== gen.TestFk_2.multigetByFk(fkToQuery).transact(xa).unsafePerformSync.toSet
      }
    }
  }
} 
Example 21
Source File: MultigetSpec.scala    From doobie-codegen   with MIT License 5 votes vote down vote up
package mdmoss.doobiegen.queries

import doobie.imports._
import mdmoss.doobiegen.db.gen
import org.specs2.matcher.ThrownExpectations
import org.specs2.mutable.Specification
import scalaz.concurrent.Task

object MultigetSpec extends Specification with ThrownExpectations {

  val xa = DriverManagerTransactor[Task]("org.postgresql.Driver", "jdbc:postgresql:gen", "test", "test")

  val Fk1RowCount       = 3
  val Fk2RowPerFk1Count = 3

  "multiget query functions" >> {
    val (fk1Rows, fk2Rows) = {
      for {
        fk1 <- gen.TestFk_1.createMany(List.fill(Fk1RowCount)(gen.TestFk_1.Shape()))
        fk2 <- gen.TestFk_2.createMany(fk1.flatMap(fkRow => List.fill(Fk2RowPerFk1Count)(gen.TestFk_2.Shape(fkRow.id))))
      } yield (fk1, fk2)
    }.transact(xa).run

    "over primary keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).run
        }
      }

      "return the same row multiple times if a duplicate primary key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).run
        }
      }
    }

    "over foreign keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).run.map(_.fk)
        }
      }

      "return the same matching set of rows multiple times if a duplicate foreign key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).run.map(_.fk)
        }
      }

      "only return all matching rows" >> {
        val fk2RowsByFk = fk2Rows.groupBy(_.fk).mapValues(_.toSet)
        val fkToQuery = fk1Rows.tail.map(_.id)
        val expectedResult = fkToQuery.toSet.flatMap(fk2RowsByFk)
        expectedResult must_=== gen.TestFk_2.multigetByFk(fkToQuery).transact(xa).run.toSet
      }
    }
  }
} 
Example 22
Source File: MultigetSpec.scala    From doobie-codegen   with MIT License 5 votes vote down vote up
package mdmoss.doobiegen.queries

import doobie.imports._
import org.specs2.matcher.ThrownExpectations
import org.specs2.mutable.Specification
import scalaz.concurrent.Task

import mdmoss.doobiegen.db.gen

object MultigetSpec extends Specification with ThrownExpectations {

  val xa = DriverManagerTransactor[Task]("org.postgresql.Driver", "jdbc:postgresql:gen", "test", "test")

  val Fk1RowCount       = 3
  val Fk2RowPerFk1Count = 3

  "multiget query functions" >> {
    val (fk1Rows, fk2Rows) = {
      for {
        fk1 <- gen.TestFk_1.createMany(List.fill(Fk1RowCount)(gen.TestFk_1.Shape()))
        fk2 <- gen.TestFk_2.createMany(fk1.flatMap(fkRow => List.fill(Fk2RowPerFk1Count)(gen.TestFk_2.Shape(fkRow.id))))
      } yield (fk1, fk2)
    }.transact(xa).unsafePerformSync

    "over primary keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).unsafePerformSync
        }
      }

      "return the same row multiple times if a duplicate primary key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        permutations must_=== permutations.map { rows =>
          gen.TestFk_1.multiget(rows.map(_.id)).transact(xa).unsafePerformSync
        }
      }
    }

    "over foreign keys must" >> {
      "order returned rows by input order" >> {
        val permutations = fk1Rows.permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).unsafePerformSync.map(_.fk)
        }
      }

      "return the same matching set of rows multiple times if a duplicate foreign key is specified in the input" >> {
        val permutations = (fk1Rows.tail.head :: fk1Rows).permutations.toList
        val expectedResult = permutations.map(_.flatMap(x => List.fill(Fk2RowPerFk1Count)(x.id)))
        expectedResult must_=== permutations.map { rows =>
          gen.TestFk_2.multigetByFk(rows.map(_.id)).transact(xa).unsafePerformSync.map(_.fk)
        }
      }

      "only return all matching rows" >> {
        val fk2RowsByFk = fk2Rows.groupBy(_.fk).mapValues(_.toSet)
        val fkToQuery = fk1Rows.tail.map(_.id)
        val expectedResult = fkToQuery.toSet.flatMap(fk2RowsByFk)
        expectedResult must_=== gen.TestFk_2.multigetByFk(fkToQuery).transact(xa).unsafePerformSync.toSet
      }
    }
  }
} 
Example 23
Source File: UpstreamServiceLocationSpec.scala    From shield   with MIT License 5 votes vote down vote up
package shield.routing

import org.specs2.mutable.Specification
import shield.config.{HttpServiceLocation, ServiceLocation}
import spray.http.Uri

import scala.util.Try

class UpstreamServiceLocationSpec extends Specification {
  "UpstreamServiceLocation" should {
    "accept valid https urls" in {
      val svc = HttpServiceLocation(Uri("https://example.edu"))
      svc.baseUrl.scheme must be equalTo "https"
      svc.baseUrl.authority.host.address must be equalTo "example.edu"
    }

    "accept valid http urls" in {
      val svc = HttpServiceLocation(Uri("http://example.edu"))
      svc.baseUrl.scheme must be equalTo "http"
      svc.baseUrl.authority.host.address must be equalTo "example.edu"
    }

    "use the correct port" in {
      val default_http = HttpServiceLocation(Uri("http://example.edu"))
      default_http.baseUrl.authority.port must be equalTo 0

      val custom_http = HttpServiceLocation(Uri("http://example.edu:5001"))
      custom_http.baseUrl.authority.port must be equalTo 5001

      val default_https = HttpServiceLocation(Uri("https://example.edu"))
      default_https.baseUrl.authority.port must be equalTo 0

      val custom_https = HttpServiceLocation(Uri("https://example.edu:8443"))
      custom_https.baseUrl.authority.port must be equalTo 8443
    }

    "reject unrecognized schemes" in {
      val ftp = Try { HttpServiceLocation(Uri("ftp://example.edu")) }
      ftp.isSuccess must be equalTo false

      val mailto = Try { HttpServiceLocation(Uri("mailto://example.edu")) }
      mailto.isSuccess must be equalTo false
    }

    "ignore case in urls" in {
      val svc = HttpServiceLocation(Uri("HTTPs://EXamPLE.edu"))
      svc.baseUrl.authority.host.address must be equalTo "example.edu"
      svc.baseUrl.scheme must be equalTo "https"
    }

    "reject urls with a path" in {
      val empty = Try { HttpServiceLocation(Uri("http://example.edu/")) }
      empty.isSuccess must be equalTo false

      val nonempty = Try { HttpServiceLocation(Uri("http://example.edu/foobar")) }
      nonempty.isSuccess must be equalTo false
    }

    "reject urls with a fragment" in {
      val empty = Try { HttpServiceLocation(Uri("http://example.edu#")) }
      empty.isSuccess must be equalTo false

      val nonempty = Try { HttpServiceLocation(Uri("http://example.edu#foobar")) }
      nonempty.isSuccess must be equalTo false
    }

    "reject urls with a query" in {
      val empty = Try { HttpServiceLocation(Uri("http://example.edu?")) }
      empty.isSuccess must be equalTo false

      val nonempty = Try { HttpServiceLocation(Uri("http://example.edu?foo=bar")) }
      nonempty.isSuccess must be equalTo false
    }

    "reject urls with a auth information" in {
      val empty = Try { HttpServiceLocation(Uri("http://:@example.edu")) }
      empty.isSuccess must be equalTo false

      val nonempty = Try { HttpServiceLocation(Uri("http://foo:[email protected]")) }
      nonempty.isSuccess must be equalTo false
    }

    "reject relative urls" in {
      val relative = Try { HttpServiceLocation(Uri("/foobar")) }
      relative.isSuccess must be equalTo false
    }

    "reject empty urls" in {
      val relative = Try { HttpServiceLocation(Uri("")) }
      relative.isSuccess must be equalTo false
    }
  }
} 
Example 24
Source File: RouteSortingSpec.scala    From shield   with MIT License 5 votes vote down vote up
package shield.routing

import org.specs2.mutable.Specification

class RouteSortingSpec extends Specification {
  "RouteSorting" should {
    "prefer more specific routes" in {
      val static = Path("/foo")
      val wild = Path("/{}")
      val path = Path("/{+}")

      static must beLessThan(wild)
      wild must beLessThan(path)
      static must beLessThan(path)
    }

    "give higher precedence to earlier static segments" in {
      val high = Path("/foo/{}")
      val low = Path("/{}/bar")

      high must beLessThan(low)
    }

    "use later segments as tie breakers" in {
      val fbf = Path("/foo/bar/fizz")
      val fb_ = Path("/foo/bar/{}")
      val f_f = Path("/foo/{}/fizz")
      val f__ = Path("/foo/{}/{}")

      fbf must beLessThan(fb_)
      fbf must beLessThan(f_f)
      fbf must beLessThan(f__)

      fb_ must beLessThan(f_f)
      fb_ must beLessThan(f__)

      f_f must beLessThan(f__)
    }

    "use Nil segments as lowest priority" in {
      // this may seem counter-intuitive at first glance.  However, if there exists a segment
      // after a regex or path segment, that is more specific than if the regex or path segment
      // consumed that later segment.
      val root = Path("/")
      val foo = Path("/foo")
      val foobar = Path("/foo/bar")
      val nested = Path("/foo/{}")

      root must beGreaterThan(foo)

      foo must beGreaterThan(foobar)
      foo must beGreaterThan(nested)
    }

    "treat path segments as lower priority than any number of static or wild segments" in {
      val wilds = Path("/foo/{}/{]/{}/{}")
      val nestedPath = Path("/foo/{+}")
      val pathSegment = Path("/{+}")

      wilds must beLessThan(nestedPath)
      wilds must beLessThan(pathSegment)

      nestedPath must beLessThan(pathSegment)
    }

    "prioritize path segments with trailing segments" in {
      val trailingStatic = Path("/{+}/foo")
      val trailingWild = Path("/{+}/{}")
      val path = Path("/{+}")

      trailingStatic must beLessThan(trailingWild)
      trailingStatic must beLessThan(path)

      trailingWild must beLessThan(path)
    }

    "handle edge cases" in {
      val root = Path("/")
      val empty = Path("")

      root must beEqualTo(empty)
    }
  }
} 
Example 25
Source File: PathParsingSpec.scala    From shield   with MIT License 5 votes vote down vote up
package shield.routing

import org.specs2.mutable.Specification
import spray.http.Uri

class PathParsingSpec extends Specification {
  "PathParsing" should {
    "handle empty paths" in {
      val emptyPath = Path("")

      emptyPath.segments must be equalTo Nil
    }

    "handle root paths" in {
      val rootPath = Path("/")

      rootPath.segments must be equalTo Nil
    }

    "handle static segments" in {
      val foo = Path("/foo")

      foo.segments must be equalTo List(StaticSegment("foo"))
    }

    "handle nested static segments" in {
      val foobar = Path("/foo/bar")

      foobar.segments must be equalTo List(StaticSegment("foo"), SlashSegment, StaticSegment("bar"))
    }

    "handle wildcard segments" in {
      val wild = Path("/foo/{bar}")
      wild.segments must be equalTo List(StaticSegment("foo"), SlashSegment, WildcardSegment)
    }

    "handle path segments" in {
      val path = Path("/foo/{+bar}")
      path.segments must be equalTo List(StaticSegment("foo"), SlashSegment, PathSegment)
    }

    "handles wildcards adjacent to static" in {
      val path = Path("/foo{.media}")
      path.segments must be equalTo List(StaticSegment("foo"), ExtensionSegment)
    }
  }
} 
Example 26
Source File: AuthUtilSpec.scala    From shield   with MIT License 5 votes vote down vote up
package shield.implicits

import com.amazonaws.auth.{AWSCredentials, AWSCredentialsProvider, AWSCredentialsProviderChain}
import org.specs2.mutable.Specification
import shield.aws.{AWSSigningConfig, AuthUtil}
import spray.http._


class AuthUtilSpec extends Specification {
  //Set consistant times that will produce consistant results for the tests
  val d1 = "20160315T141234Z"
  val d2 = "20160315"

  //Create a new config, these values are typically found in application.conf
  val config = new AWSSigningConfig("example-elasticsearch-host", "us-west-1", "es", true, new AWSCredentialsProviderChain(new StaticCredentialProvider()))

  "AuthUtil" should {

    "Use SHA256" in {
      println(AuthUtil.hashAsString("Hello world!"))
      AuthUtil.hashAsString("Hello world!") must be equalTo "c0535e4be2b79ffd93291305436bf889314e4a3faec05ecffcbb7df31ad9e51a"
      AuthUtil.hashAsString("123$%^abcDEF") must be equalTo "3b43642576e2c2cf349f34ff7f10e700bf485e6982647a50e361e883a5aaafa2"
      AuthUtil.hashAsString("  _***~`  ") must be equalTo "0597e54e8278a8673f09842d03e4af3a2688d1a15a55a640968382a5311416b4"
    }

    "Create canonical request hash" in {
      val request = new HttpRequest(HttpMethods.GET, Uri("https://example-elasticsearch-host.com:80"), List(), HttpEntity(HttpData("Sample data for a sample request ~*)@#$) @#(((")))

      println(AuthUtil.createCanonicalHash(request, "example-elasticsearch-host"))
      AuthUtil.createCanonicalHash(request, "example-elasticsearch-host") must be equalTo "05ef99e67afa47f06ed12084460baa4fca0bfbf92faebabed00fa78796028c5d"
    }

    "Create string to sign from a given canonical request" in {
      val canonicalRequestHash = "05ef99e67afa47f06ed12084460baa4fca0bfbf92faebabed00fa78796028c5d"

      AuthUtil.createStringToSign(d1, d2, config.region, config.service, canonicalRequestHash) must be equalTo "AWS4-HMAC-SHA256\n20160315\n20160315T141234Z/us-west-1/es/aws4_request\n05ef99e67afa47f06ed12084460baa4fca0bfbf92faebabed00fa78796028c5d"
    }

    "Create a signature" in {
      val stringToSign = "AWS4-HMAC-SHA256\n20160315\n20160315T141234Z/us-west-1/es/aws4_request\n05ef99e67afa47f06ed12084460baa4fca0bfbf92faebabed00fa78796028c5d"
      val signature = AuthUtil.hmacSHA256AsString("AWS4-HMAC-SHA256\n20160315\n20160315T141234Z/us-west-1/es/aws4_request\n05ef99e67afa47f06ed12084460baa4fca0bfbf92faebabed00fa78796028c5d", AuthUtil.createSignatureKey(config.getSecretKey(), d1, config.region, config.service))

      signature must be equalTo "68e811337b35141320236cf585a7fefad71d8948e4d1e9d5eb3583474d31eb6a"
    }
  }
}

//Create a static credential provider so that the access key and secret key stay the same for the purposes of testing
class StaticCredentialProvider extends AWSCredentialsProvider {
  override def refresh(): Unit = { }

  override def getCredentials: AWSCredentials = new AWSCredentials {
    override def getAWSAccessKeyId: String = "AccessKeyId"

    override def getAWSSecretKey: String = "SuperSecretKey"
  }
} 
Example 27
Source File: ImplicitsSpec.scala    From shield   with MIT License 5 votes vote down vote up
package shield.implicits

import org.specs2.mutable.Specification
import spray.http.HttpHeaders.RawHeader
import spray.http.{HttpResponse, HttpRequest}
import shield.implicits.HttpImplicits._

class ImplicitsSpec extends Specification {
  "HttpImplicits" should {
    "Replace a request header" in {
      var request = HttpRequest().withHeaders(
        RawHeader("sample", "header")
      )
      request = request.withReplacedHeaders(RawHeader("sample","newHeader"))
      request.headers.length must be equalTo 1
      request.headers(0).name must be equalTo "sample"
      request.headers(0).value must be equalTo "newHeader"
    }

    "Add a request header" in {
      var request = HttpRequest().withHeaders(
        RawHeader("sample", "header")
      )
      request = request.withAdditionalHeaders(
        RawHeader("additional", "testHeader")
      )

      request.headers.length must be equalTo 2
      request.headers.find(_.lowercaseName == "additional").get.value must be equalTo "testHeader"
      request.headers.find(_.lowercaseName == "sample").get.value must be equalTo "header"
    }

    "Strip a request header" in {
      var request = HttpRequest().withHeaders(
        RawHeader("sample", "header"),
        RawHeader("additional", "testHeader")
      )

      request = request.withStrippedHeaders(Set("sample"))
      request.headers.length must be equalTo 1
      request.headers(0).name must be equalTo "additional"
      request.headers(0).value must be equalTo "testHeader"
    }

    "Replace a response header" in {
      var response = HttpResponse().withHeaders(
        RawHeader("sample", "header")
      )
      response = response.withReplacedHeaders(RawHeader("sample","newHeader"))
      response.headers.length must be equalTo 1
      response.headers(0).name must be equalTo "sample"
      response.headers(0).value must be equalTo "newHeader"
    }

    "Add a response header" in {
      var response = HttpResponse().withHeaders(
        RawHeader("sample", "header")
      )
      response = response.withAdditionalHeaders(
        RawHeader("additional", "testHeader")
      )

      response.headers.length must be equalTo 2
      response.headers.find(_.lowercaseName == "additional").get.value must be equalTo "testHeader"
      response.headers.find(_.lowercaseName == "sample").get.value must be equalTo "header"
    }

    "Strip a response header" in {
      var response = HttpResponse().withHeaders(
        RawHeader("sample", "header"),
        RawHeader("additional", "testHeader")
      )

      response = response.withStrippedHeaders(Set("sample"))
      response.headers.length must be equalTo 1
      response.headers(0).name must be equalTo "additional"
      response.headers(0).value must be equalTo "testHeader"
    }

    "Strip a response header that is capitalized" in {
      var response = HttpResponse().withHeaders(
        RawHeader("X-Cache", "header"),
        RawHeader("additional","testHeader")
      )

      response = response.withStrippedHeaders(Set("X-Cache"))
      response.headers.length must be equalTo 1
      response.headers(0).name must be equalTo "additional"
      response.headers(0).value must be equalTo "testHeader"
    }
  }
} 
Example 28
Source File: HttpProxyLogicSpec.scala    From shield   with MIT License 5 votes vote down vote up
package shield.proxying

import org.specs2.mutable.Specification
import spray.http.HttpHeaders.RawHeader
import spray.http.{HttpHeaders, HttpRequest}
import shield.implicits.HttpImplicits._

class HttpProxyLogicSpec extends Specification {
  "HttpProxyLogic" should {
    "Use remote-address when adding to x-forwarded-for" in {
      val request = HttpRequest().withHeaders(
        RawHeader("X-Forwarded-For", "1.1.1.1"),
        RawHeader("Remote-Address", "2.2.2.2")
      ).withTrustXForwardedFor(1)
      getRemoteAddress(request) must be equalTo "2.2.2.2"
      getClientIp(request) must be equalTo "1.1.1.1"
    }

    "Add remote-address to x-forward-for header" in {
      val request = HttpRequest().withHeaders(
        RawHeader("X-Forwarded-For", "1.1.1.1, 2.2.2.2"),
        RawHeader("Remote-Address", "3.3.3.3")
      ).withTrustXForwardedFor(1)
      HttpProxyLogic.forwardedHeader(request.headers) must be equalTo RawHeader("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 3.3.3.3")
    }

    "Add remote-address to x-forwarded-for header" in {
      val request = HttpRequest().withHeaders(
        RawHeader("X-Forwarded-For", "1.1.1.1, 2.2.2.2"),
        RawHeader("Remote-Address", "3.3.3.3")
      )
      HttpProxyLogic.forwardedHeader(request.headers) must be equalTo RawHeader("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 3.3.3.3")
    }

    "If remote-address does not exist then append 127.0.0.1" in {
      val request = HttpRequest().withHeaders(
        RawHeader("X-Forwarded-For", "1.1.1.1, 2.2.2.2")
      )
      HttpProxyLogic.forwardedHeader(request.headers) must be equalTo RawHeader("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 127.0.0.1")
    }

    "Scrub requests of unrequired headers" in {
      val request = HttpRequest().withHeaders(
        HttpHeaders.`X-Forwarded-For`("1.1.1.1"),
        HttpHeaders.`Remote-Address`("2.2.2.2")
      ).withTrustXForwardedFor(1)

      HttpProxyLogic.scrubRequest(request).headers.exists(_.lowercaseName == "client-address") must be equalTo false
    }

    def getHeader(request: HttpRequest, header: String): Option[String] = {
      request.headers.find(_.lowercaseName == header).map(_.value)
    }

    def getRemoteAddress(request: HttpRequest) : String = {
      getHeader(request, "remote-address").get
    }

    def getClientIp(request: HttpRequest): String = {
      getHeader(request, "client-address").get
    }
  }
} 
Example 29
Source File: CatsResourceSpecs.scala    From cats-effect-testing   with Apache License 2.0 5 votes vote down vote up
package cats.effect.testing.specs2

import cats.effect._
import cats.effect.concurrent.Ref
import org.specs2.mutable.Specification

class CatsResourceSpecs extends Specification with CatsResourceIO[Ref[IO, Int]] {
  sequential

  override def resource: Resource[IO, Ref[IO, Int]] = Resource.make(Ref[IO].of(0))(_.set(Int.MinValue))

  "cats resource specifications" should {
    "run a resource modification" in withResource { ref => 
      ref.modify{a => 
        (a + 1, a)
      }.map(
        _ must_=== 0
      )
    }

    "be shared between tests" in withResource {ref => 
      ref.modify{a => 
        (a + 1, a)
      }.map(
        _ must_=== 1
      )
    }
  }
} 
Example 30
Source File: CatsEffectSpecs.scala    From cats-effect-testing   with Apache License 2.0 5 votes vote down vote up
package cats.effect.testing.specs2

import cats.effect.{IO, Resource}
import cats.effect.concurrent.{Ref, Deferred}
import cats.implicits._
import org.specs2.mutable.Specification

class CatsEffectSpecs extends Specification with CatsEffect {

  "cats effect specifications" should {
    "run a non-effectful test" in {
      true must beTrue
    }

    "run a simple effectful test" in IO {
      true must beTrue
      false must beFalse
    }

    "run a simple resource test" in {
      true must beTrue
    }.pure[Resource[IO, *]]

    "resource must be live for use" in {
      Resource.make(Ref[IO].of(true))(_.set(false)).map{ 
        _.get.map(_ must beTrue)
      }
    }

    "really execute effects" in {
      "First, this check creates a deferred value.".br

      val deferredValue = Deferred.unsafeUncancelable[IO, Boolean]

      "Then it executes two mutually associated steps:".br.tab

      "forcibly attempt to get the deferred value" in {
        deferredValue.get.unsafeRunTimed(Timeout) must beSome(true)
      }

      "Since specs2 executes steps in parallel by default, the second step gets executed anyway.".br

      "complete the deferred value inside IO context" in {
        deferredValue.complete(true) *> IO.pure(success)
      }

      "If effects didn't get executed then the previous step would fail after timeout.".br
    }

    // "timeout a failing test" in (IO.never: IO[Boolean])
  }
} 
Example 31
Source File: UserSyncTaskSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package tasks

import cats.effect.IO
import controllers.{Authenticator, UserAccountAccessor}
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import vinyldns.core.domain.membership._

class UserSyncTaskSpec extends Specification with Mockito {
  val notAuthUser: User = User("not-authorized", "accessKey", "secretKey")
  val lockedNotAuthUser: User = notAuthUser.copy(lockStatus = LockStatus.Locked)
  val mockAuthenticator: Authenticator = {
    val mockObject = mock[Authenticator]
    mockObject.getUsersNotInLdap(List(notAuthUser)).returns(IO(List(notAuthUser)))
    mockObject
  }

  val mockUserAccountAccessor: UserAccountAccessor = {
    val mockObject = mock[UserAccountAccessor]
    mockObject.getAllUsers.returns(IO(List(notAuthUser)))
    mockObject
      .lockUsers(List(notAuthUser))
      .returns(IO(List(lockedNotAuthUser)))
    mockObject
  }

  "SyncUserTask" should {
    "successfully lock unauthorized, non-test users" in {
      new UserSyncTask(mockUserAccountAccessor, mockAuthenticator)
        .run()
        .unsafeRunSync() must beEqualTo(())

      there.was(one(mockUserAccountAccessor).lockUsers(List(notAuthUser)))
    }

    "successfully process if no users are found" in {
      val mockAuth: Authenticator = mock[Authenticator]
      mockAuth.getUsersNotInLdap(List(notAuthUser)).returns(IO(Nil))

      val mockUsers = mock[UserAccountAccessor]
      mockUsers
        .lockUsers(Nil)
        .returns(IO(Nil))

      mockUsers.getAllUsers.returns(IO(List(notAuthUser)))

      new UserSyncTask(mockUsers, mockAuth)
        .run()
        .unsafeRunSync() must beEqualTo(())
    }
  }
} 
Example 32
Source File: MetaSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package models
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import play.api.Configuration

class MetaSpec extends Specification with Mockito {
  "Meta" should {
    "load from config" in {
      val config = Map("vinyldns.version" -> "foo-bar")
      Meta(Configuration.from(config)).version must beEqualTo("foo-bar")
    }
    "default to false if shared-display-enabled is not found" in {
      val config = Map("vinyldns.version" -> "foo-bar")
      Meta(Configuration.from(config)).sharedDisplayEnabled must beFalse
    }
    "set to true if shared-display-enabled is true in config" in {
      val config = Map("shared-display-enabled" -> true)
      Meta(Configuration.from(config)).sharedDisplayEnabled must beTrue
    }
    "get the batch-change-limit value in config" in {
      val config = Map("batch-change-limit" -> 21)
      Meta(Configuration.from(config)).batchChangeLimit must beEqualTo(21)
    }
    "default to 1000 if batch-change-limit is not found" in {
      val config = Map("vinyldns.version" -> "foo-bar")
      Meta(Configuration.from(config)).batchChangeLimit must beEqualTo(1000)
    }
    "get the default-ttl value in config" in {
      val config = Map("default-ttl" -> 7210)
      Meta(Configuration.from(config)).defaultTtl must beEqualTo(7210)
    }
    "default to 7200 if default-ttl is not found" in {
      val config = Map("vinyldns.version" -> "foo-bar")
      Meta(Configuration.from(config)).defaultTtl must beEqualTo(7200)
    }
    "default to false if manual-batch-review-enabled is not found" in {
      val config = Map("vinyldns.version" -> "foo-bar")
      Meta(Configuration.from(config)).manualBatchChangeReviewEnabled must beFalse
    }
    "set to true if manual-batch-review-enabled is true in config" in {
      val config = Map("manual-batch-review-enabled" -> true)
      Meta(Configuration.from(config)).manualBatchChangeReviewEnabled must beTrue
    }
    "default to false if scheduled-batch-change-enabled is not found" in {
      val config = Map("vinyldns.version" -> "foo-bar")
      Meta(Configuration.from(config)).scheduledBatchChangesEnabled must beFalse
    }
    "set to true if scheduled-batch-change-enabled is true in config" in {
      val config = Map("scheduled-changes-enabled" -> true)
      Meta(Configuration.from(config)).scheduledBatchChangesEnabled must beTrue
    }
  }
} 
Example 33
Source File: CustomLinksSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package models

import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import play.api.Configuration

class CustomLinksSpec extends Specification with Mockito {
  "CustomLinks" should {
    "load link from config" in {
      val linkOne = CustomLink(false, true, "title 1", "href 1", "icon 1")
      val config = Map(
        "links" -> List(
          Map(
            "displayOnSidebar" -> linkOne.displayOnSidebar,
            "displayOnLoginScreen" -> linkOne.displayOnLoginScreen,
            "title" -> linkOne.title,
            "href" -> linkOne.href,
            "icon" -> linkOne.icon
          )
        )
      )
      val customLinks = CustomLinks(Configuration.from(config))
      customLinks.links must beEqualTo(List[CustomLink](linkOne))
    }

    "load multiple links from config" in {
      val linkOne = CustomLink(false, true, "title 1", "href 1", "icon 1")
      val linkTwo = CustomLink(true, false, "title 2", "href 2", "icon 2")
      val config = Map(
        "links" -> List(
          Map(
            "displayOnSidebar" -> linkOne.displayOnSidebar,
            "displayOnLoginScreen" -> linkOne.displayOnLoginScreen,
            "title" -> linkOne.title,
            "href" -> linkOne.href,
            "icon" -> linkOne.icon
          ),
          Map(
            "displayOnSidebar" -> linkTwo.displayOnSidebar,
            "displayOnLoginScreen" -> linkTwo.displayOnLoginScreen,
            "title" -> linkTwo.title,
            "href" -> linkTwo.href,
            "icon" -> linkTwo.icon
          )
        )
      )
      val customLinks = CustomLinks(Configuration.from(config))
      customLinks.links must beEqualTo(List[CustomLink](linkOne, linkTwo))
    }

    "load empty list if no links in config" in {
      val customLinks = CustomLinks(Configuration.from(Map()))
      customLinks.links must beEqualTo(List[CustomLink]())
    }
  }
} 
Example 34
Source File: UserAccountAccessorSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package controllers

import cats.effect.IO
import org.joda.time.DateTime
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import org.specs2.specification.BeforeEach
import vinyldns.core.domain.membership._

class UserAccountAccessorSpec extends Specification with Mockito with BeforeEach {

  private val user = User(
    "fbaggins",
    "key",
    "secret",
    Some("Frodo"),
    Some("Baggins"),
    Some("[email protected]"),
    DateTime.now,
    "frodo-uuid"
  )

  private val userLog = UserChange(
    "frodo-uuid",
    user,
    "fbaggins",
    DateTime.now,
    None,
    UserChangeType.Create
  ).toOption.get

  private val mockRepo = mock[UserRepository]
  private val mockChangeRepo = mock[UserChangeRepository]
  private val underTest = new UserAccountAccessor(mockRepo, mockChangeRepo)

  protected def before: Any =
    org.mockito.Mockito.reset(mockRepo, mockChangeRepo)

  "UserAccountAccessor" should {
    "return the user when storing a user that does not exist already" in {
      mockRepo.save(any[User]).returns(IO.pure(user))
      mockChangeRepo.save(any[UserChange]).returns(IO.pure(userLog))
      underTest.create(user).unsafeRunSync() must beEqualTo(user)
      there.was(one(mockChangeRepo).save(any[UserChange]))
    }

    "return the new user when storing a user that already exists in the store" in {
      val newUser = user.copy(accessKey = "new-key", secretKey = "new-secret")
      mockRepo.save(any[User]).returns(IO.pure(newUser))
      mockChangeRepo.save(any[UserChange]).returns(IO.pure(userLog))
      underTest.update(newUser, user).unsafeRunSync() must beEqualTo(newUser)
      there.was(one(mockChangeRepo).save(any[UserChange]))
    }

    "return the user when retrieving a user that exists by name" in {
      mockRepo.getUserByName(user.userName).returns(IO.pure(Some(user)))
      mockRepo.getUser(user.userName).returns(IO.pure(None))
      underTest.get("fbaggins").unsafeRunSync() must beSome(user)
    }

    "return the user when retrieving a user that exists by user ID" in {
      mockRepo.getUserByName(user.id).returns(IO.pure(None))
      mockRepo.getUser(user.id).returns(IO.pure(Some(user)))
      underTest.get(user.id).unsafeRunSync() must beSome(user)
    }

    "return None when the user to be retrieved does not exist" in {
      mockRepo.getUserByName(any[String]).returns(IO.pure(None))
      mockRepo.getUser(any[String]).returns(IO.pure(None))
      underTest.get("fbaggins").unsafeRunSync() must beNone
    }

    "return the user by access key" in {
      mockRepo.getUserByAccessKey(user.id).returns(IO.pure(Some(user)))
      underTest.getUserByKey(user.id).unsafeRunSync() must beSome(user)
    }

    "return all users" in {
      val userList = List(user, user.copy(id = "user2", userName = "user2"))
      mockRepo.getAllUsers.returns(IO.pure(userList))
      underTest.getAllUsers.unsafeRunSync() must beEqualTo(userList)
    }

    "lock specified users" in {
      val lockedUser = user.copy(lockStatus = LockStatus.Locked)
      val lockedUserChange = UserChange.UpdateUser(
        user.copy(lockStatus = LockStatus.Locked),
        "system",
        DateTime.now,
        user
      )
      mockRepo.save(List(lockedUser)).returns(IO(List(lockedUser)))
      mockChangeRepo.save(any[UserChange]).returns(IO(lockedUserChange))
      underTest.lockUsers(List(user)).unsafeRunSync() must beEqualTo(List(lockedUser))
    }
  }
} 
Example 35
Source File: HealthControllerSpec.scala    From vinyldns   with Apache License 2.0 5 votes vote down vote up
package controllers

import cats.effect.IO
import org.junit.runner.RunWith
import org.specs2.mutable.Specification
import org.specs2.runner.JUnitRunner
import play.api.mvc.ControllerComponents
import play.api.test.Helpers.{GET, status}
import play.api.test.{FakeRequest, Helpers}
import vinyldns.core.health.HealthService
import vinyldns.core.health.HealthCheck._
import play.api.test.Helpers._

@RunWith(classOf[JUnitRunner])
class HealthControllerSpec extends Specification {

  val components: ControllerComponents = Helpers.stubControllerComponents()

  "HealthController" should {
    "send 200 if the healthcheck succeeds" in {
      val healthService =
        new HealthService(List(IO.unit.attempt.asHealthCheck(classOf[HealthControllerSpec])))
      val controller = new HealthController(components, healthService)

      val result = controller
        .health()
        .apply(FakeRequest(GET, "/health"))

      status(result) must beEqualTo(200)
    }
    "send 500 if a healthcheck fails" in {
      val err = IO
        .raiseError(new RuntimeException("bad!!"))
        .attempt
        .asHealthCheck(classOf[HealthControllerSpec])
      val healthService =
        new HealthService(List(IO.unit.attempt.asHealthCheck(classOf[HealthControllerSpec]), err))
      val controller = new HealthController(components, healthService)

      val result = controller
        .health()
        .apply(FakeRequest(GET, "/health"))

      status(result) must beEqualTo(500)
    }
  }
} 
Example 36
Source File: LongestIncreasingTest.scala    From coding-interview-questions-scala   with Apache License 2.0 5 votes vote down vote up
package org.questions.arrays

import org.specs2.mutable.Specification


trait LongestIncreasingTest extends Specification {
  val finder: LongestIncreasing

  "empty seq" should {
    "throw argument exception" in {
      finder.findLongestIncreasing(Nil) must throwA[IllegalArgumentException]
    }
  }

  "single item" should {
    "return a seq with that item" in {
      finder.findLongestIncreasing(Seq(1)) must be_===(Seq(1))
    }
  }

  "all increasing seq" should {
    "return the seq" in {
      finder.findLongestIncreasing(Seq(1, 2, 3, 4)) must be_===(Seq(1, 2, 3, 4))
    }
  }

  "increasing starts not in the beginning" should {
    "return the increasing seq" in {
      finder.findLongestIncreasing(Seq(8, 1, 2, 3)) must be_===(Seq(1, 2, 3))
    }
  }

  "findLongestIncreasing" should {
    "return the longest increasing seq" in {
      finder.findLongestIncreasing(Seq(1, 2, 0, 0, 3, 0, 4, 5, 6, 5, 2, 3)) must be_===(Seq(0, 4, 5, 6))
    }
  }
}

class LongestIncreasingRecursiveTest extends LongestIncreasingTest {
  override val finder = new LongestIncreasingRecursive
}

class LongestIncreasingIterativeTest extends LongestIncreasingTest {
  override val finder = new LongestIncreasingIterative
} 
Example 37
Source File: TwoSumTest.scala    From coding-interview-questions-scala   with Apache License 2.0 5 votes vote down vote up
package org.questions.arrays

import org.specs2.matcher.Matcher
import org.specs2.mutable.Specification
import org.specs2.specification.Scope


class TwoSumTest extends Specification {

  class Context extends Scope {
    val arrayUtils = new TwoSum

    def sumTo(sum: Int): Matcher[(Int, Int)] = (_: (Int, Int)) match {
      case (a, b) => a + b must be_===(sum)
    }
  }

  "under 2 elements in seq" should {
    "be none" in new Context {
      arrayUtils.findPairSum(Seq(1), 8) must beNone
    }
  }

  "two elements that sum" should {
    "return these elements" in new Context {
      arrayUtils.findPairSum(Seq(2, 3), 5) must beSome(sumTo(5))
    }
  }

  "two elements that doesn't sum" should {
    "return these none" in new Context {
      arrayUtils.findPairSum(Seq(2, 3), 4) must beNone
    }
  }

  "more elements that sum" should {
    "return the sum" in new Context {
      arrayUtils.findPairSum(Seq(1, 2, 3), 5) must beSome(sumTo(5))
    }
  }
} 
Example 38
Source File: WildCardMatchingTest.scala    From coding-interview-questions-scala   with Apache License 2.0 5 votes vote down vote up
package org.questions.strings

import org.specs2.mutable.Specification


class WildCardMatchingTest extends Specification {
  val matcher = new WildCardMatching


  "same string" should {
    "be matching" in {
      val string = "abc"
      matcher.isMatching(string, string) must beTrue
    }
  }

  "different string" should {
    "not match" in {
      matcher.isMatching("ab", "bc") must beFalse
    }
  }

  "question mark" should {
    "allow to skip one char" in {
      matcher.isMatching("abc", "a?c") must beTrue
    }
  }

  "star" should {
    "replace many chars" in {
      matcher.isMatching("abcd", "a*d") must beTrue
    }

    "replace zero chars" in {
      matcher.isMatching("abc", "ab*c") must beTrue
    }

    "replace one char" in {
      matcher.isMatching("abc", "a*c") must beTrue
    }

    "match if star is in the end" in {
      matcher.isMatching("abc", "a*") must beTrue
    }
  }
} 
Example 39
Source File: ParenthesesValidatorTest.scala    From coding-interview-questions-scala   with Apache License 2.0 5 votes vote down vote up
package org.questions.strings

import org.specs2.mutable.Specification


class ParenthesesValidatorTest extends Specification {
  val validator = new ParenthesesValidator

  "empty parentheses" should {
    "be valid" in {
      validator.validate("(abc)") must beTrue
    }
  }

  "no parentheses" should {
    "be valid" in {
      validator.validate("abc") must beTrue
    }
  }

  "unclosed" should {
    "be invalid" in {
      validator.validate("((abc)") must beFalse
    }
  }

  "unopened" should {
    "be invalid" in {
      validator.validate("(abc))") must beFalse
    }

    "be invalid in beginning" in {
      validator.validate(")abc(") must beFalse
    }
  }
} 
Example 40
Source File: FibonacciTest.scala    From coding-interview-questions-scala   with Apache License 2.0 5 votes vote down vote up
package org.questions

import org.questions.fibonacci.{Fibonacci, Iterative, Recursive, TailRecursion}
import org.scalacheck.Gen
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}


trait FibonacciTest extends Specification with FibonacciProperty {
  val fib: Fibonacci

  "negative input" should {
    "be invalid" in {
      fib.nth(-1) must throwA[IllegalArgumentException]
    }
  }

  "0th" should {
    "be 0" in {
      fib.nth(0) must be_===(0)
    }
  }

  "1st" should {
    "be 1" in {
      fib.nth(1) must be_===(1)
    }
  }

  "2nd" should {
    "be 1" in {
      fib.nth(2) must be_===(1)
    }
  }
}

trait BigN {
  self: FibonacciTest =>

  import scala.concurrent.ExecutionContext.Implicits.global

  "big N" should {
    "be computed in sub seconds" in {
      val calcBigN = Future.apply {
        fib.nth(100)
      }

      Await.ready(calcBigN, Duration("1 second")).isCompleted must beTrue
    }
  }
}

trait FibonacciProperty extends ScalaCheck {
  self: FibonacciTest =>

  val smallInteger = Gen.choose[Int](2,30)

  "fib(n)" should {
    "be equal to the sum of the results of last 2 elements" >> prop { n: Int =>
      fib.nth(n) must be_===(fib.nth(n - 1) + fib.nth(n - 2))
    }.setGen(smallInteger)
  }
}

class RecursiveTest extends FibonacciTest {
  override val fib = new Recursive
}

class IterativeTest extends FibonacciTest with BigN {
  override val fib = new Iterative
}

class TailRecursionTest extends FibonacciTest with BigN {
  override val fib: Fibonacci = new TailRecursion
} 
Example 41
Source File: CanvasTest.scala    From coding-interview-questions-scala   with Apache License 2.0 5 votes vote down vote up
package org.questions.fill

import org.specs2.mutable.Specification
import org.specs2.specification.Scope


class CanvasTest extends Specification {

  class Context extends Scope {
    private val sample =
      """............
        |.*******....
        |.*....***...
        |.**.....*...
        |..*....**...
        |...*****....""".stripMargin

    private def toCharsCanvas(s: String) =
      new CharsCanvas(s.lines.map(_.toCharArray).toArray)

    val canvas = toCharsCanvas(sample)
    val drawUtils = new DrawUtils(canvas)

    def >(canvas: Canvas) = {
      val (rows, cols) = canvas.getSize

      for {r <- 0 until rows} {
        for {c <- 0 until cols} {
          Predef.print(canvas.getColor(r, c))
        }
        println()
      }
    }
  }

  Seq((1, 100), (100, 1), (-1, 1), (1, -1)) foreach { case (x, y) =>
    "outside of the canvas" should {
      "result in error" in new Context {
        drawUtils.fill(x, y, 'X') must throwA[IndexOutOfBoundsException]
      }
    }
  }

  "adjacent fields with same color" should {
    "be filled" in new Context {
      drawUtils.fill(3, 4, '#')

      Seq((3, 5), (3, 3), (2, 4), (4, 4)) foreach { case (x, y) =>
        canvas.getColor(x, y) must be_===('#')
      }
    }
  }

  "adjacent fields with different color" should {
    "stay with previous color" in new Context {
      drawUtils.fill(0, 1, '#')
      canvas.getColor(1, 1) must be_===('*')
    }
  }

  "selected field" should {
    "be colored" in new Context {
      drawUtils.fill(0, 0, '#')
      canvas.getColor(0, 0) must be_===('#')
    }
  }

  "far fields that in same shape" should {
    "be colored" in new Context {
      drawUtils.fill(0, 0, '#')
      canvas.getColor(5, 11) must be_===('#')
    }
  }
} 
Example 42
Source File: KinesisPublisherPutRecordsCallResultsTest.scala    From gfc-aws-kinesis   with Apache License 2.0 5 votes vote down vote up
package com.gilt.gfc.aws.kinesis.client

import java.util.UUID

import com.amazonaws.services.kinesis.model.{PutRecordsRequestEntry, PutRecordsResultEntry}
import org.specs2.mutable.Specification

class KinesisPublisherPutRecordsCallResultsTest
  extends Specification {

  "KinesisPublisherPutRecordsCallResults" should {
    "handle empty results" in {
      val r = KinesisPublisherPutRecordsCallResults(Seq.empty)

      r.successes.isEmpty must_===(true)
      r.failures.isEmpty must_===(true)
      r.softFailures.isEmpty must_===(true)
      r.hardFailures.isEmpty must_===(true)
      r.isGenericServerError must_===(false)
    }


    "handle generic service errors" in {
      val r = KinesisPublisherPutRecordsCallResults(Seq(
        e -> None
      , e -> None
      ))

      r.successes.isEmpty must_===(true)
      r.failures.size must_===(2)
      r.softFailures.size must_===(2)
      r.hardFailures.isEmpty must_===(true)
      r.isGenericServerError must_===(true)
    }


    "handle successful calls" in {
      val r = KinesisPublisherPutRecordsCallResults(Seq(
        e -> re(null)
      , e -> re(null)
      ))

      r.successes.size must_===(2)
      r.failures.isEmpty must_===(true)
      r.softFailures.isEmpty must_===(true)
      r.hardFailures.isEmpty must_===(true)
      r.isGenericServerError must_===(false)
    }

    "handle partial batch failures" in {
      val r = KinesisPublisherPutRecordsCallResults(Seq(
        e -> re(null) // success
      , e -> re("blahblah") // 'hard' error, no retry
      , e -> re("foobar") // 'hard' error, no retry
      , e -> re("InternalFailure") // 'soft' error, should retry
      ))

      r.successes.size must_===(1)
      r.failures.size must_===(3)
      r.softFailures.size must_===(1)
      r.hardFailures.size must_===(2)
      r.isGenericServerError must_===(false)
    }
  }


  def e: PutRecordsRequestEntry = {
    new PutRecordsRequestEntry().withPartitionKey(UUID.randomUUID.toString)
  }

  def re( errCode: String
        ): Option[PutRecordsResultEntry] = {
    Some(new PutRecordsResultEntry().withErrorCode(errCode))
  }
} 
Example 43
Source File: PosixPrintPathSpecs.scala    From scala-pathy   with Apache License 2.0 5 votes vote down vote up
package pathy

import org.specs2.mutable.Specification
import pathy.Path._

class PosixPrintPathSpecs extends Specification {
  import posixCodec._

  "two directories" in {
    unsafePrintPath(dir("foo") </> file("bar")) must_=== "./foo/bar"
  }

  "file with two parents" in {
    unsafePrintPath(dir("foo") </> dir("bar") </> file("image.png")) must_=== "./foo/bar/image.png"
  }

  "file without extension" in {
    unsafePrintPath(file("image") <:> "png") must_=== "./image.png"
  }

  "file with extension" in {
    unsafePrintPath(file("image.jpg") <:> "png") must_=== "./image.png"
  }

  "printPath - ./../" in {
    unsafePrintPath(parentDir1(currentDir)) must_=== "./../"
  }
} 
Example 44
Source File: PathSpecs.scala    From scala-pathy   with Apache License 2.0 5 votes vote down vote up
package pathy

import slamdata.Predef._
import pathy.scalacheck._

import scala.Predef.identity

import org.scalacheck._, Arbitrary.arbitrary
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification
import scalaz.scalacheck.ScalazProperties._
import scalaz.syntax.foldable._

class PathSpecs extends Specification with ScalaCheck {
  import Path._, PathyArbitrary._

  "FileName" in {
    "order laws" >> order.laws[FileName]
  }

  "DirName" in {
    "order laws" >> order.laws[DirName]
  }

  "Path" in {
    implicit val arbitraryPath: Arbitrary[Path[Any,Any,Sandboxed]] =
      Arbitrary(Gen.oneOf(
        arbitrary[AbsFile[Sandboxed]],
        arbitrary[RelFile[Sandboxed]],
        arbitrary[AbsDir[Sandboxed]],
        arbitrary[RelDir[Sandboxed]]))

    "order laws" >> order.laws[Path[Any,Any,Sandboxed]]
  }

  "</> - ./../foo/" in {
    posixCodec.unsafePrintPath(parentDir1(currentDir) </> unsandbox(dir("foo"))) must_== "./../foo/"
  }

  "parentDir1 - ./../foo/../" in {
    posixCodec.unsafePrintPath((parentDir1(currentDir) </> unsandbox(dir("foo"))) </> parentDir1(currentDir)) must_== "./../foo/../"
  }

  "<::>" >> {
    "./../" in {
      posixCodec.unsafePrintPath(currentDir <::> currentDir) must_== "./../"
    }

    "./../foo/" in {
      posixCodec.unsafePrintPath(currentDir <::> dir("foo")) must_== "./../foo/"
    }

    "./../foo/../" in {
      posixCodec.unsafePrintPath((currentDir <::> dir("foo")) <::> currentDir) must_== "./../foo/../"
    }
  }

  "canonicalize" >> {
    "1 down, 1 up" in {
      canonicalize(parentDir1(dir("foo"))) must_== currentDir
    }

    "2 down, 2 up" in {
      canonicalize(parentDir1(parentDir1(dir("foo") </> dir("bar")))) must_== currentDir
    }
  }

  "relativeTo" >> {
    "simple case" >> {
      (rootDir </> dir("foo")).relativeTo(rootDir) must_== Some(dir("foo"))
    }
    "return currentDir if same path" >> {
      (rootDir </> dir("foo")).relativeTo(rootDir </> dir("foo")) must_== Some(currentDir)
    }
  }

  "renameFile - single level deep" in {
    renameFile(file("image.png"), _.dropExtension) must_== file("image")
  }

  "sandbox - sandbox absolute dir to one level higher" in {
    sandbox(rootDir </> dir("foo"), rootDir </> dir("foo") </> dir("bar")) must beSome.which {
      _ must_== dir("bar")
    }
  }

  "depth - negative" in {
    depth(parentDir1(parentDir1(parentDir1(currentDir)))) must_== -3
  }

  "flatten - returns NEL of result of folding each layer of path" in {
    flatten(
      "r", "c", "p", identity, identity,
      currentDir </> dir("foo") </> dir("bar") </> file("flat.md")
    ).toList must_== List("c", "foo", "bar", "flat.md")
  }
} 
Example 45
Source File: IngressSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.networking

import org.specs2.mutable.Specification
import play.api.libs.json._
import skuber.LabelSelector.dsl._
import skuber._
import skuber.json.networking.format._


class IngressSpec extends Specification {
  "This is a unit specification for the skuber Ingress class. ".txt

  "An Ingress object can be written to Json and then read back again successfully" >> {
    val ingress=Ingress("example")
          .addHttpRule("example.com", Map(
            "/" -> "service:80",
            "/about" -> "another-service:http"
          ))

      val readIng = Json.fromJson[Ingress](Json.toJson(ingress)).get
      readIng mustEqual ingress
  }

  "An Ingress object with empty Path can be read directly from a JSON string" >> {
    val ingJsonStr =
      """
        |{
        |  "apiVersion": "networking.k8s.io/v1beta1",
        |  "kind": "Ingress",
        |  "metadata": {
        |    "creationTimestamp": "2017-04-02T19:39:34Z",
        |    "generation": 3,
        |    "labels": {
        |      "app": "ingress"
        |    },
        |    "name": "example-ingress",
        |    "namespace": "default",
        |    "resourceVersion": "1313499",
        |    "selfLink": "/apis/extensions/v1beta1/namespaces/default/ingresses/example",
        |    "uid": "192dd131-17dc-11e7-bd9c-0a5e79684354"
        |  },
        |  "spec": {
        |    "rules": [
        |      {
        |        "host": "example.com",
        |        "http": {
        |          "paths": [
        |            {
        |              "backend": {
        |                "serviceName": "service",
        |                "servicePort": "http"
        |              }
        |            }
        |          ]
        |        }
        |      }
        |    ],
        |    "tls": [
        |      {
        |        "hosts": ["abc","def"]
        |      }  
        |    ]
        |  },
        |  "status": {
        |    "loadBalancer": {
        |      "ingress": [
        |        {
        |          "hostname": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-1111111111.us-east-1.elb.amazonaws.com"
        |        }
        |      ]
        |    }
        |  }
        |}""".stripMargin

    val ing = Json.parse(ingJsonStr).as[Ingress]
    ing.kind mustEqual "Ingress"
    ing.name mustEqual "example-ingress"

    ing.spec.get.rules.head.host must beSome("example.com")
    ing.spec.get.rules.head.http.paths must_== List(Ingress.Path(
      path = "",
      backend = Ingress.Backend("service", "http")
    ))
    ing.spec.get.tls must_== List(Ingress.TLS(
      hosts = List("abc","def"),
      secretName = None
    ))

  }
} 
Example 46
Source File: SecretSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.json

import org.specs2.mutable.Specification
import skuber.{ObjectMeta, Secret} // for unit-style testing
import format._

import play.api.libs.json._


class SecretSpec extends Specification {

  "A Secret containing a byte array can symmetrically be written to json and the same value read back in" >> {
    val dataBytes = "hello".getBytes
    val secret = Secret(metadata = ObjectMeta("mySecret"), data = Map("key" -> dataBytes))
    val resultBytes = Json.fromJson[Secret](Json.toJson(secret)).get.data("key")
    dataBytes mustEqual resultBytes
  }
  "this can be done with an empty data map" >> {
    val mySecret = Secret(metadata = ObjectMeta("mySecret"))
    val json = Json.toJson(mySecret)
    val readSecret = Json.fromJson[Secret](Json.toJson(mySecret)).get
    mySecret mustEqual readSecret
  }
  "this can be done with the type member defined" >> {
    val mySecret = Secret(metadata = ObjectMeta("mySecret"), `type` = "myType")
    val readSecret = Json.fromJson[Secret](Json.toJson(mySecret)).get
    mySecret mustEqual readSecret
  }
} 
Example 47
Source File: PodPresetFormatSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.json

import java.net.URL

import org.specs2.execute.{Failure, Result}
import org.specs2.mutable.Specification
import play.api.libs.json._
import skuber._
import skuber.settings.PodPreset

import scala.io.Source


class PodPresetFormatSpec extends Specification {
  "This is a unit specification for the skuber PodPreset related json formatter.\n ".txt

  "a podpreset can be read and written as json successfully" >> {
    val podPresetJsonSource=Source.fromURL(getClass.getResource("/examplePodPreset.json"))
    val podPresetJsonStr = podPresetJsonSource.mkString
    val podPreset = Json.parse(podPresetJsonStr).as[PodPreset]

    // write and read it back in again and compare
    val json = Json.toJson(podPreset)
    val readPodPreset = Json.fromJson[PodPreset](json).get
    readPodPreset mustEqual podPreset
  }

} 
Example 48
Source File: AuthSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.model

import java.time.Instant

import org.specs2.mutable.Specification
import skuber.api.client._



class AuthSpec extends Specification {
  "This is a unit specification for the auth data model. ".txt
  
  
  // Auth
  "Auth toString works when empty" >> {
    NoAuth.toString mustEqual "NoAuth"
  }

  "CertAuth toString masks cert, key but not user" >> {
    val auth = CertAuth(
      clientCertificate = Right("secretPem".getBytes),
      clientKey = Right("secretKey".getBytes),
      user = Some("someUser")
    )
    auth.toString mustEqual "CertAuth(clientCertificate=<PEM masked> clientKey=<PEM masked> userName=someUser )"
  }

  "CertAuth toString doesn't mask username, certPath, keyPath" >> {
    val auth = CertAuth(
      clientCertificate = Left("certPath"),
      clientKey = Left("keyPath"),
      user = Option("aUser")
    )
    auth.toString mustEqual "CertAuth(clientCertificate=certPath clientKey=keyPath userName=aUser )"
  }

  "TokenAuth toString masks token" >> {
    TokenAuth("myToken").toString mustEqual "TokenAuth(token=<redacted>)"
  }

  "GcpAuth toString masks accessToken" >> {
    GcpAuth(accessToken = Some("MyAccessToken"), expiry = Some(Instant.now), cmdPath = "gcp", cmdArgs = "").toString mustEqual
      "GcpAuth(accessToken=<redacted>)"
  }

  "OidcAuth toString masks idToken" >> {
    OidcAuth(idToken = "MyToken").toString mustEqual "OidcAuth(idToken=<redacted>)"
  }

} 
Example 49
Source File: PodDisruptionBudgetSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.policy.v1beta1

import org.specs2.mutable.Specification
import play.api.libs.json.{JsSuccess, Json}
import skuber.LabelSelector.dsl._

class PodDisruptionBudgetSpec extends Specification {
  import PodDisruptionBudget._
  "A PodDisruptionBudget can" >> {
    "decoded from json" >> {
      val pdb = PodDisruptionBudget("someName")
        .withMaxUnavailable(Left(2))
        .withMinAvailable(Left(1))
        .withLabelSelector("application" is "someApplicationName")

      Json.parse(createJson("/examplePodDisruptionBudget.json")).validate[PodDisruptionBudget] mustEqual JsSuccess(pdb)
    }
    "encode to json" >> {
      Json.toJson(
        PodDisruptionBudget("someName")
          .withMaxUnavailable(Left(2))
          .withMinAvailable(Left(1))
          .withLabelSelector("application" is "someApplicationName")
      ) mustEqual Json.parse(createJson("/examplePodDisruptionBudget.json"))
    }
  }

  private def createJson(file: String): String = {
    val source = scala.io.Source.fromURL(getClass.getResource(file))
    try source.mkString finally source.close()
  }
} 
Example 50
Source File: StatefulSetSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.apps.v1

import org.specs2.mutable.Specification
import play.api.libs.json._
import skuber.LabelSelector.dsl._
import skuber._

class StatefulSetSpec extends Specification {
  "This is a unit specification for the skuber apps/v1 StatefulSet class. ".txt

  "A StatefulSet object can be constructed from a name and pod template spec" >> {
    val container=Container(name="example",image="example")
    val template=Pod.Template.Spec.named("example").addContainer(container)
    val stateSet=StatefulSet("example")
      .withReplicas(200)
      .withServiceName("nginx-service")
      .withTemplate(template)
      .withVolumeClaimTemplate(PersistentVolumeClaim("hello"))
    stateSet.spec.get.template mustEqual template
    stateSet.spec.get.serviceName mustEqual Some("nginx-service")
    stateSet.spec.get.replicas must beSome(200)
    stateSet.spec.get.volumeClaimTemplates.size mustEqual 1
    stateSet.name mustEqual "example"
    stateSet.status mustEqual None
  }

  "A StatefulSet object can be written to Json and then read back again successfully" >> {
    val container=Container(name="example",image="example")
    val template=Pod.Template.Spec.named("example").addContainer(container)
    val stateSet=StatefulSet("example")
      .withTemplate(template)
      .withLabelSelector(LabelSelector("live" doesNotExist, "microservice", "tier" is "cache", "env" isNotIn List("dev", "test")))


    val readSSet = Json.fromJson[StatefulSet](Json.toJson(stateSet)).get
    readSSet mustEqual stateSet
  }

  "A StatefulSet object properly writes with zero replicas" >> {
    val sset=StatefulSet("example").withReplicas(0)

    val writeSSet = Json.toJson(sset)
    (writeSSet \ "spec" \ "replicas").asOpt[Int] must beSome(0)
  }

  "A StatefulSet object can be read directly from a JSON string" >> {
    import scala.io.Source
    val ssJsonSource=Source.fromURL(getClass.getResource("/exampleStatefulSet.json"))
    val ssetJsonStr = ssJsonSource.mkString
    val stateSet = Json.parse(ssetJsonStr).as[StatefulSet]

    stateSet.kind mustEqual "StatefulSet"
    stateSet.name mustEqual "nginx-stateset"
    stateSet.spec.get.replicas must beSome(7)
    stateSet.spec.get.updateStrategy.get.`type` mustEqual StatefulSet.UpdateStrategyType.RollingUpdate
    stateSet.spec.get.updateStrategy.get.rollingUpdate.get.partition mustEqual(5)
    stateSet.spec.get.volumeClaimTemplates.size mustEqual 1
    stateSet.spec.get.serviceName.get mustEqual "nginx-service"
    stateSet.spec.get.template.metadata.labels mustEqual Map("domain" -> "www.example.com","proxies" -> "microservices")
    val podSpec=stateSet.spec.get.template.spec.get
    podSpec.containers.length mustEqual 1
    val container=podSpec.containers(0)
    container.resources.get.requests.get("cpu").get mustEqual Resource.Quantity("500m")
    container.lifecycle.get.preStop.get mustEqual ExecAction(List("/bin/sh", "-c", "PID=$(pidof java) && kill $PID && while ps -p $PID > /dev/null; do sleep 1; done"))
    container.readinessProbe.get.action mustEqual ExecAction(List("/bin/sh", "-c", "./ready.sh"))
    container.readinessProbe.get.initialDelaySeconds mustEqual 15
    container.readinessProbe.get.timeoutSeconds mustEqual 5
    stateSet.spec.get.selector.get.requirements.size mustEqual 4
    stateSet.spec.get.selector.get.requirements.find(r => (r.key == "env")) mustEqual Some("env" isNotIn List("dev"))
    stateSet.spec.get.selector.get.requirements.find(r => (r.key == "domain")) mustEqual Some("domain" is "www.example.com")

    // write and read back in again, should be unchanged
    val json = Json.toJson(stateSet)
    val readSS = Json.fromJson[StatefulSet](json).get
    readSS mustEqual stateSet
  }
} 
Example 51
Source File: HPASSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.autoscaling
import org.specs2.mutable.Specification

import scala.math.BigInt
import skuber.{Container, ObjectMeta, Pod, ReplicationController}
import play.api.libs.json._
import skuber.autoscaling.HorizontalPodAutoscaler.CrossVersionObjectReference


class HPASSpec extends Specification {
  "This is a unit specification for the skuber HorizontalPodAutoscaler class. ".txt
  
  "A HPAS object can be constructed from the object it scales\n" >> {
    "A HPAS can be constructed from a replication controller" >> {
      val container=Container(name="example",image="example")
      val rc=ReplicationController("example", container, Map("app" -> "example"))
      val hpas=HorizontalPodAutoscaler.scale(rc).
                    withMinReplicas(1).
                    withMaxReplicas(10).
                    withCPUTargetUtilization(80)
      hpas.name mustEqual "example"
      hpas.spec.scaleTargetRef.kind mustEqual "ReplicationController"
      hpas.spec.maxReplicas must_== 10
      hpas.spec.minReplicas must beSome(1)
      hpas.spec.cpuUtilization mustEqual Some(CPUTargetUtilization(80))
    }
  }

  "A HPAS object properly writes with zero minReplicas" >> {
    val hpas=HorizontalPodAutoscaler(
      metadata = ObjectMeta("example"),
      spec = HorizontalPodAutoscaler.Spec(
        scaleTargetRef = CrossVersionObjectReference(name="example")
      )
    ).withMaxReplicas(0).withMinReplicas(0)

    val writeHPAS = Json.toJson(hpas)
    (writeHPAS \ "spec" \ "minReplicas").asOpt[Int] must beSome(0)
    (writeHPAS \ "spec" \ "maxReplicas").asOpt[Int] must beSome(0)
  }
} 
Example 52
Source File: ScaleSpec.scala    From skuber   with Apache License 2.0 5 votes vote down vote up
package skuber.apps

import org.specs2.mutable.Specification
import skuber.{Container, LabelSelector, ObjectMeta, Pod, ReplicationController, Scale}
import play.api.libs.json.Json


class ScaleSpec extends Specification {
  "This is a unit specification for the skuber Scale class. ".txt
  
  "A Scale object can be constructed from a name and replica count" >> {
    val scale=Scale.named("example").withSpecReplicas(10)
    scale.spec.replicas mustEqual Some(10)
    scale.name mustEqual "example"
    scale.status mustEqual None
  }
  
  "A scale object can be written to Json and then read back again successfully" >> {

      val scale= Scale(
        apiVersion="autoscaling/v1",
        metadata=ObjectMeta(name="example", namespace="na"),
        spec=Scale.Spec(replicas=Some(10))
      )
      
      val readScale = Json.fromJson[Scale](Json.toJson(scale)).get
      readScale mustEqual scale
  }
  
  "A scale object can be read directly from a JSON string" >> {
    val scaleJsonStr = """
{
  "kind": "Scale",
  "apiVersion": "extensions/v1beta1",
  "metadata": {
    "name": "redis-master",
    "namespace": "default",
    "selfLink": "/apis/extensions/v1beta1/namespaces/default/replicationcontrollers/redis-master/scale",
    "creationTimestamp": "2015-12-29T11:55:14Z"
  },
  "spec": {
    "replicas": 1
  },
  "status": {
    "replicas": 1,
    "targetSelector": "redis-master"
  }
}
"""
    val scale = Json.parse(scaleJsonStr).as[Scale]
    scale.kind mustEqual "Scale"
    scale.name mustEqual "redis-master"
    scale.spec.replicas mustEqual Some(1)
    scale.status mustEqual Some(Scale.Status(replicas=1, selector=None, targetSelector=Some("redis-master")))
  }

  "A scale object can contain NO replicas" >> {
    val scaleJsonObj =
      """
        |{
        |  "kind": "Scale",
        |  "apiVersion": "extensions/v1beta1",
        |  "metadata": {
        |    "name": "redis-master",
        |    "namespace": "default",
        |    "selfLink": "/apis/extensions/v1beta1/namespaces/default/replicationcontrollers/redis-master/scale",
        |    "creationTimestamp": "2015-12-29T11:55:14Z"
        |  },
        |  "spec": {
        |  },
        |  "status": {
        |    "replicas": 1,
        |    "targetSelector": "redis-master"
        |  }
        |}
      """.stripMargin
    val scale = Json.parse(scaleJsonObj).as[Scale]
    scale.kind mustEqual "Scale"
    scale.name mustEqual "redis-master"
    scale.spec.replicas mustEqual None
  }
} 
Example 53
Source File: MetricsEndpointsSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.metrics

import java.net.InetAddress

import akka.http.scaladsl.model.headers.{Accept, `Remote-Address`}
import akka.http.scaladsl.model.{ContentTypes, MediaTypes, RemoteAddress, StatusCodes}
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.routing.Rejection.NotFoundRejection
import org.specs2.mutable.Specification

class MetricsEndpointsSpec extends Specification with Specs2RouteTest {

  val endpoints = new MetricsEndpoints()(system, system.dispatcher)

  def remoteAddress(ip: String) = RemoteAddress(InetAddress.getByName(ip))

  "The routing infrastructure should support" should {

    "a call to /metrics to be handled" in {
      Get("/metrics").withHeaders(`Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        handled must beTrue
        contentType === ContentTypes.`application/json`
        status must be equalTo (StatusCodes.OK)
      }
    }

    "a call to /metrics should return json" in {
      Get("/metrics").withHeaders(Accept(MediaTypes.`application/json`),
        `Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        handled must beTrue
        contentType === ContentTypes.`application/json`
      }
    }

    "a call to /metrics should return an error due to CIDR rules" in {
      Get("/metrics").withHeaders(Accept(MediaTypes.`application/json`),
        `Remote-Address`(remoteAddress("192.168.1.1"))) ~> endpoints.route ~> check {
        handled must beFalse
        rejections.size must beEqualTo(1)
        rejections.head must be equalTo(NotFoundRejection("The requested resource could not be found"))
      }
    }
  }

} 
Example 54
Source File: MetricsWriterSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.metrics

import com.codahale.metrics.MetricRegistry
import com.github.vonnagy.service.container.http.DefaultMarshallers
import org.specs2.mutable.Specification

class MetricsWriterSpec extends Specification with DefaultMarshallers {

  val reg = new MetricRegistry()
  val writer = new MetricsWriter(reg)

  step {
    reg.counter("test.counter").inc(10)
    reg.meter("test.meter").mark(10)
    reg.timer("test.timer")
    reg.histogram("test.histogram").update(10)
    reg.register("test.gauge", new com.codahale.metrics.Gauge[Int] {
      def getValue: Int = 10
    })
    reg.counter("jvm.test").inc(20)
  }

  "The metrics writer" should {
    "create json for custom metrics" in {
      val json = writer.getMetrics(false)
      val value = json \ "system" \ "metrics" \ "test.counter"
      value.extract[Int] must be equalTo 10
    }

    "create json for custom and jvm metrics" in {
      val json = writer.getMetrics(true)
      val value = json \ "system" \ "metrics" \ "test.counter"
      value.extract[Int] must be equalTo 10

      val value2 = json \ "system" \ "jvm" \ "unkown" \ "jvm.test"
      value2.extract[Int] must be equalTo 20
    }
  }
} 
Example 55
Source File: BaseDirectivesSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http

import akka.http.scaladsl.marshalling._
import akka.http.scaladsl.model.MediaTypes._
import akka.http.scaladsl.model.headers.Accept
import akka.http.scaladsl.model.{MediaType, MediaTypes}
import akka.http.scaladsl.server.{ContentNegotiator, Route, UnacceptedResponseContentTypeRejection}
import com.github.vonnagy.service.container.Specs2RouteTest
import org.specs2.mutable.Specification


class BaseDirectivesSpec extends Specification with BaseDirectives with DefaultMarshallers with Specs2RouteTest {

  val `application/vnd.com.github.vonnagy.container.health-v1+json` =
    MediaType.custom("application/vnd.com.github.vonnagy.container.health-v1+json", false)

  "The base directives" should {

    "allow the use of the `acceptableMediaTypes` directive" in {

      import MediaTypes._

      implicit val marsh: ToEntityMarshaller[Seq[String]] = jsonMarshaller

      implicit val vndMarsh: ToEntityMarshaller[String] =
        Marshaller.StringMarshaller.wrap(`application/vnd.com.github.vonnagy.container.health-v1+json`)(_.toString)

      val route: Route =
        path("app-json") {
          acceptableMediaTypes(`application/json`, `application/vnd.com.github.vonnagy.container.health-v1+json`) {
            complete(Seq())
          }
        } ~
          path("app-custom") {
            acceptableMediaTypes(`application/json`, `application/vnd.com.github.vonnagy.container.health-v1+json`) {
              complete("[]")
            }
          }

      Get("/app-json")
        .withHeaders(Accept(`application/json`, `application/vnd.com.github.vonnagy.container.health-v1+json`)) ~>
        route ~> check {
        responseAs[String] === "[]"
        mediaType === MediaTypes.`application/json`
      }

      Get("/app-custom")
        .withHeaders(Accept(`application/vnd.com.github.vonnagy.container.health-v1+json`, `application/json`)) ~>
        route ~> check {
        responseAs[String] === "[]"
        mediaType === `application/vnd.com.github.vonnagy.container.health-v1+json`
      }

      Get("/app-json").withHeaders(Accept(`text/plain`)) ~> route ~> check {
        rejection === UnacceptedResponseContentTypeRejection(Set(ContentNegotiator.Alternative(`application/json`),
          ContentNegotiator.Alternative(`application/vnd.com.github.vonnagy.container.health-v1+json`)))
      }
    }
  }

  "allow for the use of json response type" in {

    implicit val marsh: ToEntityMarshaller[Seq[String]] = jsonMarshaller

    Get() ~> {
      complete(Seq())
    } ~> check {
      mediaType === `application/json`
    }
  }

  "allow for the use of plain response type" in {

    Get() ~> {
      complete("[]")
    } ~> check {
      mediaType === `text/plain`
    }

  }

} 
Example 56
Source File: CIDRDirectivesSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http.directives

import java.net.InetAddress

import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{RemoteAddress, StatusCodes}
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.routing.Rejection.NotFoundRejection
import org.specs2.mutable.Specification


class CIDRDirectivesSpec extends Specification with CIDRDirectives with Specs2RouteTest {

  val yeah = complete("Yeah!")

  def remoteAddress(ip: String) = RemoteAddress(InetAddress.getByName(ip))

  "CIDRDirectives" should {

    "allow call when no allows or denies" in {
      Get() ~> addHeaders(`Remote-Address`(remoteAddress("192.168.1.1"))) ~> {
        cidrFilter(Seq(), Seq()) {
          yeah
        }
      } ~> check {
        handled === true
        status === StatusCodes.OK
      }
    }

    "allow call when no denies, but matches allow" in {
      Get() ~> addHeaders(`Remote-Address`(remoteAddress("192.168.1.1"))) ~> {
        cidrFilter(Seq("192.168.1.1/1"), Seq()) {
          yeah
        }
      } ~> check {
        handled === true
        status === StatusCodes.OK
      }
    }

    "allow call when does not match deny, but matches allow" in {
      Get() ~> addHeaders(`Remote-Address`(remoteAddress("192.168.1.1"))) ~> {
        cidrFilter(Seq("192.168.1.1/1"), Seq("10.0.0.1/1")) {
          yeah
        }
      } ~> check {
        handled === true
        status === StatusCodes.OK
      }
    }

    "disallow call when no denies and does not match allow" in {
      Get() ~> addHeaders(`Remote-Address`(remoteAddress("192.168.1.1"))) ~> {
        cidrFilter(Seq("127.0.0.1/1"), Seq()) {
          yeah
        }
      } ~> check {
        handled must beFalse
        rejections.size must beEqualTo(1)
        rejections.head must be equalTo(NotFoundRejection("The requested resource could not be found"))
      }
    }

    "disallow call when matches a deny" in {
      Get() ~> addHeaders(`Remote-Address`(remoteAddress("10.0.0.1"))) ~> {
        cidrFilter(Seq("192.168.1.1/1"), Seq("10.0.0.1/1")) {
          yeah
        }
      } ~> check {
        handled must beFalse
        rejections.size must beEqualTo(1)
        rejections.head must be equalTo(NotFoundRejection("The requested resource could not be found"))
      }
    }

    "disallow because there is no remote address header that has been injected" in {
      Get() ~> {
        cidrFilter(Seq(), Seq()) {
          yeah
        }
      } ~> check {
        handled must beFalse
        rejections.size must beEqualTo(1)
        rejections.head must be equalTo(NotFoundRejection("The requested resource could not be found"))
      }
    }
  }
} 
Example 57
Source File: RoutingHandlerSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http.routing

import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.ContentTypes._
import akka.http.scaladsl.server.{Directives, MalformedRequestContentRejection, MissingCookieRejection, Route}
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.routing.Rejection.DuplicateRejection
import org.specs2.mutable.Specification


class RoutingHandlerSpec extends Specification with Specs2RouteTest with Directives {

  val handler = new RoutingHandler {
    def conf = system.settings.config
  }

  val dummyRoute =
    pathPrefix("test") {
      get {
        path("duplicate") {
          reject(DuplicateRejection("test"))
        } ~
        path("malformed") {
          reject(MalformedRequestContentRejection("test", new Exception("test")))
        } ~
        path("cookie") {
          reject(MissingCookieRejection("test"))
        } ~
        path("exception") {
          throw new NullPointerException("test")
        }
      }
    }

  "the routing handler" should {

    "provide custom rejection handlers" in {
      implicit val rejHandler = handler.rejectionHandler
      val sr = Route.seal(dummyRoute)

      Get("/test/duplicate") ~> sr ~> check {
        status must be equalTo BadRequest
        responseAs[String] must be equalTo(
          """{"code":400,"message":"The request contains bad syntax or cannot be fulfilled.","details":"\"test\""}""")
      }

      Get("/test/malformed") ~> sr ~> check {
        status must be equalTo UnprocessableEntity
        responseAs[String] must be equalTo(
          """{"code":422,"message":"The request was well-formed but was unable to be followed due to semantic errors.","details":"\"test\""}""")
      }
    }

    "use the default rejection handler as a fallback" in {
      implicit val rejHandler = handler.rejectionHandler
      val sr = Route.seal(dummyRoute)

      Get("/test/cookie") ~> sr ~> check {
        status must be equalTo BadRequest
        responseAs[String] must be equalTo(
          """{"code":400,"message":"The request contains bad syntax or cannot be fulfilled.","details":"Request is missing required cookie 'test'"}""")
      }
    }

    "provide custom exception handlers" in {
      implicit val exHandler = handler.exceptionHandler
      val sr = Route.seal(dummyRoute)

      Get("/test/exception") ~> sr ~> check {
        status must be equalTo InternalServerError
        contentType must be equalTo `application/json`
        responseAs[String] must be equalTo(
          """{"code":500,"message":"There was an internal server error.","details":"Something bad happened"}""")
      }
 }

  }
} 
Example 58
Source File: RoutedServiceSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http.routing

import akka.actor._
import akka.http.scaladsl.model.{HttpEntity, MediaTypes, StatusCodes}
import akka.http.scaladsl.server.{Directives, Route}
import akka.testkit.{TestActorRef, TestProbe}
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.{DefaultMarshallers, RejectionResponse}
import org.specs2.mutable.Specification

class RoutedServiceSpec extends Specification with Directives with Specs2RouteTest {

  case class TestEntity(id: Int, name: String)

  val probe = new TestProbe(system)
  val httpAct = TestActorRef(Props(new Actor with RoutedService with DefaultMarshallers {
    def receive = routeReceive
  }), "http")

  val svc = httpAct.underlyingActor.asInstanceOf[RoutedService]

  def echoComplete[T]: T => Route = { x ⇒ complete(x.toString) }

  "The RoutedService" should {

    "allow for routes to be added after the system is already loaded" in {
      // This should create the actor and register the endpoints
      val r = new RoutedEndpoints {
        def route = {
          path("test2") {
            complete("test2")
          }
        }
      }

      probe.send(httpAct, AddRoute(r))
      probe.expectMsg(RouteAdded)

      Get("/test2") ~> svc.buildRoute(svc.routes) ~> check {
        responseAs[String] must be equalTo "test2"
      }
    }

    "respond with UnprocessableEntity for requests resulting in a MalformedFormFieldRejection" in {

      implicit val unmarsh = svc.jsonUnmarshaller[TestEntity]
      implicit val rejMarsh = svc.jsonUnmarshaller[RejectionResponse]

      val postRoute = new RoutedEndpoints {
        def route = {
          post {
            path("test4") {
              entity(as[TestEntity]) {
                echoComplete
              }
            }
          }
        }
      }

      probe.send(httpAct, AddRoute(postRoute))
      probe.expectMsg(RouteAdded)

      import svc.defaultJsonFormats
      val ent = TestEntity(100, "product")

      Post("/test4", HttpEntity(MediaTypes.`application/json`, svc.serialization.write(ent))) ~>
        handleRejections(svc.rejectionHandler)(svc.buildRoute(svc.routes)) ~> check {
        status === StatusCodes.UnprocessableEntity
        mediaType === MediaTypes.`application/json`
        responseAs[RejectionResponse] must not beNull
      }
    }

    "respond with RejectionResponse for requests that error out" in {

      implicit val rejMarsh = svc.jsonUnmarshaller[RejectionResponse]

      val postRoute = new RoutedEndpoints {
        def route = {
          get {
            path("test5") { ctx => throw new Exception("test") }
          }
        }
      }

      probe.send(httpAct, AddRoute(postRoute))
      probe.expectMsg(RouteAdded)

      Get("/test5") ~>
        Route.seal(svc.buildRoute(svc.routes))(svc.routeSettings,
          exceptionHandler = svc.exceptionHandler,
          rejectionHandler = svc.rejectionHandler) ~> check {

        mediaType === MediaTypes.`application/json`
        responseAs[RejectionResponse] must not beNull
      }
    }
  }

} 
Example 59
Source File: BaseEndpointsSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.http

import java.net.InetAddress

import akka.http.scaladsl.model.headers.`Remote-Address`
import akka.http.scaladsl.model.{RemoteAddress, StatusCodes}
import akka.http.scaladsl.server.Directives
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.routing.Rejection.NotFoundRejection
import org.specs2.mutable.Specification

class BaseEndpointsSpec extends Specification with Directives with Specs2RouteTest {

  val endpoints = new BaseEndpoints

  "The base routing infrastructure" should {

    "return no content for favicon.ico" in {
      Get("/favicon.ico") ~> endpoints.route ~> check {
        status must be equalTo StatusCodes.NoContent
      }
    }

    "support a call to ping" in {
      Get("/ping") ~> endpoints.route ~> check {
        responseAs[String] must startWith("pong")
        status must beEqualTo(StatusCodes.OK)
      }
    }

    "a call to shutdown should return and error due to CIDR rules" in {
      Post("/shutdown").withHeaders(`Remote-Address`(RemoteAddress(InetAddress.getByName("192.168.1.1")))) ~> endpoints.route ~> check {
        handled must beFalse
        rejections.size must beEqualTo(1)
        rejections.head must be equalTo(NotFoundRejection("The requested resource could not be found"))
      }
    }

  }

} 
Example 60
Source File: HealthEndpointsSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.health

import java.net.InetAddress

import akka.http.scaladsl.model.headers.{Accept, `Remote-Address`}
import akka.http.scaladsl.model.{ContentTypes, MediaTypes, RemoteAddress, StatusCodes}
import com.github.vonnagy.service.container.Specs2RouteTest
import com.github.vonnagy.service.container.http.routing.Rejection.NotFoundRejection
import org.specs2.mutable.Specification

import scala.concurrent.Future

class HealthEndpointsSpec extends Specification with Specs2RouteTest {

  sequential

  val endpoints = new HealthEndpoints()(system, system.dispatcher)
  def remoteAddress(ip: String) = RemoteAddress(InetAddress.getByName(ip))

  "The routing infrastructure" should {

    "support a call to /health" in {
      Get("/health").withHeaders(`Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        handled must beTrue
        contentType === ContentTypes.`application/json`
        status must be equalTo (StatusCodes.OK)
      }
    }

    "support a call to /health that should return json" in {
      Get("/health").withHeaders(Accept(MediaTypes.`application/json`),
        `Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        handled must beTrue
        mediaType === MediaTypes.`application/json`
        contentType === ContentTypes.`application/json`
      }
    }

    "a call to /health should return an error due to CIDR rules" in {
      Get("/health").withHeaders(Accept(MediaTypes.`application/json`),
        `Remote-Address`(remoteAddress("192.168.1.1"))) ~> endpoints.route ~> check {
        handled must beFalse
        rejections.size must beEqualTo(1)
        rejections.head must be equalTo(NotFoundRejection("The requested resource could not be found"))
      }
    }

    "support a call to /health/lb" in {
      Get("/health/lb").withHeaders(Accept(MediaTypes.`text/plain`),
        `Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        handled must beTrue
        mediaType === MediaTypes.`text/plain`
        responseAs[String].equals("UP")
      }
    }

    "support a call to health/lb that returns a status of `Ok` when a health check is marked as degraded" in {
      Health(system).addCheck(new HealthCheck {
        override def getHealth: Future[HealthInfo] = Future {
          HealthInfo("degraded", HealthState.DEGRADED, "")
        }
      })

      Get("/health/lb").withHeaders(Accept(MediaTypes.`text/plain`),
        `Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        handled must beTrue
        mediaType === MediaTypes.`text/plain`
        status === StatusCodes.OK
        responseAs[String].equals("UP")
      }
    }

    "support a call to health/lb that returns a status of `ServiceUnavailable` when a health check is marked as critical" in {
      Health(system).addCheck(new HealthCheck {
        override def getHealth: Future[HealthInfo] = Future {
          HealthInfo("critical", HealthState.CRITICAL, "")
        }
      })

      Get("/health/lb").withHeaders(Accept(MediaTypes.`text/plain`),
        `Remote-Address`(remoteAddress("127.0.0.1"))) ~> endpoints.route ~> check {
        //handled must beTrue
        mediaType === MediaTypes.`text/plain`
        status === StatusCodes.ServiceUnavailable
        responseAs[String].equals("DOWN")
      }
    }

  }
} 
Example 61
Source File: SystemShutdownSpec.scala    From service-container   with Apache License 2.0 5 votes vote down vote up
package com.github.vonnagy.service.container.core

import akka.actor.{ActorSystem, Terminated}
import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification


class SystemShutdownSpec extends Specification {

  "SystemShutdown" should {

    "allow the ActorSystem to be shutdown" in {
      val sys = ActorSystem()
      val shut = new SystemShutdown {
        val system = sys
      }

      shut.shutdownActorSystem(false) {}
      implicit val ec = ExecutionEnv.fromExecutionContext(sys.dispatcher)
      shut.system.whenTerminated must beAnInstanceOf[Terminated].await

      sys.whenTerminated.isCompleted must beTrue
      success
    }
  }
} 
Example 62
Source File: PrefixDomainModelQualifierSpec.scala    From play-swagger   with Apache License 2.0 5 votes vote down vote up
package com.iheart.playSwagger

import org.specs2.mutable.Specification

class PrefixDomainModelQualifierSpec extends Specification {
  "isModel with multiple packages" >> {

    val dmq = PrefixDomainModelQualifier("com.a", "com.b")

    "returns true if the class is in one of the packages" >> {

      dmq.isModel("com.a.foo") must beTrue
    }

    "returns false if the class is not in any of the packages" >> {
      dmq.isModel("com.c.foo") must beFalse
    }
  }

  "isModel with no packages" >> {
    "returns false" >> {
      val dmq = PrefixDomainModelQualifier()
      dmq.isModel("com.c.foo") must beFalse
    }
  }
} 
Example 63
Source File: NamingStrategySpec.scala    From play-swagger   with Apache License 2.0 5 votes vote down vote up
package com.iheart.playSwagger

import org.specs2.mutable.Specification

class NamingStrategySpec extends Specification {
  "naming strategy" >> {
    "none" >> {
      NamingStrategy.from("none")("attributeName") must be("attributeName")
    }

    "snake_case" >> {
      NamingStrategy.from("snake_case")("attributeName") must equalTo("attribute_name")
    }

    "kebab-case" >> {
      NamingStrategy.from("kebab-case")("attributeName") must equalTo("attribute-name")
    }

    "lowercase" >> {
      NamingStrategy.from("lowercase")("attributeName") must equalTo("attributename")
    }

    "UpperCamelCase" >> {
      NamingStrategy.from("UpperCamelCase")("attributeName") must equalTo("AttributeName")
    }
  }
} 
Example 64
Source File: PeopleEncodersSpec.scala    From finch-template   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.redbubble.finchtemplate.api.v1.people

import com.redbubble.finchtemplate.model.Person
import com.redbubble.finchtemplate.util.spec.{FinchTemplateGenerators, SpecHelper}
import com.redbubble.util.http.ResponseOps.jsonBuf
import com.redbubble.util.json.JsonPrinter._
import io.circe.syntax._
import org.scalacheck.Prop._
import org.scalacheck.Properties
import org.specs2.mutable.Specification

final class PeopleEncodersSpec extends Specification with SpecHelper with FinchTemplateGenerators {

  private implicit val personEncoder = PeopleEncoders.personEncoder

  val encodePersonProp = new Properties("Person encoding") {
    property("encode") = forAll(genPerson) { (p: Person) =>
      val expected = parse(s"""{"person":{"name":"${p.name}","birth_year":"${p.birthYear}","hair_colour":"${p.hairColour}"}}""")
      val actual = parse(jsonToString(p.asJson))
      expected must beEqualTo(actual)
    }
  }

  s2"Person can be encoded into JSON$encodePersonProp"

  private implicit val personResponseEncoder = PeopleEncoders.personResponseEncode

  val personResponseProp = new Properties("Person JSON response encoding") {
    property("encode") = forAll(genPerson) { (p: Person) =>
      val expected = parse(s"""{"data":{"person":{"name":"${p.name}","birth_year":"${p.birthYear}","hair_colour":"${p.hairColour}"}}}""")
      val actual = parse(jsonBuf(p))
      expected must beEqualTo(actual)
    }
  }

  s2"Person can be encoded into a response JSON$personResponseProp"

  private implicit val peopleEncoder = PeopleEncoders.peopleEncoder

  val encodePeopleProp = new Properties("People encoding") {
    property("encode") = forAll(genPerson) { (p: Person) =>
      val expected = parse(s"""{"people":[{"name":"${p.name}","birth_year":"${p.birthYear}","hair_colour":"${p.hairColour}"}]}""")
      val actual = parse(jsonToString(Seq(p).asJson))
      expected must beEqualTo(actual)
    }
  }

  s2"People can be encoded into JSON$encodePeopleProp"

  private implicit val peopleResponseEncoder = PeopleEncoders.peopleResponseEncode

  val peopleResponseProp = new Properties("People JSON response encoding") {
    property("encode") = forAll(genPerson) { (p: Person) =>
      val expected = parse(s"""{"data":{"people":[{"name":"${p.name}","birth_year":"${p.birthYear}","hair_colour":"${p.hairColour}"}]}}""")
      val actual = parse(jsonBuf(Seq(p)))
      expected must beEqualTo(actual)
    }
  }

  s2"People can be encoded into a response JSON$peopleResponseProp"
} 
Example 65
Source File: PeopleDecodersSpec.scala    From finch-template   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.redbubble.finchtemplate.backends.people

import com.redbubble.finchtemplate.model.Person
import com.redbubble.finchtemplate.util.spec.{FinchTemplateGenerators, SpecHelper}
import org.scalacheck.Prop._
import org.scalacheck.Properties
import org.specs2.mutable.Specification

final class PeopleDecodersSpec extends Specification with SpecHelper with FinchTemplateGenerators with PeopleApiJson {
  val decodingProp = new Properties("People decoding") {
    property("decoding a single person") = forAll(genPerson) { (person: Person) =>
      val json = personJson(person)
      val decoded = decode(json)(PeopleDecoders.personDecoder)
      decoded must beRight(person)
    }

    property("decoding a list of people") = forAll(genPerson) { (person: Person) =>
      val json = peopleJson(Seq(person))
      val decoded = decode(json)(PeopleDecoders.peopleDecoder)
      decoded must beRight(Seq(person))
    }
  }

  s2"Decoding people responses$decodingProp"
} 
Example 66
Source File: SpecHelper.scala    From finch-template   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.redbubble.finchtemplate.util.spec

import com.redbubble.util.async.singleThreadedFuturePool
import com.redbubble.util.json.CodecOps
import com.redbubble.util.log.Logger
import org.specs2.ScalaCheck
import org.specs2.execute.{Failure, Result}
import org.specs2.mutable.Specification
import org.specs2.specification.BeforeAll

trait SpecLogging {
  final val log = new Logger("finch-template-test")(singleThreadedFuturePool)
}

object SpecLogging extends SpecLogging

trait SpecHelper extends TestEnvironmentSetter with SpecLogging with ScalaCheck with FinchTemplateGenerators
    with CodecOps with BeforeAll {
  self: Specification =>
  override def beforeAll(): Unit = setEnvironment()

  final def fail(message: String, t: Throwable): Result = Failure(message, "", t.getStackTrace.toList)
} 
Example 67
Source File: EnvironmentSpec.scala    From finch-template   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.redbubble.finchtemplate.util.config

import com.redbubble.finchtemplate.util.spec.SpecHelper
import org.specs2.mutable.Specification

final class EnvironmentSpec extends Specification with SpecHelper {
  val development = Development
  val test = Test
  val production = Production

  "When running tests" >> {
    "the environment is 'test'" >> {
      Environment.env.name must beEqualTo("test")
      Environment.env.isTest must beTrue
    }
  }

  "Environment details" >> {
    "development" >> {
      development.name mustEqual "development"
      development.isDevelopment must beTrue
      development.isTest must beFalse
      development.isProduction must beFalse
    }

    "test" >> {
      test.name mustEqual "test"
      test.isDevelopment must beFalse
      test.isTest must beTrue
      test.isProduction must beFalse
    }

    "production" >> {
      production.name mustEqual "production"
      production.isDevelopment must beFalse
      production.isTest must beFalse
      production.isProduction must beTrue
    }
  }

  // We instantiate these to ensure they are valid URLs (they're lazy)
  "Backend URLs" >> {
    "for development" >> {
      "are valid" >> {
        development.peopleApiUrl must not(beNull)
      }
    }

    "for test" >> {
      "are valid" >> {
        test.peopleApiUrl must not(beNull)
      }
    }

    "for production" >> {
      "are valid" >> {
        production.peopleApiUrl must not(beNull)
      }
    }
  }
} 
Example 68
Source File: writableHelperTest.scala    From api-first-hand   with MIT License 5 votes vote down vote up
package de.zalando.play.controllers

import akka.util.ByteString
import de.zalando.play.controllers.ResponseWriters.choose
import org.specs2.mutable.Specification
import play.api.http.Writeable
import play.api.mvc.RequestHeader

import scala.concurrent.ExecutionContext.Implicits


    override val custom: Seq[(String, ParserWrapper[_])] = Seq(
      "text/plain" -> any
    )
  }

  "WrappedBodyParsers" should {
    "find something" in {
      WrappedBodyParsers.anyParser[Any] must_== Nil
    }
    "not find anything for wrong type" in {
      binaryString.anyParser[String] must_== Nil
    }
    "find something for correct type" in {
      binaryString.anyParser[BinaryString].size must_== 1
    }
    "find something for every type if target is 'Any'" in {
      catchAll.anyParser[String].size must_== 1
      catchAll.anyParser[BinaryString].size must_== 1
    }
  }
}

object TestEnvironment {
  import Implicits.global
  val transformSeq: Seq[Any] => ByteString = a => ByteString.fromString(a.toString)
  val transformStr: String => ByteString = ByteString.fromString

  val seqText: WriteableWrapper[Seq[Any]] = Writeable(transformSeq, Some("text/plain"))

  val stringText: WriteableWrapper[String] = Writeable(transformStr, Some("text/plain"))

  val reg = Seq(seqText, stringText)
} 
Example 69
Source File: AutoFetchingCacheSpec.scala    From mules   with MIT License 5 votes vote down vote up
package io.chrisdavenport.mules.reload

import cats.effect.IO
import cats.effect.concurrent.Ref
import cats.implicits._
import io.chrisdavenport.mules._
import org.specs2.mutable.Specification

import scala.concurrent.ExecutionContext
import scala.concurrent.duration._

class AutoFetchingCacheSpec extends Specification {

  implicit val ctx = IO.contextShift(ExecutionContext.global)
  implicit val timer = IO.timer(ExecutionContext.Implicits.global)

  "AutoFetchingCache" should {
    "get a value in a quicker period than the timeout" in {
      val setup = for {

        count <- Ref.of[IO, Int](0)

        cache <- AutoFetchingCache.createCache[IO, String, Int](Some(TimeSpec.unsafeFromDuration(1.second)), None)(_ =>
          count.update( _ + 1).as(1)
        )
        value <- cache.lookupCurrent("Foo")
        cValue <- count.get
      } yield (cValue, value)
      setup.unsafeRunSync must_=== ((1, 1))
    }


    "refetch value after expiration timeout" in {
      val setup = for {
        count <- Ref.of[IO, Int](0)

        cache <- AutoFetchingCache.createCache[IO, String, Int](Some(TimeSpec.unsafeFromDuration(1.second)), None)(_ =>
          count.update( _ + 1).as(1)
        )
        _ <- cache.lookupCurrent("Foo")
        _ <- timer.sleep(2.seconds)
        value <- cache.lookupCurrent("Foo")
        cValue <- count.get

      } yield (cValue, value)
      setup.unsafeRunSync must_=== ((2, 1))
    }


    "refetch value after autoReload timeout" in {
      val setup = for {
        count <- Ref.of[IO, Int](0)

        cache <- AutoFetchingCache.createCache[IO, String, Int](None, Some(AutoFetchingCache.RefreshConfig(TimeSpec.unsafeFromDuration(500.milliseconds))))(_ =>
          count.update( _ + 1).as(1)
        )
        _ <- cache.lookupCurrent("Foo")
        _ <- timer.sleep(2.seconds)
        value <- cache.lookupCurrent("Foo")
        cValue <- count.get

      } yield (cValue, value)

      val (cValue, value) = setup.unsafeRunSync
      (value must_=== 1).and(cValue >= 4)
    }

    "refetch value after autoReload timeout and before default expiration" in {
      val setup = for {
        count <- Ref.of[IO, Int](0)

        cache <- AutoFetchingCache.createCache[IO, String, Int](
          TimeSpec.fromDuration(3.second),
          Some(AutoFetchingCache.RefreshConfig(TimeSpec.unsafeFromDuration(500.milliseconds))))(_ =>
          count.update( _ + 1) *> count.get
        )
        _ <- cache.lookupCurrent("Foo")
        _ <- timer.sleep(2.seconds)
        value <- cache.lookupCurrent("Foo")
        cValue <- count.get

      } yield (cValue, value)

      val (cValue, value) = setup.unsafeRunSync
      (value must be >= 4).and(cValue >= 4)
    }

  }
} 
Example 70
Source File: CaffeineCacheSpec.scala    From mules   with MIT License 5 votes vote down vote up
package io.chrisdavenport.mules.caffeine

import org.specs2.mutable.Specification
import scala.concurrent.duration._
import cats.effect._
// import cats.effect.implicits._
import cats.effect.IO
import cats.effect.testing.specs2.CatsIO
import io.chrisdavenport.mules.TimeSpec

class CaffeineCacheSpec extends Specification with CatsIO {
  "CaffeineCache" should {
    "get a value in a quicker period than the timeout" in {
      val setup = for {
        cache <- CaffeineCache.build[IO, String, Int](Some(TimeSpec.unsafeFromDuration(1.second)), None, None)
        _ <- cache.insert("Foo", 1)
        _ <- Timer[IO].sleep(1.milli)
        value <- cache.lookup("Foo")
      } yield value
      setup.map(_ must_=== Some(1))
    }


    "remove a value after delete" in {
      val setup = for {
        cache <- CaffeineCache.build[IO, String, Int](None, None, None)
        _ <- cache.insert("Foo", 1)
        _ <- cache.delete("Foo")
        value <- cache.lookup("Foo")
      } yield value
      setup.map(_ must_=== None)
    }


    "Lookup after interval fails to get a value" in {
      val setup = for {
        cache <- CaffeineCache.build[IO, String, Int](Some(TimeSpec.unsafeFromDuration(1.second)), None, None)
        _ <- cache.insert("Foo", 1)
        _ <- Timer[IO].sleep(2.second)
        value <- cache.lookup("Foo")
      } yield value
      setup.map(_ must_=== None)
    }


  }
} 
Example 71
Source File: DispatchOneCacheSpec.scala    From mules   with MIT License 5 votes vote down vote up
package io.chrisdavenport.mules

import org.specs2.mutable.Specification
import scala.concurrent.duration._
import cats.implicits._
import cats.effect._
import cats.effect.concurrent._
// import cats.effect.implicits._
import cats.effect.IO
import cats.effect.testing.specs2.CatsIO

class DispatchOneCacheSpec extends Specification with CatsIO {
  "DispatchOneCache" should {
    "only run once" in {
      for {
        ref <- Ref[IO].of(0)
        cache <- DispatchOneCache.ofSingleImmutableMap[IO, Unit, Int](None)
        action = {_: Unit => Timer[IO].sleep(1.second) >> ref.modify(i => (i+1, i))}
        first <- cache.lookupOrLoad((), action).start
        second <- cache.lookupOrLoad((), action).start
        third <- cache.lookupOrLoad((), action).start
        _ <- first.join
        _ <- second.join
        _ <- third.join
        testValue <- ref.get
      } yield testValue must_=== 1
    }

    "only run till errors cease" in {
      for {
        ref <- Ref[IO].of(0)
        errorFunction = ref.modify(i => (i+1, if (i > 3) i.pure[IO] else  Timer[IO].sleep(1.second) >> IO.raiseError(new Throwable("whoopsie")))).flatten
        cache <- DispatchOneCache.ofSingleImmutableMap[IO, Unit, Int](None)
        first <- cache.lookupOrLoad((), { _ => errorFunction}).start
        second <- cache.lookupOrLoad((), { _ => errorFunction}).start
        third <- cache.lookupOrLoad((), { _ => errorFunction}).start
        _ <- first.join
        _ <- second.join
        _ <- third.join
        testValue <- ref.get
      } yield testValue must_=== 5
    }

    "insert places a value" in {
      for {
        cache <- DispatchOneCache.ofSingleImmutableMap[IO, Unit, Int](None)
        action = {_: Unit => IO.pure(5)}
        _ <- cache.insert((), 1)
        now <- cache.lookupOrLoad((), action)
      } yield {
        now must_=== 1
      }
    }

    "insert overrides background action for first action" in {
      for {
        cache <- DispatchOneCache.ofSingleImmutableMap[IO, Unit, Int](None)
        action = {_: Unit => Timer[IO].sleep(5.seconds).as(5)}
        first <- cache.lookupOrLoad((), action).start
        _ <- cache.insert((), 1)
        value <- first.join
      } yield {
        value must_=== 1
      }
    }

    "insert overrides background action for secondary action" in {
      for {
        cache <- DispatchOneCache.ofSingleImmutableMap[IO, Unit, Int](None)
        action = {_: Unit => Timer[IO].sleep(5.seconds).as(5)}
        first <- cache.lookupOrLoad((),action).start
        second <- cache.lookupOrLoad((), action).start
        _ <- cache.insert((), 1)
        resultSecond <- second.join
        _ <- first.cancel.timeout(1.second).attempt.void
      } yield {
        resultSecond must_=== 1
      }
    }


    "insert overrides set value" in {
      for {
        cache <- DispatchOneCache.ofSingleImmutableMap[IO, Unit, Int](None)
        action = {_: Unit => IO.pure(2)}
        first <- cache.lookupOrLoad((), action)
        _ <- cache.insert((), 1)
        second <- cache.lookupOrLoad((), action)
      } yield {
        (first,second).must_===((2, 1))
        
      }
    }
  }
} 
Example 72
Source File: RepositoriesSpec.scala    From github   with MIT License 5 votes vote down vote up
package io.chrisdavenport.github
package endpoints

import cats.effect._
import cats.effect.testing.specs2.CatsEffect

import org.http4s._
import org.http4s.client._
import org.http4s.dsl.io._
import org.http4s.implicits._

import org.specs2.mutable.Specification

class RepositoriesSpec extends Specification with CatsEffect {
  "Repositories" should {
    "delete correctly" in {
      val delete = HttpRoutes.of[IO]{
        case DELETE -> Root / "repos" / _ / _ => NoContent()
      }
      val client = Client.fromHttpApp(delete.orNotFound)
      io.chrisdavenport.github.endpoints.Repositories.delete[IO]("foo", "bar", OAuth(""))
        .run(client)
        .attempt
        .map(_ must beRight)
    }
  }

} 
Example 73
Source File: ContentSpec.scala    From github   with MIT License 5 votes vote down vote up
package io.chrisdavenport.github.endpoints.repositories

import cats.effect._
import cats.effect.testing.specs2.CatsEffect

import io.circe.literal._

import org.http4s._
import org.http4s.client._
import org.http4s.circe._
import org.http4s.dsl.io._
import org.http4s.implicits._

import org.specs2.mutable.Specification

class ContentSpec extends Specification with CatsEffect {
  "Content endpoints" should {
    val getContent = HttpRoutes.of[IO]{
      case GET -> Root / "repos" / _ / _ / "contents" / "file" =>
        val json = json"""
{
  "type": "file",
  "encoding": "base64",
  "size": 5362,
  "name": "README.md",
  "path": "README.md",
  "content": "encoded content ...",
  "sha": "3d21ec53a331a6f037a91c368710b99387d012c1",
  "url": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
  "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
  "html_url": "https://github.com/octokit/octokit.rb/blob/master/README.md",
  "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/README.md",
  "_links": {
    "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
    "self": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
    "html": "https://github.com/octokit/octokit.rb/blob/master/README.md"
  }
}
        """
        Ok(json)
      case GET -> Root / "repos" / _ / _ / "contents" / "directory" =>
        val json = json"""
        [
  {
    "type": "file",
    "size": 625,
    "name": "octokit.rb",
    "path": "lib/octokit.rb",
    "sha": "fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
    "url": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit.rb",
    "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
    "html_url": "https://github.com/octokit/octokit.rb/blob/master/lib/octokit.rb",
    "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/lib/octokit.rb",
    "_links": {
      "self": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit.rb",
      "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
      "html": "https://github.com/octokit/octokit.rb/blob/master/lib/octokit.rb"
    }
  },
  {
    "type": "dir",
    "size": 0,
    "name": "octokit",
    "path": "lib/octokit",
    "sha": "a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
    "url": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit",
    "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
    "html_url": "https://github.com/octokit/octokit.rb/tree/master/lib/octokit",
    "download_url": null,
    "_links": {
      "self": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit",
      "git": "https://api.github.com/repos/octokit/octokit.rb/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
      "html": "https://github.com/octokit/octokit.rb/tree/master/lib/octokit"
    }
  }
]
        """
        Ok(json)
    }
    "get content correct if given a file" in {
      Content.contentsFor[IO]("foo", "bar", "file", None, None)
        .run(Client.fromHttpApp(getContent.orNotFound))
        .attempt
        .map{_ must beRight}
    }
    "get contents correct if given a directory" in {
      Content.contentsFor[IO]("foo", "bar", "directory", None, None)
        .run(Client.fromHttpApp(getContent.orNotFound))
        .attempt
        .map{_ must beRight}
    }
  }
} 
Example 74
Source File: TeamsSpec.scala    From github   with MIT License 5 votes vote down vote up
package io.chrisdavenport.github.endpoints

import cats.effect._
import cats.effect.testing.specs2.CatsEffect

import io.chrisdavenport.github.OAuth
import io.chrisdavenport.github.data.Teams._
import io.chrisdavenport.github.endpoints.organizations.Teams.{addOrUpdateTeamRepo}

import org.http4s._
import org.http4s.client._
import org.http4s.dsl.io._
import org.http4s.implicits._

import org.specs2.mutable.Specification

class TeamsSpec extends Specification with CatsEffect {

  "Teams.addOrUpdateRepo" should {
    "return right on the expected json" in {
      val client = Client.fromHttpApp(
        HttpRoutes.of[IO]{
          case PUT -> Root / "teams" / _ / "repos" / _ / _ =>
            NoContent()
        }.orNotFound
      )
      addOrUpdateTeamRepo[IO](3, "foo", "bar", Permission.Admin, OAuth("asdfa"))
        .run(client)
        .attempt
        .map(_ must beRight)
    }
  }
} 
Example 75
Source File: SearchUsersSpec.scala    From github   with MIT License 5 votes vote down vote up
package io.chrisdavenport.github.endpoints

import cats.effect._
import cats.effect.testing.specs2.CatsEffect

import io.chrisdavenport.github.data.Sort
import io.chrisdavenport.github.endpoints.utils.PaginatedJsonFiles
import io.chrisdavenport.github.internals.RequestConstructor.GithubError

import org.http4s._
import org.http4s.client._
import org.http4s.dsl.io._
import org.http4s.implicits._

import org.specs2.mutable.Specification

class SearchUsersSpec extends Specification with CatsEffect with PaginatedJsonFiles {

  override def baseUri: Uri = uri"https://api.github.com/search/users?q=scala&sort=repositories"

  override def pageFileName: Int => String = page => s"search/users/q_scala_sort_repositories_page_$page.json"

  override def extractRequest: PartialFunction[Request[IO], Request[IO]] = {
    case request @ GET -> Root / "search" / "users" => request
  }

  "Search.users" should {

    "be able to fetch multiple pages" in {
      Search.users[IO]("scala", Some(Sort.Repositories), None, None)
        .run(Client.fromHttpApp(paginatedEndpoint(numPages = 3)))
        .take(3)
        .compile
        .toList
        .map { searchResults =>
          searchResults.size mustEqual (3)
          searchResults.head.totalCount mustEqual (3343)
          searchResults.head.incompleteResults mustEqual (false)
          searchResults.head.items.size mustEqual (30)
          searchResults.head.items.head.login mustEqual ("DefinitelyScala")
          searchResults.head.items.last.login mustEqual ("ashwanthkumar")
          searchResults(1).items.size mustEqual (30)
          searchResults(1).items.head.login mustEqual ("kitlangton")
          searchResults(1).items.last.login mustEqual ("Andrea")
          searchResults(2).items.size mustEqual (30)
          searchResults(2).items.head.login mustEqual ("ryan-williams")
          searchResults(2).items.last.login mustEqual ("heguangwu")
        }
    }

    "fail when not being able to fetch a page" in {
      Search.users[IO]("scala", Some(Sort.Repositories), None, None)
        .run(Client.fromHttpApp(paginatedEndpoint(numPages = 4)))
        .compile
        .toList
        .attempt
        .map {
          _ must beLeft(new GithubError(NotFound, "Page does not exist: 4"))
        }
    }

  }


} 
Example 76
Source File: RateLimitSpec.scala    From github   with MIT License 5 votes vote down vote up
package io.chrisdavenport.github.endpoints.miscellaneous

import cats.effect._
import cats.effect.testing.specs2.CatsEffect

import io.circe.literal._

import org.http4s._
import org.http4s.client._
import org.http4s.circe._
import org.http4s.dsl.io._
import org.http4s.implicits._

import org.specs2.mutable.Specification

class RateLimitSpec extends Specification with CatsEffect {

  "RateLimit" should {

    "return a valid rate-limit response" in {
      RateLimit.rateLimit[IO](None)
        .run(Client.fromHttpApp(rateLimit.orNotFound))
        .attempt
        .map(_ must beRight)
    }

  }

  val rateLimit : HttpRoutes[IO] = HttpRoutes.of {
    case GET -> Root / "rate_limit" =>
      Ok(
        json"""
        {
          "resources": {
            "core": {
              "limit": 5000,
              "remaining": 4999,
              "reset": 1372700873
            },
            "search": {
              "limit": 30,
              "remaining": 18,
              "reset": 1372697452
            },
            "graphql": {
              "limit": 5000,
              "remaining": 4993,
              "reset": 1372700389
            },
            "integration_manifest": {
              "limit": 5000,
              "remaining": 4999,
              "reset": 1551806725
            }
          },
          "rate": {
            "limit": 5000,
            "remaining": 4999,
            "reset": 1372700873
          }
        }
      """
      )
  }

} 
Example 77
Source File: SearchRepositorySpec.scala    From github   with MIT License 5 votes vote down vote up
package io.chrisdavenport.github.endpoints

import cats.effect._
import cats.effect.testing.specs2.CatsEffect

import io.chrisdavenport.github.data.Sort.Stars
import io.chrisdavenport.github.endpoints.utils.PaginatedJsonFiles
import io.chrisdavenport.github.internals.RequestConstructor.GithubError

import org.http4s._
import org.http4s.client._
import org.http4s.dsl.io._
import org.http4s.implicits._

import org.specs2.mutable.Specification

class SearchRepositorySpec extends Specification with CatsEffect with PaginatedJsonFiles {

  override def baseUri: Uri = uri"https://api.github.com/search/repositories?q=scala&sort=stars"

  override def pageFileName: Int => String = page => s"search/repositories/q_scala_sort_stars_page_$page.json"

  override def extractRequest: PartialFunction[Request[IO], Request[IO]] = {
    case request @ GET -> Root / "search" / "repositories" => request
  }

  "Search.repository" should {

    "be able to fetch multiple pages" in {
      Search.repository[IO]("scala", Some(Stars), None, None)
        .run(Client.fromHttpApp(paginatedEndpoint(numPages = 3)))
        .compile
        .toList
        .map { searchResults =>
          searchResults.size mustEqual (3)
          searchResults.head.totalCount mustEqual (82020)
          searchResults.head.incompleteResults mustEqual (false)
          searchResults.head.items.size mustEqual (30)
          searchResults.head.items.head.name mustEqual ("spark")
          searchResults.head.items.last.name mustEqual ("scala_school")
          searchResults(1).items.size mustEqual (30)
          searchResults(1).items.head.name mustEqual ("TensorFlowOnSpark")
          searchResults(1).items.last.name mustEqual ("spark-cassandra-connector")
          searchResults(2).items.size mustEqual (30)
          searchResults(2).items.head.name mustEqual ("sangria")
          searchResults(2).items.last.name mustEqual ("json4s")
        }
    }

    "fail when not being able to fetch a page" in {
      Search.repository[IO]("scala", Some(Stars), None, None)
        .run(Client.fromHttpApp(paginatedEndpoint(numPages = 4)))
        .compile
        .toList
        .attempt
        .map {
          _ must beLeft(new GithubError(NotFound, "Page does not exist: 4"))
        }
    }

  }


} 
Example 78
Source File: SerializationRoundtripSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.entities

import java.time.Instant

import com.danielasfregola.randomdatagenerator.RandomDataGenerator
import com.danielasfregola.twitter4s.http.serializers.JsonSupport
import org.json4s.native.Serialization
import org.scalacheck.Gen.alphaChar
import org.scalacheck.{Arbitrary, Gen}
import org.specs2.mutable.Specification
import org.specs2.specification.core.Fragment

import scala.reflect._

class SerializationRoundtripSpec extends Specification with RandomDataGenerator with JsonSupport {

  "JSON serialization" should {

    def roundtripTest[T <: AnyRef: Manifest: Arbitrary]: Fragment = {

      val className = classTag[T].runtimeClass.getSimpleName

      s"round-trip successfully for $className" in {
        val randomEntity = random[T]

        val serializedJson = Serialization.write[T](randomEntity)

        val deserializedEntity = Serialization.read[T](serializedJson)

        deserializedEntity === randomEntity
      }
    }

    roundtripTest[User]
  }

  // We serialize dates to second precision
  implicit val arbitraryDate: Arbitrary[Instant] = Arbitrary {
    for {
      timeInSeconds: Long <- Gen.chooseNum(1142899200L, 1512442349L)
    } yield Instant.ofEpochSecond(timeInSeconds)
  }

  implicit val arbitraryProfileImage: Arbitrary[ProfileImage] = Arbitrary {
    for {
      prefix: String <- Gen.nonEmptyListOf(alphaChar).map(_.mkString)
      suffix: String <- Gen.oneOf("_mini", "_normal", "_bigger", "")
    } yield ProfileImage(s"${prefix}_$suffix.jpg")
  }
} 
Example 79
Source File: DeserializationRoundtripSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.entities

import com.danielasfregola.twitter4s.helpers.{FixturesSupport, JsonDiffSupport}
import org.json4s.native.Serialization.writePretty
import org.json4s.native.{JsonParser, Serialization}
import org.json4s.{JNothing, JValue}
import org.specs2.matcher.{Expectable, Matcher}
import org.specs2.mutable.Specification
import org.specs2.specification.core.Fragment

import scala.reflect._

class DeserializationRoundtripSpec extends Specification with FixturesSupport with JsonDiffSupport {

  "JSON deserialization" should {

    def roundtripTest[T <: AnyRef: Manifest](jsonFile: String): Fragment = {

      val className = classTag[T].runtimeClass.getSimpleName

      s"round-trip successfully for $className in $jsonFile" in {
        val originalJson = load(jsonFile)

        val deserializedEntity = Serialization.read[T](originalJson)

        val serializedJson = Serialization.writePretty[T](deserializedEntity)

        originalJson must beASubsetOfJson(serializedJson)
      }
    }

    roundtripTest[User]("/twitter/rest/users/user.json")
  }

  def beASubsetOfJson(otherJson: String): Matcher[String] = new Matcher[String] {

    def apply[S <: String](t: Expectable[S]) = {
      val alpha: JValue = JsonParser.parse(t.value)
      val beta: JValue = JsonParser.parse(otherJson)

      jsonDiff(alpha, beta) match {
        case diff @ JsonDiff(JNothing, _, JNothing) =>
          success(s"""${t.value}
               |is a subset of
               |$otherJson
               |${renderDiff(diff)}
             """.stripMargin,
                  t)
        case diff =>
          failure(s"""${t.value}
               |is not a subset of
               |$otherJson
               |${renderDiff(diff)}
             """.stripMargin,
                  t)
      }
    }

    private def renderDiff(diff: JsonDiff) = {
      val changed = diff.changed.toOption.map { c =>
        s"""Changed:
           |${writePretty(c)}
          """.stripMargin
      }
      val deleted = diff.deleted.toOption.map { d =>
        s"""Deleted:
           |${writePretty(d)}
          """.stripMargin
      }
      val added = diff.added.toOption.map { a =>
        s"""Added:
           |${writePretty(a)}
          """.stripMargin
      }

      (changed ++ deleted ++ added).mkString
    }
  }
} 
Example 80
Source File: packageHttpSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.http

import org.specs2.mutable.Specification

class packageHttpSpec extends Specification {

  "Rich String" should {

    "convert a text to ascii encoding" in {
      "Ladies + Gentlemen".urlEncoded === "Ladies%20%2B%20Gentlemen"
      "An encoded string!".urlEncoded === "An%20encoded%20string%21"
      "Dogs, Cats & Mice".urlEncoded === "Dogs%2C%20Cats%20%26%20Mice"
      "☃".urlEncoded === "%E2%98%83"
    }
  }
} 
Example 81
Source File: EncoderSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.util

import org.specs2.mutable.Specification

class EncoderSpec extends Specification with Encoder {

  "HmacSha1 Encoder" should {

    "encode a base and secret as expected" in {
      val base = "POST&" +
        "https%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.json&" +
        "include_entities%3Dtrue%26" +
        "oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26" +
        "oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26" +
        "oauth_signature_method%3DHMAC-SHA1%26" +
        "oauth_timestamp%3D1318622958%26" +
        "oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26" +
        "oauth_version%3D1.0%26" +
        "status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521"
      val secret = "kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE"
      toHmacSha1(base, secret) === "tnnArxj06cWHq44gCs1OSKk/jLY="
    }

    "encode a base and secret as expected with callback" in {
      val base = "POST&" +
        "https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&" +
        "oauth_callback%3Dhttp%253A%252F%252Flocalhost%252Fsign-in-with-twitter%252F%26" +
        "oauth_consumer_key%3DcChZNFj6T5R0TigYB9yd1w%26" +
        "oauth_nonce%3Dea9ec8429b68d6b77cd5600adbbb0456%26" +
        "oauth_signature_method%3DHMAC-SHA1%26" +
        "oauth_timestamp%3D1318467427%26" +
        "oauth_version%3D1.0"
      val secret = "L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg&"
      toHmacSha1(base, secret) === "F1Li3tvehgcraF8DMJ7OyxO4w9Y="
    }
  }
} 
Example 82
Source File: UriHelpersSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.util

import akka.http.scaladsl.model.Uri
import org.specs2.mutable.Specification

class UriHelpersSpec extends Specification with UriHelpers {

  "UriHelpers" should {

    "extract an endpoint representation" in {

      "from a uri" in {
        val uri = Uri("https://api.twitter.com/1.1/lists/members/create.json?param1=8044403&param2=daniela")
        uri.endpoint === "https://api.twitter.com/1.1/lists/members/create.json"
      }

      "from a uri with explicit port" in {
        val uri = Uri("http://example.com:8080/path?p=test")
        uri.endpoint === "http://example.com:8080/path"
      }
    }
  }
} 
Example 83
Source File: ConfigurationDetectorSpec.scala    From twitter4s   with Apache License 2.0 5 votes vote down vote up
package com.danielasfregola.twitter4s.util

import com.typesafe.config.{Config, ConfigException}
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import org.specs2.specification.Scope

class ConfigurationDetectorSpec extends Specification with Mockito {

  val myConfigFromEnvVar = "my-configuration-from-env-var"
  val myConfigFromFile = "my-configuration-from-file"

  abstract class ConfigurationDetectorSpecContext extends Scope {
    def config = mock[Config]

    val variableName = "MY-CONFIG"
    val configName = "my.config"
  }

  trait NoEnvVariable extends ConfigurationDetector {
    override protected def environmentVariable(name: String) = None
  }

  trait WithEnvVariable extends ConfigurationDetector {
    override protected def environmentVariable(name: String) = Some(myConfigFromEnvVar)
  }

  trait NoConfigFromFile extends ConfigurationDetector {
    override protected def configuration(path: String) = throw new ConfigException.Missing(path)
  }

  trait WithConfigFromFile extends ConfigurationDetector {
    override protected def configuration(path: String) = myConfigFromFile
  }

  "ConfigurationDetector" should {

    "if environment variable exists" in {

      "if configuration from file does not exists" in {
        "detect the configuration from the environment variable" in
          new ConfigurationDetectorSpecContext with WithEnvVariable with NoConfigFromFile {
            envVarOrConfig(variableName, configName) === myConfigFromEnvVar
          }
      }

      "if configuration from file exists" in {
        "detect the configuration from the environment variable" in
          new ConfigurationDetectorSpecContext with WithEnvVariable with WithConfigFromFile {
            envVarOrConfig(variableName, configName) === myConfigFromEnvVar
          }
      }
    }

    "if environment variable does not exist" in {

      "if configuration from file exists" in {
        "detect the configuration from the configuration file" in
          new ConfigurationDetectorSpecContext with NoEnvVariable with WithConfigFromFile {
            envVarOrConfig(variableName, configName) === myConfigFromFile
          }
      }

      "if configuration from file does not exist" in {
        "throw an exception" in
          new ConfigurationDetectorSpecContext with NoEnvVariable with NoConfigFromFile {
            envVarOrConfig(variableName, configName) must throwA[RuntimeException]
          }
      }
    }
  }
} 
Example 84
Source File: XMLSpec.scala    From scalando   with MIT License 5 votes vote down vote up
package com.jcranky.scalando.cap12

import com.jcranky.scalando.cap11.{Foto, XMLParser}
import org.specs2.mutable.Specification

class XMLSpec extends Specification {
  "the xml parser" should {
    "turn the xml into the model class" in {
      val fotosXml =
        <rsp stat="ok">
          <photos>
            <photo id="123" owner="jcranky" server="6" title="jcranky test"></photo>
          </photos>
        </rsp>

      new XMLParser().parse(fotosXml.toString()) must_== Seq(
        Foto(123, "jcranky", 6, "jcranky test"))
    }
  }
} 
Example 85
Source File: ResponseParserSpec.scala    From scalando   with MIT License 5 votes vote down vote up
package com.jcranky.flickr

import org.specs2.mutable.Specification

class ResponseParserSpec extends Specification {
  "ResponseParser.flickrBoolean" should {
    "return true for 1" in {
      ResponseParser.flickrBoolean("1") ==== true
    }

    "return false for 0" in {
      ResponseParser.flickrBoolean("0") ==== false
    }

    "return false for 3" in {
      ResponseParser.flickrBoolean("3") ==== false
    }
  }
} 
Example 86
Source File: HttpClientSpec.scala    From scalando   with MIT License 5 votes vote down vote up
package com.jcranky.flickr

import com.jcranky.flickr.HttpClient.{GetError, GetResponse}
import org.specs2.mutable.Specification


class HttpClientSpec extends Specification {
  "the http client" should {
    "respond with a body" in {
      new HttpClient().get("https://httpbin.org/get") must beRight[GetResponse]
    }

    "respond with an error" in {
      new HttpClient().get("bla-bla") must beLeft[GetError]
    }
  }
} 
Example 87
Source File: XmlFlickrParserSpec.scala    From scalando   with MIT License 5 votes vote down vote up
package com.jcranky.flickr

import com.jcranky.flickr.model.Foto
import com.typesafe.config.ConfigFactory
import org.specs2.mutable.Specification

import scala.io.Source

class XmlFlickrParserSpec extends Specification {
  val config = ConfigFactory.load("test/resources/app-test.conf")

  "the response parser" should {
    "get a list of photos" in {
      val parsed = parseFrom("src/test/resources/flickr/responses/photos-list.xml")

      parsed should beRight.like { case res =>
        res should containTheSameElementsAs (List(
          Foto("29195658220", "28437914@N03", "cfe85ac898", "8457", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195655410", "28437914@N03", "c4e6935947", "8353", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195651850", "28437914@N03", "51449e97fc", "8845", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195648660", "28437914@N03", "2529785ac8", "8537", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("28862292093", "28437914@N03", "0097cc7e69", "8521", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195634910", "28437914@N03", "a4959f2252", "8009", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195632880", "28437914@N03", "ac48c82796", "8289", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195630990", "28437914@N03", "e8077623c9", "8300", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195629640", "28437914@N03", "0b5dcba3b7", "7536", 8, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195627610", "28437914@N03", "cbd39378ef", "7561", 8, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195624830", "28437914@N03", "2e4182f583", "8283", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("28862264913", "28437914@N03", "20b5061be3", "8830", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("28862261533", "28437914@N03", "b847eb1e9f", "8426", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("28862258423", "28437914@N03", "342002b429", "8438", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195617710", "28437914@N03", "30857f493b", "7461", 8, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195614540", "28437914@N03", "08b335036e", "8537", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195611040", "28437914@N03", "173b37d510", "8371", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195605970", "28437914@N03", "9607915a90", "8538", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false),
          Foto("29195600910", "28437914@N03", "7c21f55703", "8197", 9, "MITO_SettembreMusica2016_Inaugurazione_Milano_high", true, false, false)
        ))
      }
    }

    "parse the error response" in {
      val parsed = parseFrom("src/test/resources/flickr/responses/error.xml")
      parsed should beLeft(FlickrKnownError(100, "Invalid API Key (Key has invalid format)"))
    }

    "return unknown error for invalid file" in {
      val parsed = parseFrom("src/test/resources/flickr/responses/unknown.xml")
      parsed should beLeft(FlickrUnknownError(ResponseParser.unknownFlickrResp))
    }

    "return unknown error for rsp without err" in {
      val parsed = parseFrom("src/test/resources/flickr/responses/empty-error.xml")
      parsed should beLeft(FlickrUnknownError(ResponseParser.errNotFound))
    }
  }

  def parseFrom(file: String): Either[FlickrError, Seq[Foto]] = {
    val parser = new XmlFlickrParser()
    val response = Source.fromFile(file).getLines().mkString("\n")

    parser.parse(response)
  }
} 
Example 88
Source File: FlickrClientSpec.scala    From scalando   with MIT License 5 votes vote down vote up
package com.jcranky.flickr

import com.jcranky.flickr.FlickrClient.ClientError
import com.jcranky.flickr.HttpClient.{GetError, GetResponse}
import com.jcranky.flickr.model.Foto
import com.typesafe.config.{ConfigException, ConfigFactory}
import org.specs2.mock.Mockito
import org.specs2.mutable.Specification

class FlickrClientSpec extends Specification with Mockito {
  "FlickrClient.fromConfig" should {
    "work with valid configuration" in {
      val client = FlickrClient.fromConfig(ConfigFactory.load("app-test.conf"))
      client !=== null
    }

    "fail if some configuration is missing" in {
      FlickrClient.fromConfig(ConfigFactory.load("acre.conf")) should throwAn[ConfigException]
    }
  }

  "FlickrClient.buscaFotos" should {
    "ask the httpclient for the photos and pass the response to the response parser" in {
      val fotos = List(Foto("1", "jcranky", "123", "321", 1, "my pic", true, false, false))
      val resp = buscaFotos(
        Right(GetResponse(200, "fotos-xml-here")),
        Right(fotos)
      )

      resp should beRight(fotos)
    }

    "return a client error if the parser returns a FlickrError" in {
      val error = FlickrKnownError(100, "Invalid API Key (Key has invalid format)")
      val resp = buscaFotos(
        Right(GetResponse(200, "error-xml-here")),
        Left(error)
      )

      resp should beLeft(ClientError(error.toString))
    }
  }

  
  def buscaFotos(httpResp: Either[GetError, GetResponse], parsed: Either[FlickrError, Seq[Foto]]): Either[ClientError, Seq[Foto]] = {
    val httpClient = mock[HttpClient]
    val parser = mock[ResponseParser]

    httpClient.get(any[String]) returns httpResp
    parser.parse(any[String]) returns parsed

    val client = new FlickrClient("api-key", "base-url", httpClient, parser)
    val resp = client.buscaFotos(List("scala"))

    there was one(httpClient).get(anyString)

    resp
  }
} 
Example 89
Source File: JwtDirectivesSpec.scala    From spray-jwt   with MIT License 5 votes vote down vote up
package com.github.kikuomax.spray.jwt

import com.nimbusds.jose.{
  JWSAlgorithm,
  JWSObject
}
import com.nimbusds.jwt.JWTClaimsSet
import java.util.Calendar
import org.specs2.mutable.Specification
import scala.concurrent.{
  ExecutionContext,
  Future
}
import scala.concurrent.duration.{
  Duration,
  SECONDS
}
import spray.routing.HttpService
import spray.routing.authentication.UserPass
import spray.testkit.Specs2RouteTest
import JwtClaimBuilder.claimExpiration


class JwtDirectivesSpec
  extends Specification with Specs2RouteTest with HttpService with JwtDirectives
{
  // uses the one provided by spray.testkit
  override def actorRefFactory = system

  // implicit execution context
  implicit val executionContext = system.dispatcher

  // creates signer and verifier
  val signature = JwtSignature(JWSAlgorithm.HS256, "thisHasGotToBeAtleast32BitsLong.")

  // claims set builder that builds a claims set valid for one second
  val oneSecondBuilder: String => Option[JWTClaimsSet] =
    claimExpiration(Duration(1, SECONDS))

  // route that builds a claims set valid for one second
  val oneSecondRoute =
    get {
      def authenticator = jwtAuthenticator(up => Future { up.map(_.user) })(
        oneSecondBuilder, signature.jwtSigner, executionContext)
      def authentication = authenticator(Some(UserPass("user", "pass"))).map {
        u => Right(u.get)
      }
      authenticate(authentication) { jws =>
        complete(jws.serialize())
      }
    }

  "One second claims set builder" should {
    "build claims set valid for one second" in {
      val now = Calendar.getInstance()
      val expireBefore = now.clone().asInstanceOf[Calendar]
      expireBefore.add(Calendar.SECOND, 2)  // in 2 seconds
      Get() ~> oneSecondRoute ~> check {
        val jws = JWSObject.parse(responseAs[String])
        val claims = JWTClaimsSet.parse(jws.getPayload().toJSONObject())
        // expects claims set
        // should expire after now but in 2 seconds from `now`
        claims.getExpirationTime().after(now.getTime()) must beTrue
        claims.getExpirationTime().before(expireBefore.getTime()) must beTrue
      }
    }
  }
} 
Example 90
Source File: UtilsSpec.scala    From akka-pusher   with MIT License 5 votes vote down vote up
package com.github.dtaniwaki.akka_pusher

import akka.http.scaladsl.model.Uri
import org.specs2.mutable.Specification
import org.specs2.specification.process.RandomSequentialExecution

class UtilsSpec extends Specification
    with SpecHelper
    with RandomSequentialExecution {
  "#byteArrayToString" should {
    "convert a byte array to a string" in {
      Utils.byteArrayToString(Array[Byte](10, 11, 12)) === "000000000000000000000000000a0b0c"
    }
  }
  "#md5" should {
    "generate hex digest md5" in {
      Utils.md5("foo") === "acbd18db4cc2f85cedef654fccc4a4d8"
    }
  }
  "#sha256" should {
    "generate hex digest sha256" in {
      Utils.sha256("secret", "foo") === "773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4"
    }
    "generate hex digest sha256 of strings with 日本語" in {
      Utils.sha256("secret", "Digest me 日本語") === "b52446253d26c4bd19c1200e310ddc8ff3678f3422b2df6c47b153209cadec0b"
      // echo -n "Digest me 日本語" | openssl dgst -sha256 -hmac "secret"
    }
  }
  "#normalizeQuery" should {
    "make the key lower case" in {
      Utils.normalizeQuery(Uri.Query(Map("abc" -> "abc", "CDE" -> "CDE"))).toString === "abc=abc&cde=CDE"
    }
    "make the order alphabetical" in {
      Utils.normalizeQuery(Uri.Query(Map("cde" -> "cde", "abc" -> "abc"))).toString === "abc=abc&cde=cde"
    }
  }
} 
Example 91
Source File: PusherMessagesSpec.scala    From akka-pusher   with MIT License 5 votes vote down vote up
package com.github.dtaniwaki.akka_pusher

import com.github.dtaniwaki.akka_pusher.PusherMessages._
import com.github.dtaniwaki.akka_pusher.attributes.{ PusherChannelsAttributes, PusherChannelAttributes }
import org.specs2.mutable.Specification
import org.specs2.specification.process.RandomSequentialExecution
import spray.json._

class PusherMessagesSpec extends Specification
    with SpecHelper
    with RandomSequentialExecution
    with PusherJsonSupport {

  "ChannelMessage" in {
    "#apply" should {
      "(deprecated) convert the argument type" in {
        ChannelMessage("channel", Some(Seq("user_count"))) === ChannelMessage("channel", Seq(PusherChannelAttributes.userCount))
      }
    }
  }
  "ChannelsMessage" in {
    "#apply" should {
      "(deprecated) convert the argument type" in {
        ChannelsMessage("channel", Some(Seq("user_count"))) === ChannelsMessage("channel", Seq(PusherChannelsAttributes.userCount))
      }
    }
  }
} 
Example 92
Source File: CQLHelperSpec.scala    From cassandra-util   with Apache License 2.0 5 votes vote down vote up
package com.protectwise.cql

import org.specs2.mutable.{After, Specification}

class CQLHelperSpec extends Specification {

  "CQLHelper" should {

    "provide a stringcontext to compose CQL statements" in {
      cql"foo" must beAnInstanceOf[CQLStatement]
    }

    "provide parameter binding" in {
      val bar=1
      val c = cql"foo $bar"
      c.cqlParts mustEqual Seq("foo ", "")
      c.rawParams mustEqual Seq(bar)
    }

    "handle the In() operator" in {
      val c = cql"foo ${In(Seq(1,2))} bar"
      c.cql mustEqual "foo ?,? bar"
      c.parameters mustEqual Seq(1,2)
      c.debugString(null) mustEqual "foo 1,2 bar;"
    }

    "handle the In() operator with just one value" in {
      val c = cql"foo ${In(Seq(1))} bar"
      c.cql mustEqual "foo ? bar"
      c.parameters mustEqual Seq(1)
    }

    "handle an empty In() operator" in {
      val c = cql"foo ${In(Seq())} bar"
      c.cql mustEqual "foo  bar"
      c.parameters mustEqual Seq()
    }

    "accept an Inline() text" in {
      val c = cql"foo ${Inline("x")} bar"
      c.cql mustEqual "foo x bar"
      c.parameters mustEqual Seq()
    }

    "handle a NoArg" in {
      val c = cql"foo $NoArg bar"
      c.cql mustEqual "foo  bar"
      c.parameters mustEqual Seq()
    }

    "handle .withValues on an In() operator" in {
      val a = cql"a ${} b ${} c ${} d"
      val b = a.withValues(1, In(Seq(2,3,4)), 5)
      b.cql mustEqual "a ? b ?,?,? c ? d"
      b.parameters mustEqual(Seq(1,2,3,4,5))
    }

  }

} 
Example 93
Source File: LinkSpec.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi.model

import org.specs2.mutable.Specification

import spray.json._

class LinkSpec extends Specification {
  "handle / in id correctly" >> {
    val url = "/api/foo%2Fbar/rel"
    val url1 =
      s"""
         |"$url"
      """.stripMargin.parseJson

    val url2 =
      s"""
         |{
         |  "href": "$url"
         |}
      """.stripMargin.parseJson

    url1 must be equalTo url1.convertTo[Link].toJson
    url2 must be equalTo url2.convertTo[Link].toJson

    url1.convertTo[Link].href.toString(Link.uriConfig) must be equalTo url
    url2.convertTo[Link].href.toString(Link.uriConfig) must be equalTo url
  }

  "handle : in id correctly" >> {
    val url = "/api/foo%3Abar/rel"
    val url1 =
      s"""
         |"$url"
      """.stripMargin.parseJson

    val url2 =
      s"""
         |{
         |  "href": "$url"
         |}
      """.stripMargin.parseJson

    url1 must be equalTo url1.convertTo[Link].toJson
    url2 must be equalTo url2.convertTo[Link].toJson

    url1.convertTo[Link].href.toString(Link.uriConfig) must be equalTo url
    url2.convertTo[Link].href.toString(Link.uriConfig) must be equalTo url
  }
} 
Example 94
Source File: SprayExceptionHandlerSpec.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi.spray

import org.specs2.mutable.Specification
import _root_.spray.http.StatusCodes._
import _root_.spray.http.{ContentType, MediaTypes}
import _root_.spray.json.DefaultJsonProtocol._
import _root_.spray.json.lenses.JsonLenses._
import _root_.spray.json.{JsArray, JsonParser}
import _root_.spray.routing.Directives
import _root_.spray.testkit.Specs2RouteTest

class SprayExceptionHandlerSpec extends Specification with Directives with Specs2RouteTest {
  class TestSprayExceptionHandler extends SprayExceptionHandler

  val testSprayExceptionHandler = new TestSprayExceptionHandler
  private[this] val wrap        = handleExceptions(testSprayExceptionHandler.defaultSprayExceptionHandler)
  val JSON                      = ContentType(MediaTypes.`application/vnd.api+json`, None)

  "The spray ExceptionHandler" should {
    "Respond with InternalServerError and specified error message" in {
      Get() ~> wrap {
        failWith(new Exception("Specified error message"))
      } ~> check {
        status must_== InternalServerError
        contentType must_== JSON

        val json  = JsonParser(body.asString)
        val error = json.extract[JsArray]('errors).elements.headOption
        error.map(_.extract[String]('detail)) must beSome("Specified error message")
      }
    }

    "Respond with InternalServerError and default error message" in {
      Get() ~> wrap {
        failWith(new Exception)
      } ~> check {
        status must_== InternalServerError
        contentType must_== JSON

        val json  = JsonParser(body.asString)
        val error = json.extract[JsArray]('errors).elements.headOption
        error.map(_.extract[String]('detail)) must beSome(InternalServerError.defaultMessage)
      }
    }

    "None should return 404 with proper jsonapi.org error object" in {
      Get() ~> wrap {
        val x: Option[String] = None

        SprayExceptionHandler.noneHandler {
          complete(x)
        }
      } ~> check {
        status must_== NotFound
        contentType must_== JSON

        val json  = JsonParser(body.asString)
        val error = json.extract[JsArray]('errors).elements.headOption
        error.map(_.extract[String]('detail)) must beSome(NotFound.defaultMessage)
        error.map(_.extract[String]('title)) must beSome(NotFound.reason)
      }
    }
  }
} 
Example 95
Source File: RelatedResponseSpec.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi

import org.specs2.ScalaCheck
import org.specs2.mutable.Specification
import spray.json.{JsArray, JsNull, JsObject}
import _root_.spray.json._
import _root_.spray.json.DefaultJsonProtocol._

class RelatedResponseSpec extends Specification with ScalaCheck {
  implicit val apiRoot: com.qvantel.jsonapi.ApiRoot = ApiRoot(None)

  @jsonApiResource final case class Test(id: String, name: String, age: Int)
  @jsonApiResource final case class Test2(id: String, name: String, age: Int)

  val test: Option[Test]      = Some(Test("teståöä•Ωé®", "someName", 20)) // test UTF-8
  val emptyTest: Option[Test] = None
  val tests: List[Test]       = List(Test("test 1", "someName1", 20), Test("test 2", "someName2", 21))
  val emptyTests: List[Test]  = List.empty

  def transformToTest2(in: Test): Test2 = Test2(in.id + "-2", in.name, in.age)

  "correctly write to one none case" in {
    RelatedResponse(emptyTest).toResponse must be equalTo JsObject(
      "data" -> JsNull
    )

    RelatedResponse(emptyTest).map(transformToTest2).toResponse must be equalTo JsObject(
      "data" -> JsNull
    )
  }

  "correctly write to one some case" in {
    val answer = rawOne(test.get)

    RelatedResponse(test).toResponse must be equalTo answer
    RelatedResponse(test.get).toResponse must be equalTo answer

    val transformedAnswer = rawOne(transformToTest2(test.get))
    RelatedResponse(test).map(transformToTest2).toResponse must be equalTo transformedAnswer
    RelatedResponse(test.get).map(transformToTest2).toResponse must be equalTo transformedAnswer
  }

  "correctly write to many empty case" in {
    RelatedResponse(emptyTests).toResponse must be equalTo JsObject(
      "data" -> JsArray.empty
    )

    RelatedResponse(emptyTests).map(transformToTest2).toResponse must be equalTo JsObject(
      "data" -> JsArray.empty
    )
  }

  "correctly write to many non-empty case" in {
    val answer = rawCollection(tests)

    RelatedResponse(tests).toResponse must be equalTo answer
    RelatedResponse(tests.toSeq).toResponse must be equalTo answer
    RelatedResponse(tests.toIterable).toResponse must be equalTo answer
    RelatedResponse(tests.toSet).toResponse must be equalTo answer

    val transformedAnswer = rawCollection(tests.map(transformToTest2))

    RelatedResponse(tests).map(transformToTest2).toResponse must be equalTo transformedAnswer
    RelatedResponse(tests.toSeq).map(transformToTest2).toResponse must be equalTo transformedAnswer
    RelatedResponse(tests.toIterable).map(transformToTest2).toResponse must be equalTo transformedAnswer
    RelatedResponse(tests.toSet).map(transformToTest2).toResponse must be equalTo transformedAnswer
  }

  "correctly write sparse fieldsets" in {
    implicit val sparseFields: Map[String, List[String]] = Map("tests" -> List("age"), "test2s" -> List("age"))
    val answer                                           = rawOne(test.get)

    RelatedResponse(test).toResponse must be equalTo answer
    RelatedResponse(test.get).toResponse must be equalTo answer

    val transformedAnswer = rawOne(transformToTest2(test.get))

    RelatedResponse(test).map(transformToTest2).toResponse must be equalTo transformedAnswer
    RelatedResponse(test.get).map(transformToTest2).toResponse must be equalTo transformedAnswer
  }
} 
Example 96
Source File: WithoutIdSpec.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi

import org.specs2.mutable.Specification
import _root_.spray.json._
import _root_.spray.json.DefaultJsonProtocol._

class WithoutIdSpec extends Specification {
  implicit val apiRoot: com.qvantel.jsonapi.ApiRoot = ApiRoot(None)

  @jsonApiResource("normal", "no-id") case class Test(name: String, child: ToOne[Child])
  @jsonApiResource case class Child(id: String, name: String, age: Int)

  "json api resource" should {
    "work without id" in {
      val c = Child("test-id", "test-name", 20)
      val t = Test("test", ToOne.loaded(c))

      val primaryJson =
        """
          |{
          |  "type": "tests",
          |  "attributes": {
          |    "name": "test"
          |  },
          |  "relationships": {
          |    "child": {
          |      "data": {
          |        "type": "children",
          |        "id": "test-id"
          |      }
          |    }
          |  }
          |}
        """.stripMargin.parseJson

      implicitly[JsonApiWriter[Test]].write(t) must be equalTo primaryJson
      implicitly[JsonApiWriter[Test]].included(t) must be equalTo Set(
        implicitly[JsonApiWriter[Child]].write(c).asJsObject)
    }

    "work without id and sparse fields" in {
      val c            = Child("test-id", "test-name", 20)
      val t            = Test("test", ToOne.loaded(c))
      val sparseFields = Map("tests" -> List("name"), "children" -> List("age"))

      val primaryJson =
        """
          |{
          |  "type": "tests",
          |  "attributes": {
          |    "name": "test"
          |  }
          |}
        """.stripMargin.parseJson

      implicitly[JsonApiWriter[Test]].write(t, sparseFields) must be equalTo primaryJson
      implicitly[JsonApiWriter[Test]].included(t, sparseFields) must be equalTo Set(
        implicitly[JsonApiWriter[Child]].write(c, sparseFields).asJsObject)
    }
  }
} 
Example 97
Source File: PathToSpec.scala    From jsonapi-scala   with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
package com.qvantel.jsonapi

import org.specs2.mutable.Specification
import com.netaporter.uri.dsl._
import _root_.spray.json.DefaultJsonProtocol._

class PathToSpec extends Specification {
  implicit val apiRoot = ApiRoot(Some("foo" / "bar"))

  @jsonApiResource final case class Test(id: String)

  "apiRoot should be printed to PathTo output" >> {
    val t = Test("1")

    PathTo[Test].entity(t) must be equalTo "foo/bar/tests/1"
    PathToId[Test].self("test") must be equalTo "foo/bar/tests/test"

    rawOne(t)
      .fields("data")
      .asJsObject
      .fields("links")
      .asJsObject
      .fields("self")
      .convertTo[String] must be equalTo "foo/bar/tests/1"
  }

  "root should print out apiRoot" >> {
    PathTo[Test].root must be equalTo "foo/bar/tests"
  }
} 
Example 98
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{OrderCancelRejected, OrderCanceled}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class ListOrderBookCancelingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When cancel order arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (id, ci, ei) =>
    ListOrderBook.handle(
      () => ei, ListOrderBook.empty, CancelOrder(ci, id))._2 ====
      OrderCancelRejected(ei, id)
  }

  """Given empty book
    |and buy limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (o, ci, ei) =>
    (ListOrderBook.handle(
      () => ei, _: ListOrderBook, AddLimitOrder(ci, o))).andThen {
      case (ob, _) => ListOrderBook.handle(
        () => ei, ob, CancelOrder(ci, o.id))._2
    }(ListOrderBook.empty) ==== OrderCanceled(ei, o.id)
  }

  """Given empty book
    |and sell limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (o, ci, ei) =>
    (ListOrderBook.handle(
      () => ei, _: ListOrderBook, AddLimitOrder(ci, o))).andThen {
      case (ob, _) => ListOrderBook.handle(
        () => ei, ob, CancelOrder(ci, o.id))._2
    }(ListOrderBook.empty) ==== OrderCanceled(ei, o.id)
  }

} 
Example 99
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{OrderCancelRejected, OrderCanceled}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class QueueOrderBookCancelingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When cancel order arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (id, ci, ei) =>
    QueueOrderBook.handle(
      () => ei, QueueOrderBook.empty, CancelOrder(ci, id))._2 ====
      OrderCancelRejected(ei, id)
  }

  """Given empty book
    |and buy limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (o, ci, ei) =>
    (QueueOrderBook.handle(
      () => ei, _: QueueOrderBook, AddLimitOrder(ci, o))).andThen {
      case (ob, _) => QueueOrderBook.handle(
        () => ei, ob, CancelOrder(ci, o.id))._2
    }(QueueOrderBook.empty) ==== OrderCanceled(ei, o.id)
  }

  """Given empty book
    |and sell limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (o, ci, ei) =>
    (QueueOrderBook.handle(
      () => ei, _: QueueOrderBook, AddLimitOrder(ci, o))).andThen {
      case (ob, _) => QueueOrderBook.handle(
        () => ei, ob, CancelOrder(ci, o.id))._2
    }(QueueOrderBook.empty) ==== OrderCanceled(ei, o.id)
  }

} 
Example 100
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{LimitOrderAdded, OrderCancelRejected, OrderExecuted}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class LazyCancelOrderBookTradingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    LimitOrder.genLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (l, ci, ei) =>
    LazyCancelOrderBook.handle(
      () => ei, LazyCancelOrderBook.empty, AddLimitOrder(ci, l))._2 ====
      LimitOrderAdded(ei)
  }

  """Given empty book
    |and buy limit order added
    |When resting sell limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (buy, id, ci, ei) =>
    (LazyCancelOrderBook.handle(
      () => ei, _: LazyCancelOrderBook, AddLimitOrder(ci, buy))).andThen {
      case (ob, _) => LazyCancelOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
        SellLimitOrder(id, Price(buy.price.value + 0.01))))._2
    }(LazyCancelOrderBook.empty) ==== LimitOrderAdded(ei)
  }

  """Given empty book
    |and sell limit order added
    |When resting buy limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (sell, id, ci, ei) =>
    (LazyCancelOrderBook.handle(() => ei, _: LazyCancelOrderBook, AddLimitOrder(ci, sell)))
      .andThen {
        case (ob, _) => LazyCancelOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          BuyLimitOrder(id, Price(sell.price.value - 0.01))))._2
      }(LazyCancelOrderBook.empty) ==== LimitOrderAdded(ei)
  }

  """Given empty book
    |and buy limit order added
    |When crossing sell limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (buy, id, ci, ei) =>
    (LazyCancelOrderBook.handle(() => ei, _: LazyCancelOrderBook, AddLimitOrder(ci, buy)))
      .andThen {
        case (ob, _) => LazyCancelOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          SellLimitOrder(id, Price(buy.price.value - 0.01))))._2
      }(LazyCancelOrderBook.empty) ==== OrderExecuted(ei,
      Execution(buy.id, buy.price), Execution(id, buy.price))
  }

  """Given empty book
    |and sell limit order added
    |When crossing buy limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (sell, id, ci, ei) =>
    (LazyCancelOrderBook.handle(() => ei, _: LazyCancelOrderBook, AddLimitOrder(ci, sell)))
      .andThen {
        case (ob, _) => LazyCancelOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          BuyLimitOrder(id, Price(sell.price.value + 0.01))))._2
      }(LazyCancelOrderBook.empty) ==== OrderExecuted(ei,
      Execution(id, sell.price), Execution(sell.id, sell.price))
  }

  """Given empty book
    |When cancel order command arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (id, ci, ei) =>
    LazyCancelOrderBook.handle(() => ei, LazyCancelOrderBook.empty, CancelOrder(ci, id))
      ._2 ==== OrderCancelRejected(ei, id)
  }
} 
Example 101
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{OrderCancelRejected, OrderCanceled}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class LazyCancelOrderBookCancelingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When cancel order arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (id, ci, ei) =>
    LazyCancelOrderBook.handle(
      () => ei, LazyCancelOrderBook.empty, CancelOrder(ci, id))._2 ====
      OrderCancelRejected(ei, id)
  }

  """Given empty book
    |and buy limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (o, ci, ei) =>
    (LazyCancelOrderBook.handle(
      () => ei, _: LazyCancelOrderBook, AddLimitOrder(ci, o))).andThen {
      case (ob, _) => LazyCancelOrderBook.handle(
        () => ei, ob, CancelOrder(ci, o.id))._2
    }(LazyCancelOrderBook.empty) ==== OrderCanceled(ei, o.id)
  }

  """Given empty book
    |and sell limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (o, ci, ei) =>
    (LazyCancelOrderBook.handle(
      () => ei, _: LazyCancelOrderBook, AddLimitOrder(ci, o))).andThen {
      case (ob, _) => LazyCancelOrderBook.handle(
        () => ei, ob, CancelOrder(ci, o.id))._2
    }(LazyCancelOrderBook.empty) ==== OrderCanceled(ei, o.id)
  }

} 
Example 102
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{LimitOrderAdded, OrderCancelRejected, OrderExecuted}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class ListOrderBookTradingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    LimitOrder.genLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (l, ci, ei) =>
    ListOrderBook.handle(
      () => ei, ListOrderBook.empty, AddLimitOrder(ci, l))._2 ====
      LimitOrderAdded(ei)
  }

  """Given empty book
    |and buy limit order added
    |When resting sell limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (buy, id, ci, ei) =>
    (ListOrderBook.handle(
      () => ei, _: ListOrderBook, AddLimitOrder(ci, buy))).andThen {
      case (ob, _) => ListOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
        SellLimitOrder(id, Price(buy.price.value + 0.01))))._2
    }(ListOrderBook.empty) ==== LimitOrderAdded(ei)
  }

  """Given empty book
    |and sell limit order added
    |When resting buy limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (sell, id, ci, ei) =>
    (ListOrderBook.handle(() => ei, _: ListOrderBook, AddLimitOrder(ci, sell)))
      .andThen {
        case (ob, _) => ListOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          BuyLimitOrder(id, Price(sell.price.value - 0.01))))._2
      }(ListOrderBook.empty) ==== LimitOrderAdded(ei)
  }

  """Given empty book
    |and buy limit order added
    |When crossing sell limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (buy, id, ci, ei) =>
    (ListOrderBook.handle(() => ei, _: ListOrderBook, AddLimitOrder(ci, buy)))
      .andThen {
        case (ob, _) => ListOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          SellLimitOrder(id, Price(buy.price.value - 0.01))))._2
      }(ListOrderBook.empty) ==== OrderExecuted(ei,
      Execution(buy.id, buy.price), Execution(id, buy.price))
  }

  """Given empty book
    |and sell limit order added
    |When crossing buy limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (sell, id, ci, ei) =>
    (ListOrderBook.handle(() => ei, _: ListOrderBook, AddLimitOrder(ci, sell)))
      .andThen {
        case (ob, _) => ListOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          BuyLimitOrder(id, Price(sell.price.value + 0.01))))._2
      }(ListOrderBook.empty) ==== OrderExecuted(ei,
      Execution(id, sell.price), Execution(sell.id, sell.price))
  }

  """Given empty book
    |When cancel order command arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (id, ci, ei) =>
    ListOrderBook.handle(() => ei, ListOrderBook.empty, CancelOrder(ci, id))
      ._2 ==== OrderCancelRejected(ei, id)
  }
} 
Example 103
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{LimitOrderAdded, OrderCancelRejected, OrderExecuted}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class QueueOrderBookTradingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    LimitOrder.genLimitOrder,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (l, ci, ei) =>
     QueueOrderBook.handle(
      () => ei,  QueueOrderBook.empty, AddLimitOrder(ci, l))._2 ====
      LimitOrderAdded(ei)
  }

  """Given empty book
    |and buy limit order added
    |When resting sell limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (buy, id, ci, ei) =>
    ( QueueOrderBook.handle(
      () => ei, _:  QueueOrderBook, AddLimitOrder(ci, buy))).andThen {
      case (ob, _) =>  QueueOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
        SellLimitOrder(id, Price(buy.price.value + 0.01))))._2
    }( QueueOrderBook.empty) ==== LimitOrderAdded(ei)
  }

  """Given empty book
    |and sell limit order added
    |When resting buy limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (sell, id, ci, ei) =>
    ( QueueOrderBook.handle(() => ei, _:  QueueOrderBook, AddLimitOrder(ci, sell)))
      .andThen {
        case (ob, _) =>  QueueOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          BuyLimitOrder(id, Price(sell.price.value - 0.01))))._2
      }( QueueOrderBook.empty) ==== LimitOrderAdded(ei)
  }

  """Given empty book
    |and buy limit order added
    |When crossing sell limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(
    BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (buy, id, ci, ei) =>
    ( QueueOrderBook.handle(() => ei, _:  QueueOrderBook, AddLimitOrder(ci, buy)))
      .andThen {
        case (ob, _) =>  QueueOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          SellLimitOrder(id, Price(buy.price.value - 0.01))))._2
      }( QueueOrderBook.empty) ==== OrderExecuted(ei,
      Execution(buy.id, buy.price), Execution(id, buy.price))
  }

  """Given empty book
    |and sell limit order added
    |When crossing buy limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(
    SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (sell, id, ci, ei) =>
    ( QueueOrderBook.handle(() => ei, _:  QueueOrderBook, AddLimitOrder(ci, sell)))
      .andThen {
        case (ob, _) =>  QueueOrderBook.handle(() => ei, ob, AddLimitOrder(ci,
          BuyLimitOrder(id, Price(sell.price.value + 0.01))))._2
      }( QueueOrderBook.empty) ==== OrderExecuted(ei,
      Execution(id, sell.price), Execution(sell.id, sell.price))
  }

  """Given empty book
    |When cancel order command arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(
    OrderId.genOrderId,
    CommandInstant.genCommandInstant,
    EventInstant.genEventInstant) { (id, ci, ei) =>
     QueueOrderBook.handle(() => ei,  QueueOrderBook.empty, CancelOrder(ci, id))
      ._2 ==== OrderCancelRejected(ei, id)
  }
} 
Example 104
Source File: MidpointSeriesSpec.scala    From Scala-High-Performance-Programming   with MIT License 5 votes vote down vote up
package highperfscala.dataanalysis

import org.joda.time.DateTime
import org.specs2.mutable.Specification

class MidpointSeriesSpec extends Specification {

  "A MidpointSeries" should {

    "be properly created from execution data points" in {
      val t0 = TimestampMinutes.fromDateTime(DateTime.now)
      val t1 = t0.next
      val t2 = t1.next
      val t3 = t2.next
      val t4 = t3.next
      val t5 = t4.next
      val t6 = t5.next
      val executions = Vector(
        Execution(t0, AskPrice(40), BidPrice(20)),
        Execution(t1, AskPrice(30), BidPrice(25)),
        Execution(t1, AskPrice(50), BidPrice(22)),
        Execution(t4, AskPrice(24), BidPrice(16)),
        Execution(t4, AskPrice(84), BidPrice(78)),
        Execution(t4, AskPrice(64), BidPrice(37)),
        Execution(t6, AskPrice(41), BidPrice(23))
      )

      val series = MidpointSeries.fromExecution(executions)
      series.size ==== 7
      series.midpointAt(t0).get ==== Midpoint(t0, 30)
      series.midpointAt(t1).get ==== Midpoint(t1, 31.75)
      series.midpointAt(t2).get ==== Midpoint(t2, 31.75)
      series.midpointAt(t3).get ==== Midpoint(t3, 31.75)
      series.midpointAt(t4).get ==== Midpoint(t4, 50.5)
      series.midpointAt(t5).get ==== Midpoint(t5, 50.5)
      series.midpointAt(t6).get ==== Midpoint(t6, 32)
      series.midpointAt(t6.next) ==== None
    }

  }

} 
Example 105
Source File: OrderBookTradingSpec.scala    From Scala-High-Performance-Programming   with MIT License 5 votes vote down vote up
package highperfscala.orderbook

import highperfscala.orderbook.Commands.{CancelOrder, AddLimitOrder}
import highperfscala.orderbook.Events.{OrderCancelRejected, OrderExecuted, LimitOrderAdded}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class OrderBookTradingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(LimitOrder.genLimitOrder) { l =>
    OrderBook.handle(OrderBook.empty, AddLimitOrder(l))._2 ==== LimitOrderAdded
  }

  """Given empty book
    |and buy limit order added
    |When resting sell limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId) { (buy, id) =>
    (OrderBook.handle(_: OrderBook, AddLimitOrder(buy))).andThen {
      case (ob, _) => OrderBook.handle(ob, AddLimitOrder(
        SellLimitOrder(id, Price(buy.price.value + 0.01))))._2
    }(OrderBook.empty) ==== LimitOrderAdded
  }

  """Given empty book
    |and sell limit order added
    |When resting buy limit order arrives
    |Then LimitOrderAdded
  """.stripMargin ! Prop.forAll(SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId) { (sell, id) =>
    (OrderBook.handle(_: OrderBook, AddLimitOrder(sell))).andThen {
      case (ob, _) => OrderBook.handle(ob, AddLimitOrder(
        BuyLimitOrder(id, Price(sell.price.value - 0.01))))._2
    }(OrderBook.empty) ==== LimitOrderAdded
  }

  """Given empty book
    |and buy limit order added
    |When crossing sell limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(BuyLimitOrder.genBuyLimitOrder,
    OrderId.genOrderId) { (buy, id) =>
    (OrderBook.handle(_: OrderBook, AddLimitOrder(buy))).andThen {
      case (ob, _) => OrderBook.handle(ob, AddLimitOrder(
        SellLimitOrder(id, Price(buy.price.value - 0.01))))._2
    }(OrderBook.empty) ==== OrderExecuted(
      Execution(buy.id, buy.price), Execution(id, buy.price))
  }

  """Given empty book
    |and sell limit order added
    |When crossing buy limit order arrives
    |Then OrderExecuted
  """.stripMargin ! Prop.forAll(SellLimitOrder.genSellLimitOrder,
    OrderId.genOrderId) { (sell, id) =>
    (OrderBook.handle(_: OrderBook, AddLimitOrder(sell))).andThen {
      case (ob, _) => OrderBook.handle(ob, AddLimitOrder(
        BuyLimitOrder(id, Price(sell.price.value + 0.01))))._2
    }(OrderBook.empty) ==== OrderExecuted(
      Execution(id, sell.price), Execution(sell.id, sell.price))
  }

  """Given empty book
    |When cancel order command arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(OrderId.genOrderId) { id =>
    OrderBook.handle(OrderBook.empty, CancelOrder(id))._2 ====
      OrderCancelRejected
  }
} 
Example 106
Source File: OrderBookCancelingSpec.scala    From Scala-High-Performance-Programming   with MIT License 5 votes vote down vote up
package highperfscala
package orderbook

import highperfscala.orderbook.Commands.{AddLimitOrder, CancelOrder}
import highperfscala.orderbook.Events.{OrderCanceled, OrderCancelRejected}
import org.scalacheck.Prop
import org.specs2.ScalaCheck
import org.specs2.mutable.Specification

class OrderBookCancelingSpec extends Specification with ScalaCheck {

  """Given empty book
    |When cancel order arrives
    |Then OrderCancelRejected
  """.stripMargin ! Prop.forAll(OrderId.genOrderId) { id =>
    OrderBook.handle(OrderBook.empty, CancelOrder(id))._2 ====
      OrderCancelRejected
  }

  """Given empty book
    |and buy limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(BuyLimitOrder.genBuyLimitOrder) { o =>
    (OrderBook.handle(_: OrderBook, AddLimitOrder(o))).andThen {
      case (ob, _) => OrderBook.handle(ob, CancelOrder(o.id))._2
    }(OrderBook.empty) ==== OrderCanceled
  }

  """Given empty book
    |and sell limit order added
    |When cancel order arrives
    |Then OrderCanceled
  """.stripMargin ! Prop.forAll(SellLimitOrder.genSellLimitOrder) { o =>
    (OrderBook.handle(_: OrderBook, AddLimitOrder(o))).andThen {
      case (ob, _) => OrderBook.handle(ob, CancelOrder(o.id))._2
    }(OrderBook.empty) ==== OrderCanceled
  }

} 
Example 107
Source File: IntTreeTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter07

import org.specs2.mutable.Specification

class IntTreeTest extends Specification {
  "com.es.scala.chapter07.IntTree" should {
    "confirm that the EmptyTree does not contain any element" in {
      val instance = Node(5, EmptyTree, EmptyTree)
      instance.contains(EmptyTree, 5) mustEqual(false)
    }
    "confirm that a tree with one element contains that element" in {
      val instance = Node(1, EmptyTree, EmptyTree)
      instance.contains(instance, 1) mustEqual(true)
    }
    "confirm that a tree with two elements contains both of them" in {
      val instance = Node(1, EmptyTree, EmptyTree)
      val instance2 = Node(2, instance, EmptyTree)
      instance.contains(instance2, 2) mustEqual(true)
      instance.contains(instance2, 1) mustEqual(true)
    }
    "confirm that a tree with multiple elements contains every one of them" in {
      val instance = Node (3, Node(1, EmptyTree, EmptyTree), Node(2, EmptyTree, EmptyTree))
      instance.contains(instance, 1) mustEqual(true)
      instance.contains(instance, 2) mustEqual(true)
      instance.contains(instance, 3) mustEqual(true)
    }
    "by the way, confirm that case classes allow to easily reference what went into their constructor" in {
      val instance = Node (3, Node(1, EmptyTree, EmptyTree), Node(2, EmptyTree, EmptyTree))
      instance.elem mustEqual 3
      instance.left mustEqual(Node(1, EmptyTree, EmptyTree))
      instance.right mustEqual(Node(2, EmptyTree, EmptyTree))
    }
  }
} 
Example 108
Source File: RationalTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter06

import org.specs2.mutable.Specification

class RationalTest extends Specification {
  "com.es.scala.chapter06.Rational" should {
    "compute the sum of rational numbers from 1/1 to 1/10" in {
      var i = 1
      var x = new Rational(0, 1)
      while (i <= 10) {
        x += new Rational(1, i)
        i += 1
      }
      (new Rational(7381, 2520) == x) must beTrue
    }
  }
} 
Example 109
Source File: SetTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter06

import org.specs2.mutable.Specification

class SetTest extends Specification {
  "com.es.scala.chapter06.IntSet" should {
    "verify that no element belongs to EmptySet" in {
      new EmptySet().contains(1) must beFalse
    }
    "verify that correct elements belong to NonEmptySet" in {
      val set = new EmptySet
      val set1 = set.incl(3)
      set1.contains(1) must beFalse
      set1.contains(3) must beTrue
    }
  }
} 
Example 110
Source File: SetTest6.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter06

import org.specs2.mutable.Specification

class SetTest6 extends Specification {
  "com.es.scala.chapter06.IntSet6" should {
    "verify that no element belongs to EmptySet" in {
      new EmptySet6().contains(1) must beFalse
    }
    "verify that correct elements belong to NonEmptySet" in {
      val set = new EmptySet6
      val set1 = set.incl(3)
      set1.contains(1) must beFalse
      set1.contains(3) must beTrue
    }
    "verify that union works as expected" in {
      val set = new EmptySet6
      val set1 = set.incl(3).incl(5).incl(1)
      val set2 = set.incl(4).incl(2)
      val set3 = set1.union(set2)
      set3.contains(1) must beTrue
      set3.contains(2) must beTrue
      set3.contains(3) must beTrue
      set3.contains(4) must beTrue
      set3.contains(5) must beTrue
    }
    "verify that intersection works as expected" in {
      val set = new EmptySet6
      val set1 = set.incl(1).incl(3).incl(4).incl(5)
      println("set1 = " + set1.toString)
      val set2 = set.incl(3).incl(4)
      println("set2 = " + set2.toString)
      val set3 = set1.intersection(set2)
      println("set3 = " + set3.toString)
      println("")
      set3.contains(1) must beFalse
      set3.contains(2) must beFalse
      set3.contains(3) must beTrue
      set3.contains(4) must beTrue
      set3.contains(5) must beFalse
      set3.intersection(set).contains(1) must beFalse
    }
  }
} 
Example 111
Source File: FactorialTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter04

import org.specs2.mutable.Specification


class FactorialTest extends Specification {

  "com.es.scala.chapter04.Factorial.factorial" should {
    "calculate factorial" in {
      new Factorial().factorial(5) mustEqual (120)
    }
  }

  "com.es.scala.chapter04.Factorial.factorialR" should {
    "calculate factorial but not require stack" in {
      println("new Factorial().factorialR(5)=" + new Factorial().factorialR(5))
      new Factorial().factorialR(5) mustEqual (120)
    }
  }
} 
Example 112
Source File: NewtonTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter04

import org.specs2.mutable.Specification
import Math.abs


class NewtonTest extends Specification {
  "com.es.scala.chapter04.Newton" should {
    "extract square root" in {
      abs(new Newton().sqrt(4) - 2) must be <= .1
    }
  }

  "com.es.scala.chapter04.Newton1" should {
    "extract square root better for small numbers" in {
      abs(new Newton1().sqrt(.01) - .1) must be <= .1
    }
  }

  "com.es.scala.chapter04.Newton2" should {
    "extract square root with tracing" in {
      abs(new Newton2().sqrt(.01) - .1) must be <= .1
    }
  }

  "com.es.scala.chapter04.Newton3" should {
    "also extract sqrt - it is just a rewrite with nested functions" in {
      abs(new Newton3().sqrt(.01) - .1) must be <= .1
    }
  }

  "com.es.scala.chapter04.Newton4" should {
    "do the same sqrt, just more concise" in {
      abs(new Newton4().sqrt(.01) - .1) must be <= .1
    }
  }
} 
Example 113
Source File: SumTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.chapter05

import com.es.scala.chapter04.Factorial
import org.specs2.mutable.Specification


class SumTest extends Specification {
  "com.es.scala.chapter05.Sum" should {
    "sum the numbers" in {
      new Sum().sum(x => x, 3, 5) mustEqual 12
    }
  }

  "com.es.scala.chapter05.Sum" should {
    "sum squares" in {
      new Sum().sum(x => x * x, 3, 4) mustEqual 25
    }
  }

  "com.es.scala.chapter05.Sum1" should {
    "sum the numbers, just be written shorter" in {
      new Sum1().sum(x => x)(3, 5) mustEqual 12
    }
  }
  "com.es.scala.chapter05.Sum2" should {
    "sum the numbers, shorter yet!" in {
      new Sum2().sum(x => x)(3, 5) mustEqual 12
    }
  }
  "com.es.scala.chapter05.Sum3" should {
    "sum the numbers in tail recursive way" in {
      new Sum3().sum(x => x)(3, 5) mustEqual 12
    }
  }
  "com.es.scala.chapter05.Product" should {
    "multiply numbers of an interval" in {
      new Product().product(x => x)(3, 5) mustEqual 60
    }
  }
} 
Example 114
Source File: UseOfNullTest.scala    From learning-scala   with Apache License 2.0 5 votes vote down vote up
package com.es.scala.more

import org.specs2.mutable.Specification


class UseOfNullTest extends Specification {
  val days = List("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")

  "com.es.scala.more.UseOfNull" should {
    "distinguish between being passed a null or a non-null" in {
      new UseOfNull().exampleOfNull(days) mustEqual ("Sunday")
      new UseOfNull().exampleOfNull(days) mustNotEqual ("Monday")
      (new UseOfNull().exampleOfNull(null) == null) must beTrue
    }
  }

  "com.es.scala.more.UseOfNil" should {
    "distinguish between being passed a Nil (empty list) or a non-Nil" in {
      new UseOfNull().exampleOfNil(days) mustEqual List("Sunday")
      new UseOfNull().exampleOfNil(Nil) mustEqual Nil
    }
  }

  // TODO this fails
//  "com.es.scala.more.UseOfNil" should {
//    "throw 'non implemented' exception" in {
//      new UseOfNull().notImplemented(1) must throwA[Exception]
//    }
//  }

} 
Example 115
Source File: EitherToResponseTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import bad.robot.temperature._
import org.http4s.dsl.io._
import org.specs2.mutable.Specification

import scalaz.{-\/, \/-}

class EitherToResponseTest extends Specification {

  val okResponse = (_: Any) => Ok()

  "Error mappings" >> {
    -\/(CrcFailure()).toHttpResponse(okResponse).unsafeRunSync.status                    must_== InternalServerError
    -\/(SensorError("???")).toHttpResponse(okResponse).unsafeRunSync.status              must_== InternalServerError
    -\/(UnexpectedError("???")).toHttpResponse(okResponse).unsafeRunSync.status          must_== InternalServerError
    -\/(FailedToFindFile("???")).toHttpResponse(okResponse).unsafeRunSync.status         must_== NotFound
    -\/(FileError(new Exception("???"))).toHttpResponse(okResponse).unsafeRunSync.status must_== InternalServerError
  }

  "Success mapping" >> {
    \/-("Well done").toHttpResponse(okResponse).unsafeRunSync.status must_== Ok
  }
} 
Example 116
Source File: TemperaturesTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import java.time.{Clock, Instant, ZoneId}

import bad.robot.temperature._
import bad.robot.temperature.rrd.{Host, Seconds}
import org.specs2.mutable.Specification

class TemperaturesTest extends Specification {

  "Filter out old temperatures" >> {
    val measurement1 = Measurement(Host("lounge"), Seconds(0), List(
      SensorReading("28-00000dfg34ca", Temperature(31.1)),
      SensorReading("28-00000f33fdc3", Temperature(32.8))
    ))
    val measurement2 = Measurement(Host("bedroom"), Seconds(120), List(
      SensorReading("28-00000f3554ds", Temperature(21.1)),
      SensorReading("28-000003dd3433", Temperature(22.8))
    ))

    val temperatures = CurrentTemperatures(fixedClock(Instant.ofEpochSecond(300)))
    temperatures.updateWith(measurement1)
    temperatures.updateWith(measurement2)

    val expected = Map(
      Host("bedroom", None) -> Measurement(Host("bedroom"), Seconds(120), List(
        SensorReading("28-00000f3554ds", Temperature(21.1)),
        SensorReading("28-000003dd3433", Temperature(22.8))
      ))
    )

    temperatures.all must_== expected
  }

  "Filter out old temperatures when averaging" >> {
    val measurement1 = Measurement(Host("lounge"), Seconds(0), List(
      SensorReading("28-00000dfg34ca", Temperature(31.1)),
      SensorReading("28-00000f33fdc3", Temperature(32.8))
    ))
    val measurement2 = Measurement(Host("bedroom"), Seconds(60), List(
      SensorReading("28-00000f3554ds", Temperature(21.1)),
      SensorReading("28-000003dd3433", Temperature(22.8))
    ))

    val temperatures = CurrentTemperatures(fixedClock(Instant.ofEpochSecond(300)))
    temperatures.updateWith(measurement1)
    temperatures.updateWith(measurement2)

    val expected = Map(
      Host("bedroom", None) -> Measurement(Host("bedroom"), Seconds(60), List(
        SensorReading("Average", Temperature(21.950000000000003))
      ))
    )

    temperatures.average must_== expected
  }
  
  
  def fixedClock(instant: Instant = Instant.now) = Clock.fixed(instant, ZoneId.systemDefault())

} 
Example 117
Source File: AllTemperaturesTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import bad.robot.temperature.rrd.{Host, Seconds}
import bad.robot.temperature.{Measurement, SensorReading, Temperature}
import org.specs2.mutable.Specification

class AllTemperaturesTest extends Specification {

  "drain's partially based on time (the most recent 5 seconds are retained)" >> {
    val temperatures = AllTemperatures()
    temperatures.put(measurement("A", 0, 20.0, 20.1))
    temperatures.put(measurement("B", 1, 21.0, 21.1))
    temperatures.put(measurement("C", 2, 22.0, 22.1))
    temperatures.put(measurement("D", 3, 23.2, 23.3))
    temperatures.put(measurement("E", 4, 24.0, 24.1))
    temperatures.put(measurement("F", 5, 25.0, 25.1))
    temperatures.put(measurement("G", 6, 26.0, 26.1))
    temperatures.put(measurement("H", 7, 27.0, 27.1))
    temperatures.put(measurement("I", 8, 28.0, 28.1))
    temperatures.put(measurement("J", 9, 29.0, 29.1))


    temperatures.drainPartially(Seconds(10)) must containTheSameElementsAs(List(
      measurement("A", 0, 20.0, 20.1),
      measurement("B", 1, 21.0, 21.1),
      measurement("C", 2, 22.0, 22.1),
      measurement("D", 3, 23.2, 23.3),
      measurement("E", 4, 24.0, 24.1)
    ))

    temperatures.drainPartially(Seconds(20)) must containTheSameElementsAs(List(
      measurement("F", 5, 25.0, 25.1),
      measurement("G", 6, 26.0, 26.1),
      measurement("H", 7, 27.0, 27.1),
      measurement("I", 8, 28.0, 28.1),
      measurement("J", 9, 29.0, 29.1)
    ))

    temperatures.drainPartially(Seconds(30)) must_== List()
  }

  private def measurement(host: String, time: Long, temperatures: Double*) = {
    Measurement(Host(host), Seconds(time), temperatures.zipWithIndex.map { case (temperature, index) =>
      SensorReading(s"sensor-$index", Temperature(temperature))
    }.toList)
  }
} 
Example 118
Source File: ExportEndpointTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle.SHORT
import java.util.Locale._

import cats.effect.IO
import org.http4s.Method.GET
import org.http4s.Status.Ok
import org.http4s.implicits._
import org.http4s.{Request, Uri}
import org.specs2.mutable.Specification

import scalaz.syntax.either._

class ExportEndpointTest extends Specification {

  sequential

  "convert json to csv" >> {
    val exampleJson =
      """
        |[
        |  {
        |    "label": "bedroom1-sensor-1",
        |    "data": [
        |      {
        |        "x": 1507709610000,
        |        "y": "NaN"
        |      },
        |      {
        |        "x": 1507709640000,
        |        "y": "+2.2062500000E01"
        |      },
        |      {
        |        "x": 1507709680000,
        |        "y": "+2.2262500000E01"
        |      }
        |    ]
        |  }
        |]
      """.stripMargin
    
    val expectedCsv = """"Sensor","Time","Temperature","Difference"
                        |"bedroom1-sensor-1","11/10/17 08:13","NaN","0"
                        |"bedroom1-sensor-1","11/10/17 08:14","22.0625","NaN"
                        |"bedroom1-sensor-1","11/10/17 08:14","22.2625","0.20"""".stripMargin

    val UkDateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(SHORT).withLocale(UK).withZone(ZoneId.of("GMT"))
    
    val request = Request[IO](GET, Uri.uri("/temperatures.csv"))
    val service = ExportEndpoint(exampleJson.right, UkDateTimeFormatter)
    val response = service.orNotFound.run(request).unsafeRunSync()
    response.as[String].unsafeRunSync must_== expectedCsv
    response.status must_== Ok
  }

} 
Example 119
Source File: ConnectionTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import bad.robot.temperature._
import bad.robot.temperature.rrd.Host
import org.specs2.mutable.Specification

class ConnectionTest extends Specification {

  "Encode Json" >> {
    encode(Connection(Host("box.local", Some("Z"), Some("Europe/London")), IpAddress("127.0.0.1"))).spaces2ps must_==
      """{
        |  "host" : {
        |    "name" : "box.local",
        |    "utcOffset" : "Z",
        |    "timezone" : "Europe/London"
        |  },
        |  "ip" : {
        |    "value" : "127.0.0.1"
        |  }
        |}""".stripMargin
  }

} 
Example 120
Source File: JsonFileTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import java.io.{BufferedWriter, FileWriter}

import org.specs2.matcher.DisjunctionMatchers.be_\/-
import org.specs2.mutable.Specification

class JsonFileTest extends Specification {

  val exampleJson =
    """
      |[
      |  {
      |    "label": "bedroom1-sensor-1",
      |    "data": [
      |      {
      |        "x": 1507709610000,
      |        "y": "NaN"
      |      },
      |      {
      |        "x": 1507709640000,
      |        "y": "+2.2062500000E01"
      |      },
      |      {
      |        "x": 1507709680000,
      |        "y": "+2.2262500000E01"
      |      }
      |    ]
      |  }
      |]
    """.stripMargin

  "Load a file" >> {
    createFile()
    JsonFile.load must be_\/-(exampleJson)
  }
  
  private def createFile() = {
    val writer = new BufferedWriter(new FileWriter(JsonFile.file))
    writer.write(exampleJson)
    writer.close()
  }

} 
Example 121
Source File: DiscoveryServerTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.server

import java.net.{DatagramPacket, DatagramSocket, InetAddress, InetSocketAddress, Socket => _}

import bad.robot.temperature.server.DiscoveryServer.{Quit, ServerAddressRequestMessage, ServerAddressResponseMessage, UnknownRequestResponseMessage}
import bad.robot.temperature.server.Socket._
import org.specs2.matcher.DisjunctionMatchers._
import org.specs2.mutable.Specification

import scala.concurrent.duration._
import scalaz.\/-

class DiscoveryServerTest extends Specification {

  "When the discovery server is started" >> {
    val server = new Thread(new DiscoveryServer())
    server.start()

    "Server will respond with it's address once pinged" >> {
      val socket = new DatagramSocket()
      pingServerOn(ServerAddressRequestMessage, socket)

      val response = socket.await(30 seconds).map(server => (server.getAddress.getHostAddress, server.payload))
      socket.close()
      response must be_\/-
      response match {
        case \/-((ip, message)) if ip == InetAddress.getLocalHost.getHostAddress => message must_== ServerAddressResponseMessage
        case \/-((ip, message)) if ip == "127.0.0.1" || ip == "127.0.1.1"        => message must_== ServerAddressResponseMessage
        case \/-((ip, _))                                                        => throw new Exception(s"$ip wasn't expected")
        case _                                                                   => throw new Exception("specs2 is a dick")
      }
    }

    "Server response when unknown message is received" >> {
      val socket = new DatagramSocket()
      pingServerOn("UNKNOWN_MESSAGE", socket)

      val response = socket.await(30 seconds).map(_.payload)
      socket.close()
      response must be_\/-(UnknownRequestResponseMessage)
    }

    step {
      pingServerOn(Quit, new DatagramSocket())
    }
  }

  private def pingServerOn(message: String, socket: DatagramSocket) {
    val server = new InetSocketAddress(InetAddress.getLocalHost, 8888)
    val data = message.getBytes
    socket.send(new DatagramPacket(data, data.length, server))
  }

} 
Example 122
Source File: ConfigFileTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.config

import java.io.File

import bad.robot.temperature.ConfigurationError
import bad.robot.temperature.config.ConfigFile.loadOrWarn
import knobs._
import org.specs2.mutable.Specification

class ConfigFileTest extends Specification {

  "Can be loaded" >> {
    loadOrWarn(Required(ClassPathResource("example.cfg"))).unsafeRunSync() must beRight
  }
  
  "Retrieve empty list for hosts" >> {
    loadOrWarn(Required(ClassPathResource("example-empty.cfg"))).unsafeRunSync() must beRight.like { case config => {
      config.mode must_== "client"
      config.hosts must throwA[KeyError]
    }}
  }
  
  "Retrieve no mode" >> {
    val config = loadOrWarn(Required(ClassPathResource("bad-example-missing-fields.cfg"))).unsafeRunSync()
    config must beRight.like { case config => {
      config.mode must throwA[KeyError]
      config.hosts must_== List("one", "two")
    }}
  }

  "Retrieve the values configuration items" >> {
    loadOrWarn(Required(ClassPathResource("example.cfg"))).unsafeRunSync() must beRight.like { case config => {
      config.mode must_== "server"
      config.hosts must_== List("one", "two")
    }}
  }
  
  "Example failure messages" >> {
    import scala.concurrent.ExecutionContext.Implicits.global     // todo replace with explicit one

    loadOrWarn(Required(FileResource.unwatched(new File("/foo.cfg")))).unsafeRunSync() must beLeft.like {
      case error: ConfigurationError => error.details must contain("/foo.cfg (No such file or directory)")
    }
    loadOrWarn(Required(FileResource.unwatched(new File(sys.props("user.home"))))).unsafeRunSync() must beLeft.like {
      case error: ConfigurationError => error.details must contain(s"${sys.props("user.home")} (Is a directory)")
    }
    loadOrWarn(Required(ClassPathResource("not/present/temperature-machine.cfg"))).unsafeRunSync() must beLeft.like {
      case error: ConfigurationError => error.details must contain("not/present/temperature-machine.cfg not found on classpath")
    }
    loadOrWarn(Required(ClassPathResource("bad-example.cfg"))).unsafeRunSync() must beLeft.like {
      case error: ConfigurationError => error.details must contain("expected configuration")
    }
    loadOrWarn(Required(ClassPathResource("bad-example-missing-values.cfg"))).unsafeRunSync() must beLeft.like {
      case error: ConfigurationError => error.details must contain("expected comment, newline, value, or whitespace")
    }
  }
  
} 
Example 123
Source File: IpAddressTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature

import org.specs2.mutable.Specification

class IpAddressTest extends Specification {

  "Valid IP addresses" >> {
    IpAddress.isIpAddress("10.0.1.7") must_== true
    IpAddress.isIpAddress("0.0.0.0") must_== true
    IpAddress.isIpAddress("255.255.255.255") must_== true
  }

  "Invalid IP addresses" >> {
    IpAddress.isIpAddress("fe80:0:0:0:40c3:9f41:82e7:760d%utun1") must_== false
    IpAddress.isIpAddress("256.255.255.255") must_== false
    IpAddress.isIpAddress("255.256.255.255") must_== false
    IpAddress.isIpAddress("255.255.256.255") must_== false
    IpAddress.isIpAddress("256.255.255.256") must_== false
    IpAddress.isIpAddress("0.0.0.-1") must_== false
  }

  "Encode Json" >> {
    encode(IpAddress("10.0.1.7")).spaces2ps must_==
      """|{
         |  "value" : "10.0.1.7"
         |}""".stripMargin
  }
} 
Example 124
Source File: SchedulerTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.task

import java.net.{Socket => _}
import java.util.concurrent._
import java.util.concurrent.atomic.AtomicInteger

import bad.robot.temperature.task.Scheduler.ScheduledExecutorServiceOps
import org.specs2.mutable.Specification

import scala.concurrent.duration._

class SchedulerTest extends Specification {

  val errorHandler: Throwable => Runnable => Unit = _ => _ => ()

  "Exceptions aren't propagated when wrapped" >> {
    val handler = Scheduler.wrapWithErrorHandler(() => throw new Exception(), errorHandler)
    handler.run must not(throwA[Exception])
  }

  "Executes at fixed rate" >> {
    val scheduler = new ScheduledExecutorServiceOps(Executors.newSingleThreadScheduledExecutor())
    val counter = new AtomicInteger(0)
    scheduler.schedule(1 milliseconds, errorHandler, () => {
      counter.getAndIncrement()
      throw new Exception()
    })

    counter.get() must be_>(2).eventually
  }

  "Executes at fixed rate without stopping when exceptions are thrown" >> {
    val scheduler = new ScheduledExecutorServiceOps(Executors.newSingleThreadScheduledExecutor())
    val counter = new AtomicInteger(0)
    scheduler.schedule(1 milliseconds, errorHandler, () => {
      counter.getAndIncrement()
      throw new Exception()
    })

    counter.get() must be_>(2).eventually
  }

} 
Example 125
Source File: BarrierTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature

import org.specs2.mutable.Specification

import scala.Double._

class BarrierTest extends Specification {

  "No breach" >> {
    val barrier = Barrier(5)
    barrier.breached(Temperature(10.23), Temperature(11.22)) must_== false
    barrier.breached(Temperature(-10.23), Temperature(-10.23)) must_== false
    barrier.breached(Temperature(0), Temperature(0)) must_== false
    barrier.breached(Temperature(23.12), Temperature(23.12)) must_== false
    barrier.breached(Temperature(23.12), Temperature(24.11)) must_== false
  }
  
  "Positive breach" >> {
    val barrier = Barrier(1)
    barrier.breached(Temperature(10.23), Temperature(11.24)) must_== true
    barrier.breached(Temperature(10.24), Temperature(11.23)) must_== false
  }
  
  "Negative breach" >> {
    val barrier = Barrier(1)
    barrier.breached(Temperature(-10.23), Temperature(-11.24)) must_== true
    barrier.breached(Temperature(-10.24), Temperature(-11.23)) must_== false
  }

  "NaN" >> {
    val barrier = Barrier(1)
    barrier.breached(Temperature(-10.23), Temperature(NaN)) must_== false
    barrier.breached(Temperature(NaN), Temperature(10.23)) must_== false
    barrier.breached(Temperature(NaN), Temperature(NaN)) must_== false
  }
  
} 
Example 126
Source File: ArchiveTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.rrd

import org.specs2.mutable.Specification

import scala.concurrent.duration.Duration

class ArchiveTest extends Specification {

  "Some typical RRA values" >> {
    val frequency = Duration(30, "seconds")

    val daily = Archive.apply(aDay, frequency, frequency)
    val weekHourlyAvg = Archive.apply(aWeek, frequency, anHour)
    val monthTwoHourlyAvg = Archive.apply(aMonth, frequency, anHour * 2)

    daily             must_== Archive(1, 2880)
    weekHourlyAvg     must_== Archive(120, 168)
    monthTwoHourlyAvg must_== Archive(240, 360)
  }

  "Some typical RRA values (1 min frequency)" >> {
    val frequency = Duration(1, "minute")

    val daily = Archive.apply(aDay, frequency, frequency)
    val weekHourlyAvg = Archive.apply(aWeek, frequency, anHour)
    val monthTwoHourlyAvg = Archive.apply(aMonth, frequency, anHour * 2)

    daily             must_== Archive(1, 1440)
    weekHourlyAvg     must_== Archive(60, 168)
    monthTwoHourlyAvg must_== Archive(120, 360)
  }
} 
Example 127
Source File: RpnGeneratorTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.rrd

import bad.robot.temperature.rrd.RpnGenerator.{Max, Min}
import org.specs2.mutable.Specification

class RpnGeneratorTest extends Specification {

  "generate a RPN string to aggregate sensors (Max)" >> {
    RpnGenerator.generateRpn(List("bedroom-1"), Max) must_== "bedroom-1,MAX"
    RpnGenerator.generateRpn(List("bedroom-1", "bedroom-2", "lounge-1"), Max) must_== "bedroom-1,bedroom-2,lounge-1,MAX,MAX"
  }

  "generate a RPN string to aggregate sensors (Min)" >> {
    RpnGenerator.generateRpn(List("bedroom-1"), Min) must_== "bedroom-1,MIN"
    RpnGenerator.generateRpn(List("bedroom-1", "bedroom-2", "lounge-1"), Min) must_== "bedroom-1,bedroom-2,lounge-1,MIN,MIN"
  }

} 
Example 128
Source File: HostTest.scala    From temperature-machine   with Apache License 2.0 5 votes vote down vote up
package bad.robot.temperature.rrd

import java.net.InetAddress

import bad.robot.temperature._
import org.specs2.matcher.DisjunctionMatchers.be_\/-
import org.specs2.mutable.Specification

class HostTest extends Specification {

  "Trims to max 20 characters (including the 'sensor-n' postfix)" >> {
    Host("cheetah.local") must_== Host("cheetah.loc") // aka the host name is equal
    "cheetah.loc-sensor-1".length must_== 20
  }

  "Doesn't trim" >> {
    Host("kitchen", None) must_== Host("kitchen", None, None)
  }

  "Local host" >> {
    Host.local.name must_== InetAddress.getLocalHost.getHostName.take(11)
  }

  "Encode Json" >> {
    encode(Host("local", None, None)).spaces2ps must_==
      """{
        |  "name" : "local",
        |  "utcOffset" : null,
        |  "timezone" : null
        |}""".stripMargin

    encode(Host("local", Some("+03:00"), Some("Tehran"))).spaces2ps must_==
      """{
        |  "name" : "local",
        |  "utcOffset" : "+03:00",
        |  "timezone" : "Tehran"
        |}""".stripMargin
  }

  "Decode Json (what happens if a UTC offset isn't supplied?)" >> {
    val json = """{ "name" : "local" }"""
    decodeAsDisjunction[Host](json) must be_\/-(Host("local", utcOffset = None, timezone = None))
  }
  
} 
Example 129
Source File: AlwaysPassAuthProviderSpec.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification

class AlwaysPassAuthProviderSpec(implicit ee: ExecutionEnv) extends Specification {
  val testTokenInfo = TokenInfo("", Scope.Empty, "token type", "user uid", realm = "/employees")

  "'Always pass' Authorization Provider" should {
    "accept any tokens and scopes and treat them as valid" in {
      val authProvider = new AlwaysPassAuthProvider(testTokenInfo)
      val scope = Scope(Set("any_scope"))
      val token = Some(OAuth2Token("6afe9886-0a0a-4ace-8bc7-fb96920fb764"))

      authProvider.valid(token, scope) must beEqualTo(AuthTokenValid(testTokenInfo)).await
    }
  }

} 
Example 130
Source File: ScopeTestSpec.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import org.specs2.mutable.Specification

class ScopeTestSpec extends Specification {

  "in method" should {

    "return 'true' if this scope is completely in given scope" in {
      Scope(Set("uid")).in(Scope(Set("uid"))) must beTrue
      Scope(Set("uid", "cn")).in(Scope(Set("uid", "cn"))) must beTrue
      Scope(Set("uid")).in(Scope(Set("uid", "cn"))) must beTrue
      Scope(Set("uid", "cn")).in(Scope(Set("cn", "uid"))) must beTrue
    }

    "return 'false' if this scope is partially in given scope" in {
      Scope(Set("uid", "cn")).in(Scope(Set("uid"))) must beFalse
      Scope(Set("uid", "cn")).in(Scope(Set("cn", "foo"))) must beFalse
    }

    "return 'false' if this scope is not in given scope" in {
      Scope(Set("uid")).in(Scope(Set("cn"))) must beFalse
    }
  }

  "empty scope" should {

    "be in any scope" in {
      Scope.Empty.in(Scope.Empty) must beTrue
      Scope.Empty.in(Scope(Set("uid"))) must beTrue
      Scope.Empty.in(Scope(Set("uid", "another_scope"))) must beTrue
      Scope(Set("uid", "")).in(Scope(Set("uid"))) must beTrue
      Scope(Set("uid", "", "")).in(Scope(Set("uid", ""))) must beTrue
    }

  }

} 
Example 131
Source File: SecurityRulesRepositorySpec.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import play.api.Configuration
import play.api.test.FakeRequest

import scala.concurrent.ExecutionContext

class SecurityRulesRepositorySpec extends Specification with Mockito {

  "SecurityRulesRepository" should {

    "load rules from default file" in {
      val provider = mock[AuthProvider]
      val repository = new SecurityRulesRepository(Configuration(), provider)
      val expectedRule = ValidateTokenRule(provider, "GET", "/foo", Scope(Set("uid", "entity.read")))

      repository.get(FakeRequest("GET", "/foo")) must beSome(expectedRule)
    }

    "load rules from custom file" in {
      val provider = mock[AuthProvider]
      val config = Configuration("authorisation.rules.file" -> "security_custom-security.conf")
      val repository = new SecurityRulesRepository(config, provider)
      val expectedRule = ValidateTokenRule(provider, "POST", "/bar.*", Scope(Set("uid")))

      repository.get(FakeRequest("POST", "/bar.*")) must beSome(expectedRule)
    }

    "raise an error when custom file is not available" in {
      val authProvider = mock[AuthProvider]
      val config = Configuration("authorisation.rules.file" -> "this-file-does-not-exist.conf")

      new SecurityRulesRepository(config, authProvider) must
        throwA[RuntimeException]("configuration file this-file-does-not-exist.conf for security rules not found")
    }

    "allow comments in security rules configuration file" in {
      val provider = mock[AuthProvider]
      val config = Configuration("authorisation.rules.file" -> "security_commented.conf")
      val repository = new SecurityRulesRepository(config, provider)
      val expectedRule = ValidateTokenRule(provider, "OPTIONS", "/", Scope(Set("app.resource.read")))

      repository.get(FakeRequest("OPTIONS", "/")) must beSome(expectedRule)
    }

    "raise an error when it cannot parse a configuration file" in {
      val authProvider = mock[AuthProvider]
        def config(fileName: String): Configuration = Configuration("authorisation.rules.file" -> fileName)

      new SecurityRulesRepository(config("security_unknown-http-method.conf"), authProvider) must throwA[RuntimeException]
      new SecurityRulesRepository(config("security_no-scopes.conf"), authProvider) must throwA[RuntimeException]
    }

    "return None if there is no configured rules for given request" in {
      val authProvider = mock[AuthProvider]
      val repository = new SecurityRulesRepository(Configuration(), authProvider)

      repository.get(FakeRequest("GET", "/unknown-uri")) must beNone
    }

    "allow explicitly to pass-through or deny a request for a specific URI" in {
      val authProvider = mock[AuthProvider]
      val configuration = Configuration("authorisation.rules.file" -> "security_pass-through.conf")
      val repository = new SecurityRulesRepository(configuration, authProvider)

      repository.get(FakeRequest("GET", "/foo")).get must beAnInstanceOf[ExplicitlyAllowedRule]
      repository.get(FakeRequest("GET", "/bar")).get must beAnInstanceOf[ExplicitlyDeniedRule]
    }

  }

} 
Example 132
Source File: RequestValidatorSpec.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import org.specs2.mutable.Specification
import play.api.mvc._
import play.api.test.FakeRequest

import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
class RequestValidatorSpec extends Specification {

  val testTokenInfo = TokenInfo("", Scope.Empty, "token type", "user uid", realm = "/employees")

  "Request Validator" should {
    "provide token information when token is valid" in {
      val authProvider = new AuthProvider {
        override def valid(token: Option[OAuth2Token], scope: Scope): Future[AuthResult] =
          Future.successful(AuthTokenValid(testTokenInfo))
      }

      val result = Await.result(RequestValidator.validate(Scope(Set("uid")), FakeRequest(), authProvider), 1.seconds)
      result must beEqualTo(Right(testTokenInfo))
    }

    "return HTTP status 401 (unauthorized) when token was not provided" in {
      val authProvider = new AuthProvider {
        override def valid(token: Option[OAuth2Token], scope: Scope): Future[AuthResult] =
          Future.successful(AuthTokenEmpty)
      }

      val result = Await.result(RequestValidator.validate(Scope(Set("uid")), FakeRequest(), authProvider), 1.seconds)
      result must beEqualTo(Left(Results.Unauthorized))
    }

    "return HTTP status 401 (unauthorized) when token is in valid" in {
      val authProvider = new AuthProvider {
        override def valid(token: Option[OAuth2Token], scope: Scope): Future[AuthResult] =
          Future.successful(AuthTokenInvalid)
      }

      val result = Await.result(RequestValidator.validate(Scope(Set("uid")), FakeRequest(), authProvider), 1.seconds)
      result must beEqualTo(Left(Results.Unauthorized))
    }

    "return HTTP status 401 (unauthorized) when Authorization provider has failed" in {
      val authProvider = new AuthProvider {
        override def valid(token: Option[OAuth2Token], scope: Scope): Future[AuthResult] =
          Future.failed(new RuntimeException)
      }

      val result = Await.result(RequestValidator.validate(Scope(Set("uid")), FakeRequest(), authProvider), 1.seconds)
      result must beEqualTo(Left(Results.Unauthorized))
    }

    "return HTTP status 403 (forbidden) in case insufficient scopes" in {
      val authProvider = new AuthProvider {
        override def valid(token: Option[OAuth2Token], scope: Scope): Future[AuthResult] =
          Future.successful(AuthTokenInsufficient)
      }

      val result = Await.result(RequestValidator.validate(Scope(Set("uid")), FakeRequest(), authProvider), 1.seconds)
      result must beEqualTo(Left(Results.Forbidden))
    }
  }
} 
Example 133
Source File: OAuth2AuthProviderSpec.scala    From play-zhewbacca   with MIT License 5 votes vote down vote up
package org.zalando.zhewbacca

import org.specs2.mutable.Specification
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}

class OAuth2AuthProviderSpec extends Specification {

  "IAM Authorization Provider" should {

    "accept valid token with necessary scope" in {
      val tokenInfo = TokenInfo("311f3ab2-4116-45a0-8bb0-50c3bca0441d", Scope(Set("uid")), "Bearer", userUid = "1234", realm = "/employees")
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(Some(tokenInfo))).valid(
        Some(OAuth2Token("311f3ab2-4116-45a0-8bb0-50c3bca0441d")),
        Scope(Set("uid")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenValid(tokenInfo))
    }

    "accept token which has many scopes" in {
      val tokenInfo = TokenInfo("311f3ab2-4116-45a0-8bb0-50c3bca0441d", Scope(Set("uid", "cn")), "Bearer", userUid = "1234", realm = "/employees")
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(Some(tokenInfo))).valid(
        Some(OAuth2Token("311f3ab2-4116-45a0-8bb0-50c3bca0441d")),
        Scope(Set("uid")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenValid(tokenInfo))
    }

    "reject token when IAM reports it is not valid one" in {
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(None)).valid(
        Some(OAuth2Token("311f3ab2-4116-45a0-8bb0-50c3bca0441d")),
        Scope(Set("uid")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenInvalid)
    }

    "reject token if IAM responses with Token Info for different token" in {
      val tokenInfo = TokenInfo("986c2946-c754-4e58-a0cb-7e86e3e9901b", Scope(Set("uid")), "Bearer", userUid = "1234", realm = "/employees")
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(Some(tokenInfo))).valid(
        Some(OAuth2Token("311f3ab2-4116-45a0-8bb0-50c3bca0441d")),
        Scope(Set("uid")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenInsufficient)
    }

    "reject token with insufficient scopes" in {
      val tokenInfo = TokenInfo("311f3ab2-4116-45a0-8bb0-50c3bca0441d", Scope(Set("uid")), "Bearer", userUid = "1234", realm = "/employees")
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(Some(tokenInfo))).valid(
        Some(OAuth2Token("311f3ab2-4116-45a0-8bb0-50c3bca0441d")),
        Scope(Set("uid", "seo_description.write")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenInsufficient)
    }

    "reject non 'Bearer' token" in {
      val tokenInfo = TokenInfo("311f3ab2-4116-45a0-8bb0-50c3bca0441d", Scope(Set("uid")), "Token", userUid = "1234", realm = "/employees")
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(Some(tokenInfo))).valid(
        Some(OAuth2Token("311f3ab2-4116-45a0-8bb0-50c3bca0441d")),
        Scope(Set("uid")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenInsufficient)
    }

    "reject empty token" in {
      val request = new OAuth2AuthProvider((token: OAuth2Token) => Future.successful(None)).valid(
        None,
        Scope(Set("uid")))

      Await.result(request, 1.second) must beEqualTo(AuthTokenEmpty)
    }
  }
} 
Example 134
Source File: QueriesSpec.scala    From testcontainers-specs2   with MIT License 5 votes vote down vote up
package io.chrisdavenport.testcontainersspecs2

import java.util.UUID

import cats.effect._
import doobie._
import doobie.implicits._
import doobie.postgres.implicits._
import doobie.specs2._
import org.flywaydb.core.Flyway
import org.specs2.mutable.Specification

import scala.concurrent.ExecutionContext

class QueriesSpec[F[_]]
    extends Specification
    with IOChecker
    with ForAllTestContainer
    with UsesPostgreSQLMultipleDatabases {

  implicit val CS: ContextShift[IO] = IO.contextShift(ExecutionContext.global)

  override lazy val transactor: Transactor[IO] = Transactor.fromDriverManager[IO](
    driverName,
    jdbcUrl,
    dbUserName,
    dbPassword
  )

  sequential

  // afterStart / beforeStop available for actions at the begininning
  // and end of a particular container session.
  // In this case we make sure migrations have run before we check the sql statements.
  override def afterStart(): Unit = {
    Flyway
      .configure()
      .dataSource(jdbcUrl, dbUserName, dbPassword)
      .load()
      .migrate
    ()
  }

  private case class Person(person_id: UUID, firstName: String, lastName: String)

  check(sql"SELECT 1".query[Int])
  check(sql"SELECT person_id, first_name, last_name FROM persons".query[Person])

} 
Example 135
Source File: MigrationsSpec.scala    From testcontainers-specs2   with MIT License 5 votes vote down vote up
package io.chrisdavenport.testcontainersspecs2

import cats.effect._
import org.flywaydb.core.Flyway
import org.specs2.mutable.Specification

class MigrationsSpec
    extends Specification
    with ForAllTestContainer
    with UsesPostgreSQLMultipleDatabases {

  "Migrations should run Correctly" in {
    IO {
      Flyway
        .configure()
        .dataSource(jdbcUrl, dbUserName, dbPassword)
        .load()
        .migrate
    }.attempt
      .map(_.isRight)
      .unsafeRunSync() must_=== true
  }

} 
Example 136
Source File: DependenciesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class DependenciesSpec extends Specification with JsonSpec {

  "dependencies draft 4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("dependencies", "draft4")
  }

  "dependencies draft 7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("dependencies", "draft7")
  }
} 
Example 137
Source File: MinPropertiesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MinPropertiesSpec extends Specification with JsonSpec {

  "minProperties draft4" in {
    import Version4._
    implicit val validator = SchemaValidator(Some(Version4))
    validate("minProperties", "draft4")
  }

  "minProperties draft7" in {
    import Version7._
    implicit val validator = SchemaValidator(Some(Version7))
    validate("minProperties", "draft7")
  }
} 
Example 138
Source File: SimplePerformanceSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import java.net.URL

import com.eclipsesource.schema.drafts.Version4
import org.specs2.mutable.Specification
import play.api.libs.json.{JsValue, Json}

class SimplePerformanceSpec extends Specification {

  import Version4._

  def timed(name: String)(body: => Unit) {
    val start = System.currentTimeMillis()
    body
    println(name + ": " + (System.currentTimeMillis() - start) + " ms")
  }

  val validator = SchemaValidator(Some(Version4))
  val schemaUrl: URL = getClass.getResource("/issue-99-1.json")
  val schema: SchemaType = JsonSource.schemaFromUrl(schemaUrl).get

  val instance: JsValue = Json.parse("""{ "mything": "the thing" }""".stripMargin)

  timed("preloaded") {
    for (_ <- 1 to 1000) validator.validate(schema, instance)
  }
  timed("url based") {
    for (_ <- 1 to 1000) validator.validate(schemaUrl)(instance)
  }

} 
Example 139
Source File: RefRemoteDraft7Spec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.Version7
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class RefRemoteDraft7Spec extends Specification with JsonSpec {

  import Version7._

  implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    .addSchema(
      "http://localhost:1234/integer.json",
      JsonSource.schemaFromStream(
        getClass.getResourceAsStream("/remotes/integer.json")
      ).get
    )
    .addSchema(
      "http://localhost:1234/subSchemas.json",
      JsonSource.schemaFromStream(
        getClass.getResourceAsStream("/remotes/subSchemas.json")
      ).get
    )
    .addSchema(
      "http://localhost:1234/folder/folderInteger.json",
      JsonSource.schemaFromStream(
        getClass.getResourceAsStream("/remotes/folder/folderInteger.json")
      ).get
    )
    .addSchema(
      "http://localhost:1234/name.json",
      JsonSource.schemaFromStream(
        getClass.getResourceAsStream("/remotes/name.json")
      ).get
    )

  "refRemote draft7" in {
    validate("refRemote", "draft7")
  }
} 
Example 140
Source File: NotSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class NotSpec extends Specification with JsonSpec {

  "not draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("not", "draft4")
  }

  "not draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("not", "draft7")
  }
} 
Example 141
Source File: MultipleOfSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MultipleOfSpec extends Specification with JsonSpec {

  "multipleOf draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("multipleOf", "draft4")
  }

  "multipleOf draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("multipleOf", "draft7")
  }
} 
Example 142
Source File: UrlHandlerSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.internal.validators.DefaultFormats
import com.eclipsesource.schema.urlhandlers.ClasspathUrlHandler
import org.specs2.mutable.Specification
import play.api.libs.json.Json

class UrlHandlerSpec extends Specification with ErrorHelper { self =>

  "UrlHandlers" should {

    import Version4._

    val clazz = this.getClass

    // no handler at all
    "should fail to resolve absolute references on the classpath if not handler available" in {
      val validator = SchemaValidator(Some(Version4))
      val someJson = clazz.getResourceAsStream("/schemas/my-schema-with-protocol-ful-absolute-path.schema")
      val schema = JsonSource.schemaFromStream(someJson)
      validator.validate(schema.get, Json.obj("foo" -> Json.obj("bar" -> "Munich")))
        .isError must beTrue
    }

    // absolute protocol-ful handler
    "should resolve absolute references on the classpath with ClasspathUrlProtocolHandler" in {
      val validator = SchemaValidator(Some(Version4)).addUrlHandler(new ClasspathUrlHandler(), ClasspathUrlHandler.Scheme)
      val someJson = clazz.getResourceAsStream("/schemas/my-schema-with-protocol-ful-absolute-path.schema")
      val schema = JsonSource.schemaFromStream(someJson)
      val result = validator.validate(schema.get, Json.obj("foo" -> Json.obj("bar" -> "Munich")))
      result.isSuccess must beTrue
    }

    "should resolve absolute references on classpath with ClasspathUrlProtocolHandler (version 7)" in {
      import Version7._
      val validator = SchemaValidator(Some(Version7(new SchemaConfigOptions {
        override def formats: Map[String, SchemaFormat] = DefaultFormats.formats
        override def supportsExternalReferences: Boolean = true
      }))).addUrlHandler(new ClasspathUrlHandler(), ClasspathUrlHandler.Scheme)
      val schema = JsonSource.schemaFromString(
        """{
          |  "type": "object",
          |  "properties": {
          |     "schema": {
          |        "$ref": "classpath:///refs/json-schema-draft-07.json"
          |     }
          |  }
          |}
        """.stripMargin)
      val result = validator.validate(schema.get, Json.obj("schema" -> Json.obj()))
      result.isSuccess must beTrue
    }

    "should resolve relative references on classpath (valid instance)" in {
      val validator = SchemaValidator(Some(Version4))
      val url = clazz.getResource("/schemas/my-schema-with-protocol-less-relative-path.schema")
      validator.validate(url)(Json.obj("foo" -> Json.obj("bar" -> "Munich")))
        .isSuccess must beTrue
    }

    "should resolve relative references on the classpath (invalid instance)" in {
      val validator = SchemaValidator(Some(Version4))
      val url = clazz.getResource("/schemas/my-schema-with-protocol-less-relative-path.schema")
      val res = validator.validate(url)(Json.obj("foo" -> Json.obj("bar" -> 3)))
      firstErrorOf(res) must beEqualTo("Wrong type. Expected string, was number.")
    }
  }
} 
Example 143
Source File: EnumSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class EnumSpec extends Specification with JsonSpec {

  "enum draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("enum", "draft4")
  }

  "enum draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("enum", "draft7")
  }
} 
Example 144
Source File: UniqueItemsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class UniqueItemsSpec extends Specification with JsonSpec {

  "uniqueItems draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("uniqueItems", "draft4")
  }

  "uniqueItems draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("uniqueItems", "draft7")
  }
} 
Example 145
Source File: DefaultSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class DefaultSpec extends Specification with JsonSpec {

  "validate draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("default", "draft4")
  }

  "validate draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("default", "draft7")
  }
} 
Example 146
Source File: TypeSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class TypeSpec extends Specification with JsonSpec {

  "type draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("type", "draft4")
  }
  "type draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("type", "draft7")
  }
} 
Example 147
Source File: RemoteSpecs.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.Version4
import com.eclipsesource.schema.test.{Assets, JsonSpec}
import org.specs2.mutable.Specification
import org.specs2.specification.AfterAll
import org.specs2.specification.core.Fragments
import org.specs2.specification.dsl.Online
import play.api.Application
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.mvc.DefaultActionBuilder
import play.api.test.TestServer

class RemoteSpecs extends Specification with JsonSpec with Online with AfterAll {

  import Version4._

  implicit val validator: SchemaValidator = {
    SchemaValidator(Some(Version4)).addSchema(
      "http://localhost:1234/scope_foo.json",
      JsonSource.schemaFromString(
        """{
          |  "definitions": {
          |    "bar": { "type": "string" }
          |  }
          |}""".stripMargin
      ).get
    )
  }

  def createApp: Application = new GuiceApplicationBuilder()
    .appRoutes(app => {
      val Action = app.injector.instanceOf[DefaultActionBuilder]
      Assets.routes(Action)(getClass, "remotes/")
    })
    .build()

  lazy val server = TestServer(port = 1234, createApp)

  def afterAll: Unit = {
    server.stop
    Thread.sleep(1000)
  }

  def validateAjv(testName: String): Fragments = validate(testName, "ajv_tests")

  sequential

  "Validation from remote resources is possible" >> {
    {
      server.start
      Thread.sleep(1000)
    } must not(throwAn[Exception]) continueWith {
      validateMultiple(
        "ajv_tests" -> Seq(
          "5_adding_dependency_after",
          "5_recursive_references",
          "12_restoring_root_after_resolve",
          "13_root_ref_in_ref_in_remote_ref",
          "14_ref_in_remote_ref_with_id",
          "62_resolution_scope_change"
        ),
        "draft4" -> Seq("refRemote")
      )
    }
  }

  validateAjv("1_ids_in_refs")
} 
Example 148
Source File: RequiredSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class RequiredSpec extends Specification with JsonSpec {

  "required draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("required", "draft4")
  }

  "required draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("required", "draft7")
  }
} 
Example 149
Source File: MaxItemsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MaxItemsSpec extends Specification with JsonSpec {

  "maxItems draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("maxItems", "draft4")
  }

  "maxItems draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("maxItems", "draft7")
  }
} 
Example 150
Source File: AdditionalItemsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification
import play.api.libs.json.{JsArray, JsNumber}

class AdditionalItemsSpec extends Specification with JsonSpec {

  "validate draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("additionalItems", "draft4")
  }

  "validate draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("additionalItems", "draft7")
  }

  "AdditionalItems" should {
    import Version7._
    val schema = JsonSource.schemaFromString(
      """{
        |  "items": [{}, {}, {}],
        |  "additionalItems": false
        |}""".stripMargin).get

    "no additional items present" in {
      val data = JsArray(Seq(JsNumber(1), JsNumber(2), JsNumber(3)))
      SchemaValidator(Some(Version4)).validate(schema, data).isSuccess must beTrue
    }
  }
} 
Example 151
Source File: PatternPropertiesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class PatternPropertiesSpec extends Specification with JsonSpec {

  "patternProperties draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("patternProperties", "draft4")
  }

  "patternProperties draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("patternProperties", "draft7")
  }
} 
Example 152
Source File: MaximumSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MaximumSpec extends Specification  with JsonSpec {

  "maximum draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("maximum", "draft4")
  }

  "maximum draft7" in {
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    import Version7._
    validate("maximum", "draft7")
  }
} 
Example 153
Source File: AnyOfSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class AnyOfSpec extends Specification with JsonSpec {

  "anyOf draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("anyOf", "draft4")
    validate("anyOf", "ajv_tests")
  }

  "anyOf draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("anyOf", "draft7")
  }
} 
Example 154
Source File: PatternSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class PatternSpec extends Specification with JsonSpec {

  "pattern draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("pattern", "draft4")
  }

  "pattern draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("pattern", "draft7")
  }
} 
Example 155
Source File: SchemaReadsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema.internal.serialization

import com.eclipsesource.schema._
import com.eclipsesource.schema.{JsonSource, SchemaType, SchemaValue}
import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.internal.draft7.constraints.{AnyConstraints7, NumberConstraints7, StringConstraints7}
import org.specs2.mutable.Specification
import play.api.libs.json.{JsArray, JsBoolean, JsString, Json}

class SchemaReadsSpec extends Specification {


  "Schema Reads for draft 4" should {

    import Version4._

    "not fail with match error (#104)" in {
      val schema = JsonSource.schemaFromString("""
        |{
        |  "someProp": {"type": "sting"}
        |}""".stripMargin)

      schema.isSuccess must beTrue
    }

    "not be able to read boolean schema" in {
      Json.fromJson[SchemaType](JsBoolean(true)).isError must beTrue
    }

    "fail if exclusiveMinimum is not a boolean" in {
      val result = JsonSource.schemaFromString(
        """{ "exclusiveMinimum": 3 }""".stripMargin
      )
      result.asEither must beLeft.like { case error => (error.toJson(0) \ "msgs").get.as[JsArray].value.head ==
        JsString("error.expected.jsboolean")
      }
    }
  }

  "Schema Reads for draft 7" should {

    import Version7._

    "read boolean schema" in {
      val booleanSchema = Json.fromJson[SchemaType](JsBoolean(true)).get
      booleanSchema must beEqualTo(SchemaValue(JsBoolean(true)))
    }

    "read compound type with error" in {
      val schema = JsonSource.schemaFromString("""
                                                 |{
                                                 |  "type": ["number", "string"]
                                                 |}""".stripMargin)

      schema.isSuccess must beTrue
      schema.asOpt must beSome.which(
        _ == CompoundSchemaType(
          Seq(
            SchemaNumber(NumberConstraints7().copy(any = AnyConstraints7().copy(schemaType = Some("number")))),
            SchemaString(StringConstraints7().copy(any = AnyConstraints7().copy(schemaType = Some("string"))))
          )
        )
      )
    }
  }
} 
Example 156
Source File: RefsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema.internal.refs

import org.specs2.mutable.Specification


class RefsSpec extends Specification {
  "Refs" should {
    "should define resolution scopes" in {

      Refs.mergeRefs(
        Ref("#foo"),
        Some(Ref("#bar"))
      ) must beEqualTo(Ref("#foo"))

      Refs.mergeRefs(
        Ref("#"), Some(Ref("http://x.y.z/rootschema.json#"))
      ) must beEqualTo(Ref("http://x.y.z/rootschema.json#"))

      Refs.mergeRefs(
        Ref("#foo"), Some(Ref("http://x.y.z/rootschema.json#"))
      ) must beEqualTo(Ref("http://x.y.z/rootschema.json#foo"))

      Refs.mergeRefs(
        Ref("otherschema.json"), Some(Ref("http://x.y.z/rootschema.json#"))
      ) must beEqualTo(Ref("http://x.y.z/otherschema.json#"))

      Refs.mergeRefs(
        Ref("#bar"), Some(Ref("http://x.y.z/otherschema.json"))
      ) must beEqualTo(Ref("http://x.y.z/otherschema.json#bar"))

      Refs.mergeRefs(
        Ref("t/inner.json#a"), Some(Ref("http://x.y.z/rootschema.json#"))
      ) must beEqualTo(Ref("http://x.y.z/t/inner.json#a"))

      Refs.mergeRefs(
        Ref("some://where.else/completely#"), Some(Ref("http://x.y.z/rootschema.json#"))
      ) must beEqualTo(Ref("some://where.else/completely#"))
    }
  }
} 
Example 157
Source File: ResolveNumberConstraintsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema.internal.refs

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.{JsonSource, SchemaType, SchemaValue}
import org.specs2.mutable.Specification
import play.api.libs.json.JsNumber

class ResolveNumberConstraintsSpec extends Specification {

  "draft v4" should {

    import Version4._
    val resolver = SchemaRefResolver(Version4)

    "resolve number constraints" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "type": "integer",
          |  "minimum": 0,
          |  "maximum": 10,
          |  "multipleOf": 2
          |}""".stripMargin).get

      val scope = SchemaResolutionScope(schema)
      resolver.resolveFromRoot("#/minimum", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(0)))
      resolver.resolveFromRoot("#/maximum", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(10)))
      resolver.resolveFromRoot("#/multipleOf", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(2)))
    }
  }

  "draft v7" should {

    import Version7._
    val resolver = SchemaRefResolver(Version7)

    "resolve number constraints" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "type": "integer",
          |  "minimum": 0,
          |  "maximum": 10,
          |  "multipleOf": 2
          |}""".stripMargin).get

      val scope = SchemaResolutionScope(schema)
      resolver.resolveFromRoot("#/minimum", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(0)))
      resolver.resolveFromRoot("#/maximum", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(10)))
      resolver.resolveFromRoot("#/multipleOf", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(2)))
    }
  }
} 
Example 158
Source File: ResolveObjectConstraintsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema.internal.refs

import com.eclipsesource.schema.{JsonSource, SchemaString, SchemaType}
import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.internal.draft7.constraints.StringConstraints7
import org.specs2.mutable.Specification
import play.api.libs.json.{JsBoolean, JsObject, JsString, JsValue}

class ResolveObjectConstraintsSpec extends Specification {

  "draft v4" should {

    import Version4._
    val resolver = SchemaRefResolver(Version4)

    "resolve dependencies constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |"dependencies": {
          |    "a": "b",
          |    "c": ["d", "e"]
          |  }
          |}""".stripMargin).get

      val resolved = resolver.resolveFromRoot("#/dependencies/c/1", SchemaResolutionScope(schema))
      resolved.right.map(_.toJson) must beRight[JsValue](JsString("e"))
    }

    "resolve patternProperties constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "patternProperties": {
          |        "^(/[^/]+)+$": {}
          |  }
          |}""".stripMargin).get
      val result = resolver.resolveFromRoot("#/patternProperties", SchemaResolutionScope(schema))
      result.map(_.toJson).right.get must beAnInstanceOf[JsObject]
    }

    "should resolve additionalProperties constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "additionalProperties": false
          |}""".stripMargin).get

      val result = resolver.resolveFromRoot("#/additionalProperties", SchemaResolutionScope(schema))
      result.map(_.toJson) must beRight[JsValue](JsBoolean(false))
    }
  }

  "draft v7" should {

    import Version7._
    val resolver = SchemaRefResolver(Version7)

    "resolve dependencies constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |"dependencies": {
          |    "a": "b",
          |    "c": ["d", "e"]
          |  }
          |}""".stripMargin).get

      val resolved = resolver.resolveFromRoot("#/dependencies/c/1", SchemaResolutionScope(schema))
      resolved.right.map(_.toJson) must beRight[JsValue](JsString("e"))
    }

    "resolve patternProperties constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "patternProperties": {
          |        "^(/[^/]+)+$": {}
          |  }
          |}""".stripMargin).get
      val result = resolver.resolveFromRoot("#/patternProperties", SchemaResolutionScope(schema))
      result.map(_.toJson).right.get must beAnInstanceOf[JsObject]
    }

    "should resolve additionalProperties constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "additionalProperties": false
          |}""".stripMargin).get

      val result = resolver.resolveFromRoot("#/additionalProperties", SchemaResolutionScope(schema))
      result.map(_.toJson) must beRight[JsValue](JsBoolean(false))
    }

    "should resolve additionalProperties constraint" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "propertyNames": {"maxLength": 3}
          |}""".stripMargin).get

      val result = resolver.resolveFromRoot("#/propertyNames", SchemaResolutionScope(schema))
      result.map(_.resolved) must beRight[SchemaType](SchemaString(StringConstraints7().copy(maxLength = Some(3))))
    }
  }
} 
Example 159
Source File: ResolveArrayConstraintsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema.internal.refs

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.internal.constraints.Constraints.Minimum
import com.eclipsesource.schema.internal.draft7.constraints.NumberConstraints7
import com.eclipsesource.schema.{JsonSource, SchemaNumber, SchemaType, SchemaValue}
import org.specs2.mutable.Specification
import play.api.libs.json.{JsBoolean, JsNumber}

class ResolveArrayConstraintsSpec extends Specification {

  "draft v4" should {

    import Version4._
    val resolver = SchemaRefResolver(Version4)

    "resolve array constraints" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "items": {
          |    "type": "integer"
          |  },
          |  "minItems": 42,
          |  "maxItems": 99,
          |  "additionalItems": false,
          |  "uniqueItems": false
          |}""".stripMargin).get

      val scope = SchemaResolutionScope(schema)
      resolver.resolveFromRoot("#/minItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(42)))
      resolver.resolveFromRoot("#/maxItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(99)))
      resolver.resolveFromRoot("#/additionalItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsBoolean(false)))
      resolver.resolveFromRoot("#/uniqueItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsBoolean(false)))
    }
  }

  "draft v7" should {

    import Version7._
    val resolver = SchemaRefResolver(Version7)

    "resolve array constraints" in {
      val schema = JsonSource.schemaFromString(
        """{
          |  "items": {
          |    "type": "integer"
          |  },
          |  "minItems": 42,
          |  "maxItems": 99,
          |  "additionalItems": false,
          |  "uniqueItems": false,
          |  "contains": {
          |    "minimum": 55
          |  }
          |}""".stripMargin).get

      val scope = SchemaResolutionScope(schema)
      resolver.resolveFromRoot("#/minItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(42)))
      resolver.resolveFromRoot("#/maxItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(99)))
      resolver.resolveFromRoot("#/additionalItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsBoolean(false)))
      resolver.resolveFromRoot("#/uniqueItems", scope).map(_.resolved) must beRight[SchemaType](SchemaValue(JsBoolean(false)))
      resolver.resolveFromRoot("#/contains", scope).map(_.resolved) must beRight[SchemaType](
        SchemaNumber(NumberConstraints7(Some(Minimum(BigDecimal(55), Some(false)))))
      )
    }
  }
} 
Example 160
Source File: ResolveStringConstraintsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema.internal.refs

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.{JsonSource, SchemaType, SchemaValue}
import org.specs2.mutable.Specification
import play.api.libs.json.{JsNumber, JsString}

class ResolveStringConstraintsSpec extends Specification {

  "draft v4" should {

    import Version4._
    val resolver = SchemaRefResolver(Version4)

    "resolve string constraints" in {
      val schema =
        JsonSource.schemaFromString(
          """{
            |  "type": "string",
            |  "minLength": 1,
            |  "maxLength": 10,
            |  "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
            |}""".stripMargin).get

      val scope = SchemaResolutionScope(schema)
      resolver.resolveFromRoot("#/minLength", scope)
        .map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(1)))
      resolver.resolveFromRoot("#/maxLength", scope)
        .map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(10)))
      resolver.resolveFromRoot("#/pattern", scope)
        .map(_.resolved) must beRight[SchemaType](SchemaValue(JsString("^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$")))
    }
  }

  "draft v7" should {

    import Version7._
    val resolver = SchemaRefResolver(Version7)

    "resolve string constraints" in {
      val schema =
        JsonSource.schemaFromString(
          """{
            |  "type": "string",
            |  "minLength": 1,
            |  "maxLength": 10,
            |  "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"
            |}""".stripMargin).get

      val scope = SchemaResolutionScope(schema)
      resolver.resolveFromRoot("#/minLength", scope)
        .map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(1)))
      resolver.resolveFromRoot("#/maxLength", scope)
        .map(_.resolved) must beRight[SchemaType](SchemaValue(JsNumber(10)))
      resolver.resolveFromRoot("#/pattern", scope)
        .map(_.resolved) must beRight[SchemaType](SchemaValue(JsString("^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$")))
    }
  }
} 
Example 161
Source File: DefinitionsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class DefinitionsSpec extends Specification with JsonSpec { self =>

  "validate draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("definitions", "draft4")
  }

  "validate draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("definitions", "draft7")
  }

} 
Example 162
Source File: MinimumSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MinimumSpec extends Specification with JsonSpec {

  "minimum draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("minimum", "draft4")
  }

  "minimum draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("minimum", "draft7")
  }
} 
Example 163
Source File: TinCanSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import org.specs2.mutable.Specification
import play.api.libs.json.{JsValue, Json}

import scala.util.Try

class TinCanSpec extends Specification { self =>

  import com.eclipsesource.schema.drafts.Version4

  val instance = JsonSource.fromString(
    """
      |{
      |  "actor": {
      |    "name": "Sally Glider",
      |    "mbox": "mailto:[email protected]"
      |  },
      |  "verb": {
      |    "id": "http://adlnet.gov/expapi/verbs/experienced",
      |    "display": { "en-US": "experienced" }
      |  },
      |  "object": {
      |    "id": "http://example.com/activities/solo-hang-gliding",
      |    "definition": {
      |      "name": { "en-US": "Solo Hang Gliding" }
      |    }
      |  }
      |}
    """.stripMargin).get


  "Tin Can Spec" should {

    import Version4._

    def readSchema(filename: String) =
      JsonSource.schemaFromStream(self.getClass.getResourceAsStream(s"/tincan/$filename.json")).get

    "validate basic statement object" in {

      val validator = SchemaValidator(Some(Version4))
        .addSchema("#agent", readSchema("agent"))
        .addSchema("#group", readSchema("group"))
        .addSchema("#inversefunctional", readSchema("inversefunctional"))
        .addSchema("#mbox", readSchema("mbox"))
        .addSchema("#statement_base", readSchema("statement_base"))
        .addSchema("#statement_object", readSchema("statement_object"))
        .addSchema("#verb", readSchema("verb"))
        .addSchema("#languagemap", readSchema("languagemap"))
        .addSchema("#activity", readSchema("activity"))
        .addSchema("#activity_definition", readSchema("activity_definition"))
        .addSchema("#activityid", readSchema("activityid"))

      val result = validator.validate(readSchema("statement_base"), instance)
      result.isSuccess must beTrue
    }
  }
} 
Example 164
Source File: ItemsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.internal.refs.{SchemaRefResolver, SchemaResolutionScope}
import com.eclipsesource.schema.internal.validators.ArrayValidator
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification
import play.api.libs.json.{JsNumber, Json}

class ItemsSpec extends Specification with JsonSpec {

  "validate draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("items", "draft4")
  }

  "validate draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("items", "draft7")
  }

  "validate array with some invalid items" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    val schema = JsonSource.schemaFromString(
      """{
        |  "type": "array",
        |  "items": {
        |    "minimum": 3
        |  }
        |}""".stripMargin).get

    val instance = Json.arr(2, 3, 4, 1)

    val result = validator.validate(schema, instance)
    result.isError must beTrue
    result.asEither must beLeft.like { case error =>
      error.toJson.value must haveLength(2)
    }
  }

  "validate array with wrong json type" in {
    import Version4._
    val schema = JsonSource.schemaFromString(
      """{
        |  "type": "array",
        |  "items": {
        |    "minimum": 3
        |  }
        |}""".stripMargin).get.asInstanceOf[SchemaArray]
    val context = SchemaResolutionContext(SchemaRefResolver(Version4), SchemaResolutionScope(schema))
    val result = ArrayValidator.validate(schema, JsNumber(2), context)
    result.isFailure must beTrue
  }
} 
Example 165
Source File: BigNumSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.Version4
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification
import play.api.libs.json.JsNumber

class BigNumSpec extends Specification with JsonSpec {

  import Version4._
  implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
  validate("optional/bignum", "draft4")

  "Bignum" should {

    "be an integer" in {
      val schema = JsonSource.schemaFromString(""" {"type": "integer"} """).get
      val instance = JsNumber(BigDecimal("12345678910111213141516171819202122232425262728293031"))
      val result = SchemaValidator(Some(Version4)).validate(schema)(instance)
      result.asOpt must beSome.which(_ == JsNumber(BigDecimal("12345678910111213141516171819202122232425262728293031")))
    }

  }
} 
Example 166
Source File: AdditionalPropertiesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class AdditionalPropertiesSpec extends Specification with JsonSpec {

  "additionalProperties draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("additionalProperties", "draft4")
  }

  "additionalProperties draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("additionalProperties", "draft7")
  }
} 
Example 167
Source File: MinItemsSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MinItemsSpec extends Specification with JsonSpec {

  "minItems draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("minItems", "draft4")
  }

  "minItems draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("minItems", "draft7")
  }
} 
Example 168
Source File: SchemaSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.Version4
import org.specs2.mutable.Specification

class SchemaSpec extends Specification { self =>

  "Schema draft v7" should {
    "validate itself" in {
      import com.eclipsesource.schema.drafts.Version7._
      val schema = JsonSource.fromUrl(self.getClass.getResource("/refs/json-schema-draft-07.json")).get
      val jsonSchema = JsonSource.schemaFromStream(self.getClass.getResourceAsStream("/refs/json-schema-draft-07.json")).get
      implicit val validator: SchemaValidator = SchemaValidator()
      validator.validate(jsonSchema, schema).isSuccess must beTrue
    }
  }

  "Schema draft v4" should {
    "validate itself" in {
      import Version4._
      val schema = JsonSource.fromUrl(self.getClass.getResource("/refs/json-schema-draft-04.json")).get
      val jsonSchema = JsonSource.schemaFromStream(self.getClass.getResourceAsStream("/refs/json-schema-draft-04.json")).get
      implicit val validator: SchemaValidator = SchemaValidator()
      validator.validate(jsonSchema, schema).isSuccess must beTrue
    }
  }
} 
Example 169
Source File: Issue99Spec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.Version4
import org.specs2.mutable.Specification
import play.api.libs.json.Json

class Issue99Spec extends Specification { self =>

  "Issue 99 Spec" should {

    import Version4._

    "validate issue 99 test case" in {
      val schema = JsonSource.schemaFromString(
        """
          |{
          |  "type": "object",
          |  "properties": {
          |    "mything": { "$ref": "#thing" }
          |  },
          |  "definitions": {
          |    "thing": {
          |      "id": "#thing",
          |      "type": "string"
          |    }
          |  }
          |}
        """.stripMargin).get
      val validator = SchemaValidator(Some(Version4))
      validator.validate(schema, Json.obj(
        "mything" -> "test"
      )).isSuccess must beTrue
    }

    "validate issue 99-1 test case via URL" in {
      val schemaUrl = self.getClass.getResource("/issue-99-1.json")
      val validator = SchemaValidator(Some(Version4))
      val result = validator.validate(schemaUrl)(Json.obj(
        "mything" -> "test"
      ))
      result.isSuccess must beTrue
    }

    "not cause stack overflow for issue 99-5 test case via URL" in {
      val schemaUrl = self.getClass.getResource("/issue-99-5.json")
      val validator = SchemaValidator(Some(Version4))
      // must terminate
      validator.validate(schemaUrl)(Json.obj(
        "mything" -> "test"
      )).isError must beTrue
    }
  }

} 
Example 170
Source File: OneOfSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class OneOfSpec extends Specification with JsonSpec {

  import Version4._

  "oneOf draft4" in {
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("oneOf", "draft4")
    validate("oneOf", "ajv_tests")
  }

  "oneOf draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("oneOf", "draft7")
  }

  "oneOf must be array of objects (invalid)" in {
    val schema = JsonSource.schemaFromString(
      """{
        | "oneOf": [
        |  "#/definitions/foo"
        | ]
        |}""".stripMargin)
    schema.isError must beTrue
  }

  "oneOf must be array of objects (valid)" in {
    val schema = JsonSource.schemaFromString(
      """{
        | "oneOf": [{
        |  "$ref": "#/definitions/foo"
        | }]
        |}""".stripMargin)
    schema.isSuccess must beTrue
  }
} 
Example 171
Source File: PropertiesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class PropertiesSpec extends Specification with JsonSpec {

  "properties draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("properties", "draft4")
  }

  "properties draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("properties", "draft7")
  }
} 
Example 172
Source File: ExamplesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.Version4
import org.specs2.mutable.Specification

class ExamplesSpec extends Specification {

  val validator = SchemaValidator(Some(Version4))
  val swaggerSchemaUrl = "/test-schemas/swagger-2.0"

  private def validateExample(schema: String, url: String) = {
    val schemaUrl = getClass.getResource(url)
    val instanceUrl = getClass.getResource(url)
    val instance = JsonSource.fromUrl(instanceUrl)
    val result   = validator.validate(schemaUrl)(instance.get)
    result.isSuccess must beTrue
    result.get must beEqualTo(instance.get)
  }

  "Validator" should {
    "validate petstore-minimal" in {
      validateExample(swaggerSchemaUrl, "/test-schemas/petstore-minimal.json")
    }

    "validate petstore-simple" in {
      validateExample(swaggerSchemaUrl, "/test-schemas/petstore-simple.json")
    }

    "validate petstore-expanded" in {
      validateExample(swaggerSchemaUrl, "/test-schemas/petstore-expanded.json")
    }

    "validate petstore-with-external-docs" in {
      validateExample(swaggerSchemaUrl, "/test-schemas/petstore-with-external-docs.json")
    }

    "validate petstore" in {
      validateExample(swaggerSchemaUrl, "/test-schemas/petstore.json")
    }

    "validate core schema agsinst itself" in {
      validateExample("/test-schemas/schema", "/test-schemas/schema")
    }
  }

} 
Example 173
Source File: MinLengthSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification
import play.api.libs.json.JsString

class MinLengthSpec extends Specification with JsonSpec {

  "validate draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("minLength", "draft4")
  }

  "validate draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("minLength", "draft7")
  }

  "MinLength" should {

    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))

    "validate against numeric strings that are long enough" in {
      val schema = JsonSource.schemaFromString(
        """{
          |"minLength": 3
        }""".stripMargin).get

      validator.validate(schema)(JsString("123")).isSuccess must beTrue
    }

    "not validate against numeric strings that are too short" in {
      val schema = JsonSource.schemaFromString(
        """{
          |"minLength": 3
        }""".stripMargin).get

      validator.validate(schema)(JsString("12")).isError must beTrue
    }

  }
} 
Example 174
Source File: MaxPropertiesSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification

class MaxPropertiesSpec extends Specification with JsonSpec {

  "maxProperties draft4" in {
    import Version4._
    implicit val validator = SchemaValidator(Some(Version4))
    validate("maxProperties", "draft4")
  }

  "maxProperties draft7" in {
    import Version7._
    implicit val validator = SchemaValidator(Some(Version7))
    validate("maxProperties", "draft7")
  }
} 
Example 175
Source File: MaxLengthSpec.scala    From play-json-schema-validator   with Apache License 2.0 5 votes vote down vote up
package com.eclipsesource.schema

import com.eclipsesource.schema.drafts.{Version4, Version7}
import com.eclipsesource.schema.test.JsonSpec
import org.specs2.mutable.Specification
import play.api.libs.json._

class MaxLengthSpec extends Specification with JsonSpec {

  "maxLength draft4" in {
    import Version4._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version4))
    validate("maxLength", "draft4")
  }

  "maxLength draft7" in {
    import Version7._
    implicit val validator: SchemaValidator = SchemaValidator(Some(Version7))
    validate("maxLength", "draft7")
  }

  "MaxLength" should {
    import Version4._
    "fail with an error in case the string is too long" in {
      val schema = JsonSource.schemaFromString(
        """{
          |"maxLength": 2
        }""".stripMargin).get
      val json = JsString("foo")
      val result = SchemaValidator(Some(Version4)).validate(schema)(json)
      result.isError must beTrue
      result.asEither must beLeft.like {
        case error => (error.toJson(0) \ "msgs") == JsDefined(JsArray(Seq(JsString("'foo' exceeds maximum length of 2."))))
      }
    }
  }
} 
Example 176
Source File: HostFileConfigSpec.scala    From scala-ssh   with Apache License 2.0 5 votes vote down vote up
package com.decodified.scalassh

import org.specs2.mutable.Specification

class HostFileConfigSpec extends Specification {

  "Depending on the host file the HostFileConfig should produce a proper" >> {
    "PasswordLogin" ! {
      config("password.com") === Right(HostConfig(PasswordLogin("bob", "123"), "password.com", enableCompression = true))
    }
    "unencrypted PublicKeyLogin" ! {
      config("keyfile.com") === Right(HostConfig(PublicKeyLogin("alice", "/some/file"), "xyz.special.com", port = 30))
    }
    "encrypted PublicKeyLogin" ! {
      config("enc-keyfile.com") === Right(HostConfig(PublicKeyLogin("alice", "superSecure", "/some/file" :: Nil), "enc-keyfile.com"))
    }
    "AgentLogin" ! {
      config("agent.com") === Right(HostConfig(AgentLogin("bob"), "agent.com", enableCompression = true))
    }
    "error message if the file is missing" ! {
      config("non-existing.net").left.get === "Host resources 'non-existing.net', 'net' not found, either " +
        "provide one or use a concrete HostConfig, PasswordLogin, PublicKeyLogin or AgentLogin"
    }
    "error message if the login-type is invalid" ! {
      config("invalid-login-type.com").left.get must startingWith("Illegal login-type setting 'fancy pants'")
    }
    "error message if the username is missing" ! {
      config("missing-user.com").left.get must endWith("is missing required setting 'username'")
    }
    "error message if the host file contains an illegal line" ! {
      config("illegal-line.com").left.get must endWith("contains illegal line:\nthis line triggers an error!")
    }
  }

  "The sequence of searched config locations for host `node42.tier1.example.com`" should
    "be as described in the README" ! {
      HostFileConfig.searchLocations("node42.tier1.example.com").toList ===
        "node42.tier1.example.com" ::
        "node4X.tier1.example.com" ::
        "nodeXX.tier1.example.com" ::
        "tier1.example.com" ::
        "tierX.example.com" ::
        "example.com" ::
        "com" :: Nil
    }

  val config = HostResourceConfig()
} 
Example 177
Source File: IsoLListFormatSpec.scala    From sjson-new   with Apache License 2.0 5 votes vote down vote up
package sjsonnew
package support.spray

import spray.json.{ JsArray, JsNumber, JsString, JsObject }
import org.specs2.mutable.Specification

class IsoLListFormatSpec extends Specification with BasicJsonProtocol {
  sealed trait Contact
  case class Person(name: String, value: Option[Int]) extends Contact
  case class Organization(name: String, value: Option[Int]) extends Contact

  implicit val personIso: IsoLList.Aux[Person, String :*: Option[Int] :*: LNil] = LList.isoCurried(
    { p: Person => ("name", p.name) :*: ("value", p.value) :*: LNil })
    { in => Person(
      in.find[String]("name").get,
      in.find[Option[Int]]("value").flatten) }

  implicit val organizationIso: IsoLList.Aux[Organization, String :*: Option[Int] :*: LNil] = LList.isoCurried(
    { o: Organization => ("name", o.name) :*: ("value", o.value) :*: LNil })
    { in => Organization(
      in.find[String]("name").get,
      in.find[Option[Int]]("value").flatten) }

  implicit val ContactFormat: JsonFormat[Contact] = flatUnionFormat2[Contact, Person, Organization]("$type")

  val p1 = Person("Alice", Some(1))
  val personJs = JsObject("$fields" -> JsArray(JsString("name"), JsString("value")),
    "name" -> JsString("Alice"), "value" -> JsNumber(1))
  val c1: Contact = Organization("Company", None)
  val contactJs =
    JsObject(
      "$type" -> JsString("Organization"),
      "$fields" -> JsArray(JsString("name"), JsString("value")),
      "name" -> JsString("Company")
    )
  "The isomorphism from a custom type to LList" should {
    "convert from value to JObject" in {
      Converter.toJsonUnsafe(p1) mustEqual personJs
    }
    "convert from JObject to the same value" in {
      Converter.fromJsonUnsafe[Person](personJs) mustEqual p1
    }
    "convert from a union value to JObject" in {
      Converter.toJsonUnsafe(c1) mustEqual contactJs
    }
  }
} 
Example 178
Source File: TransactionLedgerEntriesSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import stellar.sdk.model.ledger.{LedgerEntryChange, TransactionLedgerEntries}
import stellar.sdk.model.{Desc, Now}

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.Try

class TransactionLedgerEntriesSpec(ee: ExecutionEnv) extends Specification {

  import ee.ec

  val last100 = Await.result(PublicNetwork.transactions(cursor = Now, order = Desc), 1.minute).take(100).toList

  "transaction meta parsing" should {
    "parse the last 100 without any issues" >> {
      Try {
        last100.map(_.ledgerEntries)
      } must beSuccessfulTry[Seq[TransactionLedgerEntries]]
    }
  }

  "fee ledger entry parsing" should {
    "parse the last 100 without any issues" >> {
      Try {
        last100.flatMap(_.feeLedgerEntries)
      } must beSuccessfulTry[Seq[LedgerEntryChange]]
    }
  }
} 
Example 179
Source File: FriendBotSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import stellar.sdk.model.op.AccountMergeOperation
import stellar.sdk.model.{Account, AccountId, NativeAmount, TimeBounds, Transaction}

import scala.concurrent.Await
import scala.concurrent.duration._
import scala.util.Try

class FriendBotSpec(implicit ee: ExecutionEnv) extends Specification {

  "the test network" should {
    "allow account funding via friendbot" >> {
      // #friendbot_example
      val kp = KeyPair.random
      val response = TestNetwork.fund(kp)
      // #friendbot_example

      val r = Await.result(response, 1 minute)

      // roll it back in, to be a good testnet citizen
      implicit val n = TestNetwork
      val giveItBack = for {
        accn <- n.account(kp)
        friendbot <- response.map(_.transaction.transaction.source)
        response <- Transaction(accn,
          maxFee = NativeAmount(100),
          timeBounds = TimeBounds.Unbounded
        ).add(AccountMergeOperation(friendbot.id)).sign(kp).submit()
      } yield response
      Await.result(giveItBack, 1 minute)

      r.isSuccess must beTrue
    }

    "be used to serialise a transaction" >> {
      val accn = KeyPair.fromPassphrase("an account")
      val sequence = 1
      val txn = {
        // #new_transaction_example
        implicit val network = TestNetwork
        val account = Account(AccountId(accn.publicKey), sequence)
        Transaction(account, maxFee = NativeAmount(100), timeBounds = TimeBounds.Unbounded)
        // #new_transaction_example
      }
      Try(txn.encodeXDR) must beASuccessfulTry[String]
    }
  }

} 
Example 180
Source File: DomainInfoItSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk

import okhttp3.HttpUrl
import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import stellar.sdk.model.domain.{DomainInfo, IssuerDocumentation, Validator}

import scala.concurrent.duration._

class DomainInfoItSpec(implicit ee: ExecutionEnv) extends Specification {

  "known stellar.toml files" should {
    "parse correctly" >> {
      // #domain_info_example
      DomainInfo.forDomain("stellar.org") must beSome(
        DomainInfo(
          version = Some("2.0.0"),
          accounts = List(
            KeyPair.fromAccountId("GB6NVEN5HSUBKMYCE5ZOWSK5K23TBWRUQLZY3KNMXUZ3AQ2ESC4MY4AQ"),
            KeyPair.fromAccountId("GATL3ETTZ3XDGFXX2ELPIKCZL7S5D2HY3VK4T7LRPD6DW5JOLAEZSZBA"),
            KeyPair.fromAccountId("GCVLWV5B3L3YE6DSCCMHLCK7QIB365NYOLQLW3ZKHI5XINNMRLJ6YHVX"),
            KeyPair.fromAccountId("GCVJDBALC2RQFLD2HYGQGWNFZBCOD2CPOTN3LE7FWRZ44H2WRAVZLFCU"),
            KeyPair.fromAccountId("GAMGGUQKKJ637ILVDOSCT5X7HYSZDUPGXSUW67B2UKMG2HEN5TPWN3LQ"),
            KeyPair.fromAccountId("GDUY7J7A33TQWOSOQGDO776GGLM3UQERL4J3SPT56F6YS4ID7MLDERI4"),
            KeyPair.fromAccountId("GCPWKVQNLDPD4RNP5CAXME4BEDTKSSYRR4MMEL4KG65NEGCOGNJW7QI2"),
            KeyPair.fromAccountId("GDKIJJIKXLOM2NRMPNQZUUYK24ZPVFC6426GZAEP3KUK6KEJLACCWNMX"),
            KeyPair.fromAccountId("GAX3BRBNB5WTJ2GNEFFH7A4CZKT2FORYABDDBZR5FIIT3P7FLS2EFOZZ"),
            KeyPair.fromAccountId("GBEVKAYIPWC5AQT6D4N7FC3XGKRRBMPCAMTO3QZWMHHACLHTMAHAM2TP"),
            KeyPair.fromAccountId("GCKJZ2YVECFGLUDJ5T7NZMJPPWERBNYHCXT2MZPXKELFHUSYQR5TVHJQ"),
            KeyPair.fromAccountId("GBA6XT7YBQOERXT656T74LYUVJ6MEIOC5EUETGAQNHQHEPUFPKCW5GYM"),
            KeyPair.fromAccountId("GD2D6JG6D3V52ZMPIYSVHYFKVNIMXGYVLYJQ3HYHG5YDPGJ3DCRGPLTP"),
            KeyPair.fromAccountId("GA2VRL65L3ZFEDDJ357RGI3MAOKPJZ2Z3IJTPSC24I4KDTNFSVEQURRA")
          ),
          issuerDocumentation = Some(IssuerDocumentation(
            name = Some("Stellar Development Foundation"),
            url = Some(HttpUrl.parse("https://www.stellar.org")),
            github = Some("stellar"),
            twitter = Some("StellarOrg"),
          )),
          validators = List(
            Validator(
              alias = Some("sdf1"),
              displayName = Some("SDF 1"),
              host = Some("core-live-a.stellar.org:11625"),
              publicKey = Some(KeyPair.fromAccountId("GCGB2S2KGYARPVIA37HYZXVRM2YZUEXA6S33ZU5BUDC6THSB62LZSTYH")),
              history = Some(HttpUrl.parse("http://history.stellar.org/prd/core-live/core_live_001/"))
            ),
            Validator(
              alias = Some("sdf2"),
              displayName = Some("SDF 2"),
              host = Some("core-live-b.stellar.org:11625"),
              publicKey = Some(KeyPair.fromAccountId("GCM6QMP3DLRPTAZW2UZPCPX2LF3SXWXKPMP3GKFZBDSF3QZGV2G5QSTK")),
              history = Some(HttpUrl.parse("http://history.stellar.org/prd/core-live/core_live_002/"))
            ),
            Validator(
              alias = Some("sdf3"),
              displayName = Some("SDF 3"),
              host = Some("core-live-c.stellar.org:11625"),
              publicKey = Some(KeyPair.fromAccountId("GABMKJM6I25XI4K7U6XWMULOUQIQ27BCTMLS6BYYSOWKTBUXVRJSXHYQ")),
              history = Some(HttpUrl.parse("http://history.stellar.org/prd/core-live/core_live_003/"))
            ),
          )
        )
      )
      // #domain_info_example
      .awaitFor(30.seconds)
    }
  }
} 
Example 181
Source File: TestNetworkJourney.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import org.specs2.specification.BeforeAfterAll
import stellar.sdk.model._
import stellar.sdk.model.op.PaymentOperation
import stellar.sdk.util.ByteArrays

import scala.concurrent.Await
import scala.concurrent.duration._

class TestNetworkJourney(implicit ee: ExecutionEnv) extends Specification with BeforeAfterAll {

  implicit val network = TestNetwork

  private val testAccounts = new TestAccounts(4)

  def beforeAll() = testAccounts.open()
  def afterAll() = testAccounts.close()

  "a client" should {
    "be able to send a payment" >> {
      val List(senderKey, recipientKey) = testAccounts.take(2)
      val response = for {
        sender <- network.account(senderKey)
        payment = PaymentOperation(recipientKey.toAccountId, Amount.lumens(2))
        txn = Transaction(sender, List(payment), NoMemo, TimeBounds.Unbounded, Amount.lumens(1))
        response <- txn.sign(senderKey).submit()
      } yield response

      response.map(_.isSuccess) must beTrue.await(0, 1.minute)
    }

    "be able to fee bump a v0 transaction" >> {
      val List(senderKey, recipientKey) = testAccounts.take(2)
      val sender = Await.result(network.account((senderKey)), 10.seconds)
      val payment = PaymentOperation(recipientKey.toAccountId, Amount.lumens(2))
      val signedTransaction = Transaction(sender, List(payment), NoMemo, TimeBounds.Unbounded, NativeAmount(100))
        .sign(senderKey)
      val parsedV0Txn: SignedTransaction = SignedTransaction.decode.run(signedTransaction.encodeV0).value._2

      val bumpedTxn = parsedV0Txn.bumpFee(NativeAmount(500), recipientKey)
      val response = Await.result(bumpedTxn.submit(), 20.seconds)
      response.isSuccess must beTrue
    }
  }
} 
Example 182
Source File: FederationLookupSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk

import org.specs2.concurrent.ExecutionEnv
import org.specs2.mutable.Specification
import stellar.sdk.model.response.FederationResponse

import scala.concurrent.duration._

class FederationLookupSpec(implicit ec: ExecutionEnv) extends Specification {

  "federation server lookup" should {
    "find result by name" >> {
      FederationServer("https://keybase.io/_/api/1.0/stellar/federation.json")
        .byName("jem*keybase.io") must beSome(
        FederationResponse(
          address = "jem*keybase.io",
          account = KeyPair.fromAccountId("GBRAZP7U3SPHZ2FWOJLHPBO3XABZLKHNF6V5PUIJEEK6JEBKGXWD2IIE")
        )).awaitFor(10.seconds)
    }
  }

} 
Example 183
Source File: PaymentPathSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model

import org.json4s.NoTypeHints
import org.json4s.native.{JsonMethods, Serialization}
import org.specs2.mutable.Specification
import stellar.sdk.ArbitraryInput

class PaymentPathSpec extends Specification with ArbitraryInput {

  implicit val formats = Serialization.formats(NoTypeHints) + PaymentPathDeserializer

  "a payment path response document" should {
    "parse to a payment path" >> prop { path: PaymentPath =>

      def amountJson(prefix: String, amount: Amount) =
        s"""
           |"${prefix}amount": "${amount.toDisplayUnits}",
           |${assetJson(prefix, amount.asset)}
         """.stripMargin

      def assetJson(prefix: String, asset: Asset) = {
        asset match {
          case NativeAsset => s""""${prefix}asset_type": "native""""
          case issuedAsset: NonNativeAsset =>
            s"""
               |"${prefix}asset_type": "${issuedAsset.typeString}",
               |"${prefix}asset_code": "${issuedAsset.code}",
               |"${prefix}asset_issuer": "${issuedAsset.issuer.accountId}"
            """.stripMargin
        }
      }

      val json =
        s"""
           |{
           |  ${amountJson("source_", path.source)},
           |  ${amountJson("destination_", path.destination)},
           |  "path": ${path.path.map(j => s"{${assetJson("", j)}}").mkString("[", ",", "]")}
           |}
         """.stripMargin

      JsonMethods.parse(json).extract[PaymentPath] mustEqual path
    }
  }

  "the underlying amount parser" should {
    "not parse unrecognised asset type" >> {
      val doc = """{"foo_asset_type":"bananas"}"""
      AmountParser.parseAsset("foo_", JsonMethods.parse(doc)) must throwA[RuntimeException]
    }
  }

} 
Example 184
Source File: StrKeySpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model

import org.specs2.mutable.Specification
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class StrKeySpec extends Specification with ArbitraryInput with DomainMatchers {

  "strkey" should {
    "encode and decode to same" >> prop { key: StrKey =>
      val string = key.encodeToChars.mkString
      StrKey.decodeFromString(string) must beEquivalentTo(key)
    }

    "fail to decode if any char is > 127" >> {
      StrKey.decodeFromString("welcome to the 草叢") must throwAn[AssertionError]
    }
  }

} 
Example 185
Source File: TradeSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.specs2.mutable.Specification
import stellar.sdk.ArbitraryInput
import stellar.sdk.model.op.JsonSnippets

class TradeSpec extends Specification with ArbitraryInput with JsonSnippets {

  implicit val formats = Serialization.formats(NoTypeHints) + TradeDeserializer

  "trade" should {
    "parse from json" >> prop { trade: Trade =>

      val doc =
        s"""
           |{
           |  "_links": {
           |    "self": {"href": ""},
           |    "base": {"href": "https://horizon.stellar.org/accounts/GCI7ILB37OFVHLLSA74UCXZFCTPEBJOZK7YCNBI7DKH7D76U4CRJBL2A"},
           |    "counter": {"href": "https://horizon.stellar.org/accounts/GDRFRGR2FDUFF2RI6PQE5KFSCJHGSEIOGET22R66XSATP3BYHZ46BPLO"},
           |    "operation": {"href": "https://horizon.stellar.org/operations/38583306127675393"}
           |  },
           |  "id": "${trade.id}",
           |  "paging_token": "38583306127675393-2",
           |  "ledger_close_time": "${formatter.format(trade.ledgerCloseTime)}",
           |  "offer_id": "${trade.offerId}",
           |  "base_offer_id": "${trade.baseOfferId}",
           |  "base_account": "${trade.baseAccount.accountId}",
           |  ${amountDocPortion(trade.baseAmount, "base_amount", "base_")}
           |  ${amountDocPortion(trade.counterAmount, "counter_amount", "counter_")}
           |  "counter_account": "${trade.counterAccount.accountId}",
           |  "counter_offer_id": "${trade.counterOfferId}",
           |  "base_is_seller": ${trade.baseIsSeller}
           |}
         """.stripMargin

      parse(doc).extract[Trade] mustEqual trade
    }
  }

} 
Example 186
Source File: TransactionLedgerEntriesSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.ledger

import com.typesafe.scalalogging.LazyLogging
import org.specs2.mutable.Specification

import scala.util.{Failure, Try}

class TransactionLedgerEntriesSpec extends Specification with LedgerEntryGenerators with LazyLogging {

  "a ledger entry" should {
    "serde to/from XDR" >> prop { entries: TransactionLedgerEntries =>
      val triedEntries = Try(TransactionLedgerEntries.decode.run(entries.encode).value._2)
      triedEntries match {
        case Failure(_) => logger.error(s"Failed to decode $entries")
        case _ =>
      }
      triedEntries must beSuccessfulTry(entries)
    }
  }

} 
Example 187
Source File: LedgerEntrySpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.ledger

import com.typesafe.scalalogging.LazyLogging
import org.specs2.mutable.Specification

import scala.util.{Failure, Try}

class LedgerEntrySpec extends Specification with LedgerEntryGenerators with LazyLogging {

  "a ledger entry" should {
    "serde to/from XDR" >> prop { entry: LedgerEntry =>
      val triedEntry = Try(LedgerEntry.decode.run(entry.encode).value._2)
      triedEntry match {
        case Failure(_) => logger.error(s"Failed to decode $entry")
        case _ =>
      }
      triedEntry must beSuccessfulTry(entry)
    }
  }

} 
Example 188
Source File: LedgerEntryChangeSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.ledger

import com.typesafe.scalalogging.LazyLogging
import org.specs2.mutable.Specification

import scala.util.{Failure, Try}

class LedgerEntryChangeSpec extends Specification with LedgerEntryGenerators with LazyLogging {

  "a ledger entry change" should {
    "serde to/from XDR" >> prop { change: LedgerEntryChange =>
      val triedChange = Try(LedgerEntryChange.decode.run(change.encode).value._2)
      triedChange match {
        case Failure(_) => logger.error(s"Failed to decode $change")
        case _ =>
      }
      triedChange must beSuccessfulTry(change)
    }
  }

} 
Example 189
Source File: AccountMergeOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers, KeyPair}

class AccountMergeOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[AccountMergeOperation]] = Arbitrary(genTransacted(genAccountMergeOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "account merge operation" should {
    "serde via xdr string" >> prop { actual: AccountMergeOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: AccountMergeOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[AccountMergeOperation] =>
      val doc =
        s"""
           | {
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account":"${op.operation.sourceAccount.get.accountId}",
           |  "type_i": 8,
           |  "type": "account_merge"
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  "account": "${op.operation.sourceAccount.get.accountId}",
           |  "into": "${KeyPair.fromPublicKey(op.operation.destination.hash).accountId}",
           |}
         """.stripMargin

      parse(doc).extract[Transacted[AccountMergeOperation]] mustEqual op
    }.setGen(genTransacted(genAccountMergeOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 190
Source File: SetOptionsOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class SetOptionsOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[SetOptionsOperation]] = Arbitrary(genTransacted(genSetOptionsOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "set options operation" should {
    "serde via xdr string" >> prop { actual: SetOptionsOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: SetOptionsOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded must beEquivalentTo(actual)
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[SetOptionsOperation] =>
      val doc =
        s"""
           |{
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659137"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659137/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659137"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659137"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  ${opt("inflation_dest", op.operation.inflationDestination.map(_.accountId))}
           |  ${opt("home_domain", op.operation.homeDomain)}
           |  ${opt("master_key_weight", op.operation.masterKeyWeight)}
           |  ${opt("signer_key", op.operation.signer.map(_.key.encodeToChars.mkString))}
           |  ${opt("signer_weight", op.operation.signer.map(_.weight))}
           |  ${opt("set_flags", op.operation.setFlags.map(_.map(_.i)))}
           |  ${opt("set_flags_s", op.operation.setFlags.map(_.map(_.s)))}
           |  ${opt("clear_flags", op.operation.clearFlags.map(_.map(_.i)))}
           |  ${opt("clear_flags_s", op.operation.clearFlags.map(_.map(_.s)))}
           |  ${opt("low_threshold", op.operation.lowThreshold)}
           |  ${opt("med_threshold", op.operation.mediumThreshold)}
           |  ${opt("high_threshold", op.operation.highThreshold)}
           |  "type": "set_options",
           |  "type_i": 5,
           |}
         """.stripMargin

      parse(doc).extract[Transacted[SetOptionsOperation]] must beEquivalentTo(op)
    }.setGen(genTransacted(genSetOptionsOperation.suchThat(_.sourceAccount.nonEmpty)))
  }
} 
Example 191
Source File: PathPaymentStrictReceiveOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.{Formats, NoTypeHints}
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class PathPaymentStrictReceiveOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[PathPaymentStrictReceiveOperation]] = Arbitrary(genTransacted(genPathPaymentStrictReceiveOperation))
  implicit val formats: Formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "path payment operation" should {
    "serde via xdr string" >> prop { actual: PathPaymentStrictReceiveOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: PathPaymentStrictReceiveOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[PathPaymentStrictReceiveOperation] =>
      val doc =
        s"""
           |{
           |  "_links":{
           |    "self":{"href":"https://horizon-testnet.stellar.org/operations/940258535411713"},
           |    "transaction":{"href":"https://horizon-testnet.stellar.org/transactions/a995af17837d1b53fb5782269250a36e9dbe74170260b46f2708e5f23f7c864a"},
           |    "effects":{"href":"https://horizon-testnet.stellar.org/operations/940258535411713/effects"},
           |    "succeeds":{"href":"https://horizon-testnet.stellar.org/effects?order=desc&cursor=940258535411713"},
           |    "precedes":{"href":"https://horizon-testnet.stellar.org/effects?order=asc&cursor=940258535411713"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type":"path_payment",
           |  "type_i":2,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  ${amountDocPortion(op.operation.destinationAmount)}
           |  ${amountDocPortion(op.operation.sendMax, "source_max", "source_")}
           |  "from":"${op.operation.sourceAccount.get.accountId}",
           |  "to":"${op.operation.destinationAccount.publicKey.accountId}",
           |  "path":[${if (op.operation.path.isEmpty) "" else op.operation.path.map(asset(_)).mkString("{", "},{", "}")}]
           |}
         """.stripMargin

      parse(doc).extract[Transacted[Operation]] mustEqual removeDestinationSubAccountId(op)
    }.setGen(genTransacted(genPathPaymentStrictReceiveOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

  // Because sub accounts are not yet supported in Horizon JSON.
  private def removeDestinationSubAccountId(op: Transacted[PathPaymentStrictReceiveOperation]): Transacted[PathPaymentStrictReceiveOperation] = {
    op.copy(operation = op.operation.copy(destinationAccount = op.operation.destinationAccount.copy(subAccountId = None)))
  }
} 
Example 192
Source File: CreateAccountOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.{Formats, NoTypeHints}
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class CreateAccountOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[CreateAccountOperation]] = Arbitrary(genTransacted(genCreateAccountOperation))
  implicit val formats: Formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer + OperationDeserializer

  "create account operation" should {
    "serde via xdr string" >> prop { actual: CreateAccountOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: CreateAccountOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "be parsed from json " >> prop { op: Transacted[CreateAccountOperation] =>
      val doc =
        s"""
           |{
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659137"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659137/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659137"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659137"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "create_account",
           |  "type_i": 0,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  "starting_balance": "${amountString(op.operation.startingBalance)}",
           |  "funder": "${op.operation.sourceAccount.get.accountId}",
           |  "account": "${op.operation.destinationAccount.publicKey.accountId}"
           |}
         """.stripMargin

      parse(doc).extract[Transacted[CreateAccountOperation]] mustEqual removeDestinationSubAccountId(op)
    }.setGen(genTransacted(genCreateAccountOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

  // Because sub accounts are not yet supported in Horizon JSON.
  private def removeDestinationSubAccountId(op: Transacted[CreateAccountOperation]): Transacted[CreateAccountOperation] = {
    op.copy(operation = op.operation.copy(destinationAccount = op.operation.destinationAccount.copy(subAccountId = None)))
  }
} 
Example 193
Source File: InflationOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class InflationOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[InflationOperation]] = Arbitrary(genTransacted(genInflationOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "the inflation operation" should {
    "serde via xdr string" >> prop { actual: InflationOperation =>
      Operation.decodeXDR(base64(actual.encode)) mustEqual actual
    }

    "serde via xdr bytes" >> prop { actual: InflationOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[InflationOperation] =>
      val doc =
        s"""
           | {
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "inflation",
           |  "type_i": 9,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |}
         """.stripMargin

      parse(doc).extract[Transacted[InflationOperation]] mustEqual op
    }.setGen(genTransacted(genInflationOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 194
Source File: BumpSequenceOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class BumpSequenceOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[BumpSequenceOperation]] = Arbitrary(genTransacted(genBumpSequenceOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "bump sequence operation" should {
    "serde via xdr bytes" >> prop { actual: BumpSequenceOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "serde via xdr string" >> prop { actual: BumpSequenceOperation =>
      Operation.decodeXDR(ByteArrays.base64(actual.encode)) mustEqual actual
    }

    "parse from json" >> prop { op: Transacted[BumpSequenceOperation] =>
      val doc =
        s"""
           | {
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "bump_sequence",
           |  "type_i": 11,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  "bump_to": ${op.operation.bumpTo}
           |}
         """.stripMargin

      parse(doc).extract[Transacted[BumpSequenceOperation]] mustEqual op
    }.setGen(genTransacted(genBumpSequenceOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 195
Source File: CreatePassiveSellOfferOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class CreatePassiveSellOfferOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[CreatePassiveSellOfferOperation]] = Arbitrary(genTransacted(genCreatePassiveSellOfferOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer + OperationDeserializer

  "create passive offer operation" should {
    "serde via xdr string" >> prop { actual: CreatePassiveSellOfferOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: CreatePassiveSellOfferOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[CreatePassiveSellOfferOperation] =>
      val doc =
        s"""
           |{
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659137"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659137/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659137"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659137"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "create_passive_sell_offer",
           |  "type_i": 4,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  ${amountDocPortion(op.operation.selling, assetPrefix = "selling_")},
           |  ${asset(op.operation.buying, "buying_")},
           |  "offer_id": 0,
           |  "price": "1.0",
           |  "price_r": {
           |    "d": ${op.operation.price.d},
           |    "n": ${op.operation.price.n}
           |  }
           |}
         """.stripMargin

      parse(doc).extract[Transacted[CreatePassiveSellOfferOperation]] mustEqual op
    }.setGen(genTransacted(genCreatePassiveSellOfferOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 196
Source File: PathPaymentStrictSendOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.{Formats, NoTypeHints}
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class PathPaymentStrictSendOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[PathPaymentStrictSendOperation]] = Arbitrary(genTransacted(genPathPaymentStrictSendOperation))
  implicit val formats: Formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "path payment operation" should {
    "serde via xdr string" >> prop { actual: PathPaymentStrictSendOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: PathPaymentStrictSendOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[PathPaymentStrictSendOperation] =>
      val doc =
        s"""
           |{
           |  "_links":{
           |    "self":{"href":"https://horizon-testnet.stellar.org/operations/940258535411713"},
           |    "transaction":{"href":"https://horizon-testnet.stellar.org/transactions/a995af17837d1b53fb5782269250a36e9dbe74170260b46f2708e5f23f7c864a"},
           |    "effects":{"href":"https://horizon-testnet.stellar.org/operations/940258535411713/effects"},
           |    "succeeds":{"href":"https://horizon-testnet.stellar.org/effects?order=desc&cursor=940258535411713"},
           |    "precedes":{"href":"https://horizon-testnet.stellar.org/effects?order=asc&cursor=940258535411713"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type":"path_payment_strict_send",
           |  "type_i":13,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  ${amountDocPortion(op.operation.sendAmount, assetPrefix = "source_")}
           |  ${amountDocPortion(op.operation.destinationMin, "destination_min")}
           |  "from":"${op.operation.sourceAccount.get.accountId}",
           |  "to":"${op.operation.destinationAccount.publicKey.accountId}",
           |  "path":[${if (op.operation.path.isEmpty) "" else op.operation.path.map(asset(_)).mkString("{", "},{", "}")}]
           |}
         """.stripMargin

      parse(doc).extract[Transacted[Operation]] mustEqual removeDestinationSubAccountId(op)
    }.setGen(genTransacted(genPathPaymentStrictSendOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

  // Because sub accounts are not yet supported in Horizon JSON.
  private def removeDestinationSubAccountId(op: Transacted[PathPaymentStrictSendOperation]): Transacted[PathPaymentStrictSendOperation] = {
    op.copy(operation = op.operation.copy(destinationAccount = op.operation.destinationAccount.copy(subAccountId = None)))
  }
} 
Example 197
Source File: AllowTrustOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers, KeyPair}

class AllowTrustOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[AllowTrustOperation]] = Arbitrary(genTransacted(genAllowTrustOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "allow trust operation" should {
    "serde via xdr string" >> prop { actual: AllowTrustOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: AllowTrustOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[AllowTrustOperation] =>
      val doc =
        s"""
           | {
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "allow_trust",
           |  "type_i": 7,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  "asset_type": "${if (op.operation.assetCode.length <= 4) "credit_alphanum4" else "credit_alphanum12"}",
           |  "asset_code": "${op.operation.assetCode}",
           |  "asset_issuer": "${op.operation.sourceAccount.get.accountId}"
           |  "trustor": "${op.operation.trustor.accountId}",
           |  "trustee": "${op.operation.sourceAccount.get.accountId}",
           |  "authorize": ${op.operation.trustLineFlags.contains(TrustLineAuthorized)}
           |  "authorize_to_maintain_liabilities": ${op.operation.trustLineFlags.contains(TrustLineCanMaintainLiabilities)}
           |}
         """.stripMargin

      val parsed = parse(doc).extract[Transacted[AllowTrustOperation]]
      parsed mustEqual op
      parsed.operation.authorize mustEqual op.operation.authorize
      parsed.operation.authorizeToMaintainLiabilities mustEqual op.operation.authorizeToMaintainLiabilities
    }.setGen(genTransacted(genAllowTrustOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 198
Source File: ChangeTrustOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class ChangeTrustOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[ChangeTrustOperation]] = Arbitrary(genTransacted(genChangeTrustOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "change trust operation" should {
    "serde via xdr string" >> prop { actual: ChangeTrustOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: ChangeTrustOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[ChangeTrustOperation] =>
      val doc =
        s"""
           | {
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "change_trust",
           |  "type_i": 6,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  ${amountDocPortion(op.operation.limit, "limit")},
           |  "trustee": "${op.operation.limit.asset.issuer.accountId}",
           |  "trustor": "${op.operation.sourceAccount.get.accountId}",
           |}
         """.stripMargin

      parse(doc).extract[Transacted[ChangeTrustOperation]] mustEqual op
    }.setGen(genTransacted(genChangeTrustOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 199
Source File: ManageDataOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.apache.commons.codec.binary.Base64
import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.{Arbitrary, Gen}
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers, PublicKey}

class ManageDataOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arbDelete: Arbitrary[Transacted[DeleteDataOperation]] = Arbitrary(genTransacted(genDeleteDataOperation))
  implicit val arbWrite: Arbitrary[Transacted[WriteDataOperation]] = Arbitrary(genTransacted(genWriteDataOperation))
  implicit val formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  def doc[O <: ManageDataOperation](op: Transacted[O]) = {
    val dataValue = op.operation match {
      case WriteDataOperation(_, value, _) => Base64.encodeBase64String(value.toArray)
      case _ => ""
    }

    s"""
      |{
      |  "_links": {
      |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
      |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
      |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
      |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
      |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
      |  },
      |  "id": "${op.id}",
      |  "paging_token": "10157597659137",
      |  "source_account": "${op.operation.sourceAccount.get.accountId}",
      |  "type": "manage_data",
      |  "type_i": 1,
      |  "created_at": "${formatter.format(op.createdAt)}",
      |  "transaction_hash": "${op.txnHash}",
      |  "name": "${op.operation.name}",
      |  "value": "$dataValue"
      |}""".stripMargin
  }

  "a write data operation" should {
    "serde via xdr string" >> prop { actual: WriteDataOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: WriteDataOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded must beEquivalentTo(actual)
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[WriteDataOperation] =>
      parse(doc(op)).extract[Transacted[ManageDataOperation]] must beEquivalentTo(op)
    }.setGen(genTransacted(genWriteDataOperation.suchThat(_.sourceAccount.nonEmpty)))

    "encode a string payload as UTF-8 in base64" >> prop { (s: String, source: PublicKey) =>
      val value = new String(s.take(64).getBytes("UTF-8").take(60), "UTF-8")
      WriteDataOperation("name", value).value.toSeq mustEqual value.getBytes("UTF-8").toSeq
      WriteDataOperation("name", value, None).value.toSeq mustEqual value.getBytes("UTF-8").toSeq
      WriteDataOperation("name", value, Some(source)).value.toSeq mustEqual value.getBytes("UTF-8").toSeq
    }.setGen1(Arbitrary.arbString.arbitrary.suchThat(_.nonEmpty))

    "fail if the key is greater than 64 bytes" >> prop { s: String =>
      WriteDataOperation(s, "value") must throwAn[IllegalArgumentException]
    }.setGen(Gen.identifier.suchThat(_.getBytes("UTF-8").length > 64))

    "fail if the value is greater than 64 bytes" >> prop { s: String =>
      WriteDataOperation("name", s) must throwAn[IllegalArgumentException]
    }.setGen(Gen.identifier.suchThat(_.getBytes("UTF-8").length > 64))
  }

  "a delete data operation" should {
    "serde via xdr string" >> prop { actual: DeleteDataOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: DeleteDataOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[DeleteDataOperation] =>
      parse(doc(op)).extract[Transacted[ManageDataOperation]] mustEqual op
    }.setGen(genTransacted(genDeleteDataOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

} 
Example 200
Source File: PaymentOperationSpec.scala    From scala-stellar-sdk   with Apache License 2.0 5 votes vote down vote up
package stellar.sdk.model.op

import org.json4s.{Formats, NoTypeHints}
import org.json4s.native.JsonMethods.parse
import org.json4s.native.Serialization
import org.scalacheck.Arbitrary
import org.specs2.mutable.Specification
import stellar.sdk.util.ByteArrays.base64
import stellar.sdk.{ArbitraryInput, DomainMatchers}

class PaymentOperationSpec extends Specification with ArbitraryInput with DomainMatchers with JsonSnippets {

  implicit val arb: Arbitrary[Transacted[PaymentOperation]] = Arbitrary(genTransacted(genPaymentOperation))
  implicit val formats: Formats = Serialization.formats(NoTypeHints) + TransactedOperationDeserializer

  "payment operation" should {
    "serde via xdr string" >> prop { actual: PaymentOperation =>
      Operation.decodeXDR(base64(actual.encode)) must beEquivalentTo(actual)
    }

    "serde via xdr bytes" >> prop { actual: PaymentOperation =>
      val (remaining, decoded) = Operation.decode.run(actual.encode).value
      decoded mustEqual actual
      remaining must beEmpty
    }

    "parse from json" >> prop { op: Transacted[PaymentOperation] =>
      val doc =
        s"""
           | {
           |  "_links": {
           |    "self": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144"},
           |    "transaction": {"href": "https://horizon-testnet.stellar.org/transactions/17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a"},
           |    "effects": {"href": "https://horizon-testnet.stellar.org/operations/10157597659144/effects"},
           |    "succeeds": {"href": "https://horizon-testnet.stellar.org/effects?order=desc\u0026cursor=10157597659144"},
           |    "precedes": {"href": "https://horizon-testnet.stellar.org/effects?order=asc\u0026cursor=10157597659144"}
           |  },
           |  "id": "${op.id}",
           |  "paging_token": "10157597659137",
           |  "source_account": "${op.operation.sourceAccount.get.accountId}",
           |  "type": "payment",
           |  "type_i": 1,
           |  "created_at": "${formatter.format(op.createdAt)}",
           |  "transaction_hash": "${op.txnHash}",
           |  ${amountDocPortion(op.operation.amount)},
           |  "from": "${op.operation.sourceAccount.get.accountId}",
           |  "to": "${op.operation.destinationAccount.publicKey.accountId}",
           |}
         """.stripMargin

      parse(doc).extract[Transacted[PaymentOperation]] mustEqual removeDestinationSubAccountId(op)
    }.setGen(genTransacted(genPaymentOperation.suchThat(_.sourceAccount.nonEmpty)))
  }

  // Because sub accounts are not yet supported in Horizon JSON.
  private def removeDestinationSubAccountId(op: Transacted[PaymentOperation]): Transacted[PaymentOperation] = {
    op.copy(operation = op.operation.copy(destinationAccount = op.operation.destinationAccount.copy(subAccountId = None)))
  }
}