package play.api.test
import javax.inject.{ Inject, Provider }
import akka.actor.ActorSystem
import play.api._
import play.api.http._
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.inject._
import play.api.mvc._
import play.api.libs.json.JsValue
import play.api.routing.Router
import scala.concurrent.Future
import xml.NodeSeq
import scala.runtime.AbstractPartialFunction
import play.api.libs.Files.TemporaryFile
case class (: Seq[(String, String)] = Seq.empty) extends Headers(data)
case class FakeRequest[A](method: String, uri: String, : Headers, body: A, remoteAddress: String = "127.0.0.1", version: String = "HTTP/1.1", id: Long = 666, tags: Map[String, String] = Map.empty[String, String], secure: Boolean = false) extends Request[A] {
private def _copy[B](
id: Long = this.id,
tags: Map[String, String] = this.tags,
uri: String = this.uri,
path: String = this.path,
method: String = this.method,
version: String = this.version,
headers: Headers = this.headers,
remoteAddress: String = this.remoteAddress,
secure: Boolean = this.secure,
body: B = this.body): FakeRequest[B] = {
new FakeRequest[B](
method, uri, headers, body, remoteAddress, version, id, tags, secure
)
}
lazy val path = uri.split('?').take(1).mkString
lazy val queryString: Map[String, Seq[String]] =
play.core.parsers.FormUrlEncodedParser.parse(rawQueryString)
def (: (String, String)*): FakeRequest[A] = {
(headers = headers.replacenewHeaders: _*))
}
def withFlash(data: (String, String)*): FakeRequest[A] = {
withHeaders(play.api.http.HeaderNames.COOKIE ->
Cookies.mergeCookieHeader(headers.get(play.api.http.HeaderNames.COOKIE).getOrElse(""),
Seq(Flash.encodeAsCookie(new Flash(flash.data ++ data)))
)
)
}
def withCookies(cookies: Cookie*): FakeRequest[A] = {
withHeaders(play.api.http.HeaderNames.COOKIE ->
Cookies.mergeCookieHeader(headers.get(play.api.http.HeaderNames.COOKIE).getOrElse(""), cookies)
)
}
def withSession(newSessions: (String, String)*): FakeRequest[A] = {
withHeaders(play.api.http.HeaderNames.COOKIE ->
Cookies.mergeCookieHeader(headers.get(play.api.http.HeaderNames.COOKIE).getOrElse(""),
Seq(Session.encodeAsCookie(new Session(session.data ++ newSessions)))
)
)
}
def withFormUrlEncodedBody(data: (String, String)*): FakeRequest[AnyContentAsFormUrlEncoded] = {
_copy(body = AnyContentAsFormUrlEncoded(play.utils.OrderPreserving.groupBy(data.toSeq)(_._1)))
}
def certs = Future.successful(IndexedSeq.empty)
def withJsonBody(json: JsValue): FakeRequest[AnyContentAsJson] = {
_copy(body = AnyContentAsJson(json))
}
def withXmlBody(xml: NodeSeq): FakeRequest[AnyContentAsXml] = {
_copy(body = AnyContentAsXml(xml))
}
def withTextBody(text: String): FakeRequest[AnyContentAsText] = {
_copy(body = AnyContentAsText(text))
}
def withRawBody(bytes: Array[Byte]): FakeRequest[AnyContentAsRaw] = {
_copy(body = AnyContentAsRaw(RawBuffer(bytes.length, bytes)))
}
def withMultipartFormDataBody(form: MultipartFormData[TemporaryFile]) = {
_copy(body = AnyContentAsMultipartFormData(form))
}
def withBody[B](body: B): FakeRequest[B] = {
_copy(body = body)
}
def getMethod: String = method
}
object FakeRequest {
def apply(): FakeRequest[AnyContentAsEmpty.type] = {
FakeRequest("GET", "/", FakeHeaders(), AnyContentAsEmpty)
}
def apply(method: String, path: String): FakeRequest[AnyContentAsEmpty.type] = {
FakeRequest(method, path, FakeHeaders(), AnyContentAsEmpty)
}
def apply(call: Call): FakeRequest[AnyContentAsEmpty.type] = {
apply(call.method, call.url)
}
}
import play.api.Application
case class FakeApplication(
override val path: java.io.File = new java.io.File("."),
override val classloader: ClassLoader = classOf[FakeApplication].getClassLoader,
additionalPlugins: Seq[String] = Nil,
withoutPlugins: Seq[String] = Nil,
additionalConfiguration: Map[String, _ <: Any] = Map.empty,
withGlobal: Option[play.api.GlobalSettings] = None,
withRoutes: PartialFunction[(String, String), Handler] = PartialFunction.empty) extends Application {
private val app: Application = new GuiceApplicationBuilder()
.in(Environment(path, classloader, Mode.Test))
.global(withGlobal.orNull)
.configure(additionalConfiguration)
.bindings(
bind[FakePluginsConfig] to FakePluginsConfig(additionalPlugins, withoutPlugins),
bind[FakeRouterConfig] to FakeRouterConfig(withRoutes))
.overrides(
bind[Plugins].toProvider[FakePluginsProvider],
bind[Router].toProvider[FakeRouterProvider])
.build
override def mode: Mode.Mode = app.mode
override def global: GlobalSettings = app.global
override def configuration: Configuration = app.configuration
override def actorSystem: ActorSystem = app.actorSystem
override def plugins: Seq[Plugin.Deprecated] = app.plugins
override def requestHandler: HttpRequestHandler = app.requestHandler
override def errorHandler: HttpErrorHandler = app.errorHandler
override def stop(): Future[Unit] = app.stop()
override def injector: Injector = app.injector
}
private case class FakePluginsConfig(additionalPlugins: Seq[String], withoutPlugins: Seq[String])
private class FakePluginsProvider @Inject() (config: FakePluginsConfig, environment: Environment, injector: Injector) extends Provider[Plugins] {
lazy val get: Plugins = {
val pluginClasses = config.additionalPlugins ++ Plugins.loadPluginClassNames(environment).diff(config.withoutPlugins)
new Plugins(Plugins.loadPlugins(pluginClasses, environment, injector).toIndexedSeq)
}
}
private class FakeRoutes(
injected: PartialFunction[(String, String), Handler], fallback: Router) extends Router {
def documentation = fallback.documentation
val routes = new AbstractPartialFunction[RequestHeader, Handler] {
override def applyOrElse[A <: RequestHeader, B >: Handler](rh: A, default: A => B) =
injected.applyOrElse((rh.method, rh.path), (_: (String, String)) => default(rh))
def isDefinedAt(rh: RequestHeader) = injected.isDefinedAt((rh.method, rh.path))
} orElse new AbstractPartialFunction[RequestHeader, Handler] {
override def applyOrElse[A <: RequestHeader, B >: Handler](rh: A, default: A => B) =
fallback.routes.applyOrElse(rh, default)
def isDefinedAt(x: RequestHeader) = fallback.routes.isDefinedAt(x)
}
def withPrefix(prefix: String) = {
new FakeRoutes(injected, fallback.withPrefix(prefix))
}
}
private case class FakeRouterConfig(withRoutes: PartialFunction[(String, String), Handler])
private class FakeRouterProvider @Inject() (config: FakeRouterConfig, parent: RoutesProvider) extends Provider[Router] {
lazy val get: Router = new FakeRoutes(config.withRoutes, parent.get)
}