diff --git a/build.sbt b/build.sbt index 1bb36f2..20233bc 100644 --- a/build.sbt +++ b/build.sbt @@ -6,6 +6,7 @@ organization := "tdauth" scalaVersion := "2.12.7" +libraryDependencies += "com.github.scopt" % "scopt_2.12" % "3.7.0" libraryDependencies += "io.spray" % "spray-json_2.12" % "1.3.4" libraryDependencies += "com.typesafe.akka" %% "akka-http" % "10.1.5" libraryDependencies += "com.typesafe.akka" %% "akka-http-core" % "10.1.5" diff --git a/src/main/scala/de/retest/guistatemachine/RestService.scala b/src/main/scala/de/retest/guistatemachine/RestService.scala index abe89d9..d8e1941 100644 --- a/src/main/scala/de/retest/guistatemachine/RestService.scala +++ b/src/main/scala/de/retest/guistatemachine/RestService.scala @@ -82,13 +82,12 @@ trait RestService { } ~ delete { path("application" / LongNumber / "test-suite" / LongNumber) { (appId, suiteId) => val r = persistence.deleteTestSuite(Id(appId), Id(suiteId)) - complete(StatusCodes.OK) + complete(if (r) StatusCodes.OK else StatusCodes.NotFound) } } ~ delete { path("application" / LongNumber) { id => val r = persistence.deleteApplication(Id(id)) - complete(StatusCodes.OK) + complete(if (r) StatusCodes.OK else StatusCodes.NotFound) } } - } \ No newline at end of file diff --git a/src/main/scala/de/retest/guistatemachine/WebServer.scala b/src/main/scala/de/retest/guistatemachine/WebServer.scala index fe07191..39ef092 100644 --- a/src/main/scala/de/retest/guistatemachine/WebServer.scala +++ b/src/main/scala/de/retest/guistatemachine/WebServer.scala @@ -6,6 +6,9 @@ import akka.actor.ActorSystem import akka.http.scaladsl.Http import akka.stream.ActorMaterializer import de.retest.guistatemachine.persistence.Persistence +import scopt.OptionParser + +case class Config(maxtime: Long = -1) object WebServer extends App with RestService { final val HOST = "localhost" @@ -16,13 +19,36 @@ object WebServer extends App with RestService { // needed for the future flatMap/onComplete in the end implicit val executionContext = system.dispatcher - val persistence = new Persistence + val parser = new OptionParser[Config]("scopt") { + head("gui-state-machine-api", "1.0") + + opt[Long]('t', "maxtime") action { (x, c) => + c.copy(maxtime = x) + } text ("maxtime specifies the maximum up time for the HTTP server in ms. This option can be helpful to run tests over a specific period of time.") + + help("help").text("prints this usage text") + } + // parser.parse returns Option[C] + parser.parse(args, Config()) match { + case Some(config) => + val persistence = new Persistence + + val bindingFuture = Http().bindAndHandle(getRoute(persistence), HOST, PORT) + + println(s"Server online at http://${HOST}:${PORT}/") - val bindingFuture = Http().bindAndHandle(getRoute(persistence), HOST, PORT) + if (config.maxtime < 0) { + println("Press RETURN to stop...") + StdIn.readLine() // let it run until user presses return + } else { + println(s"The server will shutdown automatically after ${config.maxtime / 1000} seconds.") + Thread.sleep(config.maxtime) + } + bindingFuture + .flatMap(_.unbind()) // trigger unbinding from the port + .onComplete(_ => system.terminate()) // and shutdown when done - println(s"Server online at http://${HOST}:${PORT}/\nPress RETURN to stop...") - StdIn.readLine() // let it run until user presses return - bindingFuture - .flatMap(_.unbind()) // trigger unbinding from the port - .onComplete(_ => system.terminate()) // and shutdown when done + case None => + // arguments are bad, error message will have been displayed + } } \ No newline at end of file diff --git a/src/test/scala/de/retest/guistatemachine/RestServiceSpec.scala b/src/test/scala/de/retest/guistatemachine/RestServiceSpec.scala index 7704b2e..0c05d34 100644 --- a/src/test/scala/de/retest/guistatemachine/RestServiceSpec.scala +++ b/src/test/scala/de/retest/guistatemachine/RestServiceSpec.scala @@ -42,6 +42,27 @@ class RestServiceSpec extends WordSpec with Matchers with ScalatestRouteTest wit } } + "fail for the GET request with the path /application/0" in { + Get("/application/0") ~> sut ~> check { + handled shouldEqual true + status shouldEqual StatusCodes.NotFound + } + } + + "fail for the DELETE request with the path /application/0" in { + Delete("/application/0") ~> sut ~> check { + handled shouldEqual true + status shouldEqual StatusCodes.NotFound + } + } + + "fail for the GET request with the path /application/0/test-suites" in { + Get("/application/0/test-suites") ~> sut ~> check { + handled shouldEqual true + status shouldEqual StatusCodes.NotFound + } + } + "allow POST for path /create-application" in { Post("/create-application") ~> sut ~> check { handled shouldEqual true @@ -68,6 +89,20 @@ class RestServiceSpec extends WordSpec with Matchers with ScalatestRouteTest wit } } + "fail for the GET request with the path /application/0/test-suite/0" in { + Get("/application/0/test-suite/0") ~> sut ~> check { + handled shouldEqual true + status shouldEqual StatusCodes.NotFound + } + } + + "fail for the DELETE request with the path /application/0/test-suite/0" in { + Delete("/application/0/test-suite/0") ~> sut ~> check { + handled shouldEqual true + status shouldEqual StatusCodes.NotFound + } + } + "allow POST for path /application/0/create-test-suite" in { Post("/application/0/create-test-suite") ~> sut ~> check { handled shouldEqual true @@ -102,5 +137,14 @@ class RestServiceSpec extends WordSpec with Matchers with ScalatestRouteTest wit persistence.getApplications().apps.values.size shouldEqual 0 } } + + "not handle the GET request with the path /applications/bla/hello/bla" in { + Get("/applications/bla/hello/bla") ~> sut ~> check { + handled shouldEqual false + //mediaType shouldEqual MediaTypes.`application/json` + //val r = responseAs[GuiApplications] + //r.apps.values.size shouldEqual 0 + } + } } } diff --git a/src/test/scala/de/retest/guistatemachine/WebServerSpec.scala b/src/test/scala/de/retest/guistatemachine/WebServerSpec.scala new file mode 100644 index 0000000..1d1b8e1 --- /dev/null +++ b/src/test/scala/de/retest/guistatemachine/WebServerSpec.scala @@ -0,0 +1,13 @@ +package de.retest.guistatemachine + +import org.scalatest.WordSpec +import org.scalatest.Matchers + +class WebServerSpec extends WordSpec with Matchers { + + "The web server" should { + "start and end successfully" in { + WebServer.main(Array("--maxtime=1000")) + } + } +} \ No newline at end of file diff --git a/src/test/scala/de/retest/guistatemachine/model/IdSpec.scala b/src/test/scala/de/retest/guistatemachine/model/IdSpec.scala new file mode 100644 index 0000000..8b7d110 --- /dev/null +++ b/src/test/scala/de/retest/guistatemachine/model/IdSpec.scala @@ -0,0 +1,17 @@ +package de.retest.guistatemachine.model + +import org.scalatest.WordSpec +import org.scalatest.Matchers + +class IdSpec extends WordSpec with Matchers { + + "Id" should { + "compare" in { + val id0 = Id(0) + val id1 = Id(1) + id0.compare(id0) shouldEqual 0 + id0.compare(id1) shouldEqual -1 + id1.compare(id0) shouldEqual 1 + } + } +} \ No newline at end of file