Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScalatestRouteTest does not support session test #25

Open
epiphyllum opened this issue Jan 14, 2017 · 6 comments
Open

ScalatestRouteTest does not support session test #25

epiphyllum opened this issue Jan 14, 2017 · 6 comments

Comments

@epiphyllum
Copy link

epiphyllum commented Jan 14, 2017

in my example:
there are three route: login, upload, download
to test it, the client must login first to upload
then with the result from previous upload, can only the client initiate the download test
it seems that ScalatestRouteTest does not support this kinds of tests

package com.yimei.zflow.util.asset.routes

import akka.actor.ActorSystem
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, Multipart}
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.typesafe.config.ConfigFactory
import com.yimei.zflow.util.FlywayDB
import com.yimei.zflow.util.asset.routes.Models._
import com.yimei.zflow.util.organ.OrganSession
import org.scalatest.{Inside, Matchers, WordSpec}

object AssetRouteUT extends {
  implicit val coreSystem: ActorSystem = ActorSystem("TestSystem", ConfigFactory.parseString(
    """
      |database {
      |  jdbcUrl = "jdbc:mysql://127.0.0.1/cyflow?useUnicode=true&characterEncoding=utf8"
      |  username = "mysql"
      |  password = "mysql"
      |}
      |file.root = "/tmp"
      |akka.http.session.server-secret = "1234567891234567891234567891234567891234567890000012345678901234"
      |
    """.stripMargin))
} with AssetRoute {
  val fileField = "file"

  def prepare() = {
    val config = coreSystem.settings.config
    val jdbcUrl = config.getString("database.jdbcUrl")
    val username = config.getString("database.username")
    val password = config.getString("database.password")
    val flyway = new FlywayDB(jdbcUrl, username, password);
    flyway.drop()
    flyway.migrate()
  }

  import akka.http.scaladsl.server.Directives._
  def loginRoute: Route = path("login") {
    organSetSession(OrganSession("hary", "uid", "party", "instanceId", "company")) { ctx =>
      ctx.complete("ok")
    }
  }
}

/**
  * Created by hary on 17/1/10.
  */
class AssetRouteTest extends WordSpec with Matchers with Inside with ScalatestRouteTest with SprayJsonSupport {

  import AssetRouteUT.{assetRoute, loginRoute, prepare}

  override protected def beforeAll(): Unit = {
    super.beforeAll()
    prepare

    // must be tested with login session

  }

  val xml = "<int>42</int>"  // 上传文件
  val simpleMultipartUpload =
    Multipart.FormData(Multipart.FormData.BodyPart.Strict(
      "file",
      HttpEntity(ContentTypes.`text/xml(UTF-8)`, xml),
      Map("filename"  "age.xml")))

  var assetId: String = null

  "AssetRouteTest" should {

    "login is ok" in {
      Post("/login") ~> loginRoute ~> check {
        responseAs[String] shouldBe "ok"
      }

    }

    "uploadFile is ok" in {
      Post("/upload") ~> assetRoute ~> check {
        inside(responseAs[UploadResult]) {
          case UploadResult(id) =>
            assetId = id
            1 shouldBe 1
        }
      }
    }

    "downloadFile is in" in {
      Get("/download/" + assetId) ~> assetRoute ~> check {
        responseAs[String] shouldEqual xml
      }
    }
  }

}
@epiphyllum
Copy link
Author

it seems that each test request is indepenent

@epiphyllum
Copy link
Author

maybe, I can add the cookie header in subsequent test request to make it work

@epiphyllum
Copy link
Author

it seems that each test request is indepentent in ScalatestRouteTest, when I add Set-Cookie,
authorization is still failed。

package com.yimei.zflow.util.asset.routes

import akka.actor.ActorSystem
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.{ContentTypes, HttpEntity, HttpHeader, Multipart}
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.testkit.ScalatestRouteTest
import com.typesafe.config.ConfigFactory
import com.yimei.zflow.util.FlywayDB
import com.yimei.zflow.util.asset.routes.Models._
import com.yimei.zflow.util.organ.OrganSession
import org.scalatest.{Inside, Matchers, WordSpec}

object AssetRouteUT extends {
  implicit val coreSystem: ActorSystem = ActorSystem("TestSystem", ConfigFactory.parseString(
    """
      |database {
      |  jdbcUrl = "jdbc:mysql://127.0.0.1/cyflow?useUnicode=true&characterEncoding=utf8"
      |  username = "mysql"
      |  password = "mysql"
      |}
      |file.root = "/tmp"
      |akka.http.session.server-secret = "1234567891234567891234567891234567891234567890000012345678901234"
      |
    """.stripMargin))
} with AssetRoute {
  val fileField = "file"

  def prepare() = {
    val config = coreSystem.settings.config
    val jdbcUrl = config.getString("database.jdbcUrl")
    val username = config.getString("database.username")
    val password = config.getString("database.password")
    val flyway = new FlywayDB(jdbcUrl, username, password);
    flyway.drop()
    flyway.migrate()
  }

  import akka.http.scaladsl.server.Directives._
  def loginRoute: Route = path("login") {
    organSetSession(OrganSession("hary", "uid", "party", "instanceId", "company")) { ctx =>
      ctx.complete("ok")
    }
  }
}

/**
  * Created by hary on 17/1/10.
  */
class AssetRouteTest extends WordSpec with Matchers with Inside with ScalatestRouteTest with SprayJsonSupport {

  import AssetRouteUT.{assetRoute, loginRoute, prepare}

  override protected def beforeAll(): Unit = {
    super.beforeAll()
    prepare

    // must be tested with login session

  }

  val xml = "<int>42</int>"  // 上传文件
  val simpleMultipartUpload =
    Multipart.FormData(Multipart.FormData.BodyPart.Strict(
      "file",
      HttpEntity(ContentTypes.`text/xml(UTF-8)`, xml),
      Map("filename"  "age.xml")))

  var assetId: String = null

  var cookie: HttpHeader = null

  "AssetRouteTest" should {

    "login is ok" in {
      Post("/login") ~> loginRoute ~> check {
        cookie = header("Set-Cookie").get
        responseAs[String] shouldBe "ok"
        println("cookie is " + cookie.toString)
      }

    }

    "uploadFile is ok" in {
      Post("/upload") ~> addHeader(cookie) ~> assetRoute ~> check {
        inside(responseAs[UploadResult]) {
          case UploadResult(id) =>
            assetId = id
            1 shouldBe 1
        }
        cookie = header("Set-Cookie").get
      }
    }

    "downloadFile is in" in {
      Get("/download/" + assetId) ~> addHeader(cookie) ~> assetRoute ~> check {
        responseAs[String] shouldEqual xml
      }
    }
  }

}

@adamw
Copy link
Member

adamw commented Jan 14, 2017

Yes, each test is independent, only the headers that you specify explicitly are sent. Previous responses have no influence on subsequent requests.

Maybe this will help: https://github.com/softwaremill/akka-http-session/blob/master/core/src/test/scala/com/softwaremill/session/OneOffTest.scala#L94

These are the tests of the set/get session directives. In there the /set endpoints sets a session (logs a user in), and /get uses a previously created session.

@Hajto
Copy link

Hajto commented Jul 26, 2017

@adamw Can I pre-generate cookie/JWT before sending checking ANY route (like call JWT generate(resource)) ?

@adamw
Copy link
Member

adamw commented Jul 27, 2017

@Hajto yes, you can do it through SessionManager.clientSessionManager.createCookie(data: T). You need to have an implicit session manager somewhere in order for the routes to work, so you can just use the same one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants