Skip to content

Commit c4ed0be

Browse files
committed
Merge pull request jaliss#345 from jeantil/master
jaliss#124 Add test helpers for unit and integration testing of securesocial controllers
2 parents 7d41a54 + 77ce2f9 commit c4ed0be

9 files changed

+166
-1
lines changed

samples/scala/demo/project/Build.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ object ApplicationBuild extends Build {
88
val appVersion = "1.0"
99

1010
val appDependencies = Seq(
11-
"ws.securesocial" %% "securesocial" % "master-SNAPSHOT"
11+
"ws.securesocial" %% "securesocial" % "master-SNAPSHOT",
12+
"ws.securesocial" %% "ss-testkit" % "master-SNAPSHOT" % "test"
1213
)
1314
val main = play.Project(appName, appVersion, appDependencies).settings(
1415
resolvers += Resolver.sonatypeRepo("snapshots")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import play.api.test.{FakeRequest, WithApplication, FakeApplication, PlaySpecification}
2+
3+
class ApplicationScenario extends PlaySpecification {
4+
def app = FakeApplication(additionalPlugins = Seq("securesocial.testkit.AlwaysValidIdentityProvider"))
5+
"A logged in user can view the index" in new WithApplication(app) {
6+
//Given
7+
val creds1 = cookies(route(FakeRequest(POST, "/authenticate/naive").withTextBody("user")).get)
8+
//When
9+
val Some(response)=route(FakeRequest(GET, "/").withCookies(creds1.get("id").get))
10+
11+
//Then
12+
status(response) must equalTo(OK)
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import controllers.Application
2+
import org.specs2.matcher.ShouldMatchers
3+
import play.api.http.HeaderNames
4+
import play.api.mvc.{Request, AnyContent}
5+
import play.api.test.{PlaySpecification, FakeApplication, FakeRequest}
6+
import securesocial.testkit.WithLoggedUser
7+
8+
class ApplicationSpec extends PlaySpecification with ShouldMatchers {
9+
import WithLoggedUser._
10+
def minimalApp = FakeApplication(withoutPlugins=excludedPlugins,additionalPlugins = includedPlugins)
11+
"Access secured index " in new WithLoggedUser(minimalApp) {
12+
13+
val req: Request[AnyContent] = FakeRequest().
14+
withHeaders((HeaderNames.CONTENT_TYPE, "application/x-www-form-urlencoded")).
15+
withCookies(cookie) // Fake cookie from the WithloggedUser trait
16+
17+
val result = Application.index.apply(req)
18+
19+
val actual: Int= status(result)
20+
actual must be equalTo OK
21+
}
22+
}

test-kit/project/Build.scala

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import sbt._
2+
import Keys._
3+
4+
object ApplicationBuild extends Build {
5+
6+
val appName = "ss-testkit"
7+
val appVersion = "master-SNAPSHOT"
8+
val appOrganization = "ws.securesocial"
9+
val dependencies = Seq(
10+
"ws.securesocial" %% "securesocial" % "master-SNAPSHOT",
11+
"org.scalacheck" %% "scalacheck" % "1.11.1",
12+
"com.typesafe.play" %% "play-test" % "2.2.0",
13+
"org.mockito" % "mockito-all" % "1.9.5"
14+
)
15+
val main = sbt.Project(appName, file(".") ).settings(
16+
resolvers += Resolver.sonatypeRepo("snapshots")
17+
, libraryDependencies ++= dependencies
18+
, version := appVersion
19+
, organization := appOrganization
20+
)
21+
}

test-kit/project/build.properties

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sbt.version=0.13.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package securesocial.testkit
2+
3+
import play.api.Logger
4+
import securesocial.core._
5+
import play.api.mvc.{Result, Request}
6+
import securesocial.core.IdentityId
7+
8+
class AlwaysValidIdentityProvider(app:play.api.Application) extends IdentityProvider(app){
9+
val logger = Logger("securesocial.stubs.AlwaysValidIdentityProvider")
10+
def authMethod: AuthenticationMethod = AuthenticationMethod("naive")
11+
12+
13+
override def doAuth()(implicit request: Request[play.api.mvc.AnyContent]): Either[Result, SocialUser] ={
14+
val userId = request.body.toString
15+
val r =Right(SocialUserGenerator.socialUserGen(IdentityId(userId, id), authMethod).sample.get)
16+
r
17+
}
18+
19+
20+
def fillProfile(user: SocialUser): SocialUser = {
21+
user
22+
}
23+
24+
def id: String = "naive"
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package securesocial.testkit
2+
3+
import securesocial.core.{Authenticator, AuthenticatorStore}
4+
import play.api.Application
5+
6+
class FakeAuthenticatorStore(app:Application) extends AuthenticatorStore(app) {
7+
var authenticator:Option[Authenticator] = None
8+
def save(authenticator: Authenticator): Either[Error, Unit] = {
9+
this.authenticator=Some(authenticator)
10+
Right()
11+
}
12+
def find(id: String): Either[Error, Option[Authenticator]] = {
13+
Some(authenticator.filter(_.id == id)).toRight(new Error("no such authenticator"))
14+
}
15+
def delete(id: String): Either[Error, Unit] = {
16+
this.authenticator=None
17+
Right()
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package securesocial.testkit
2+
3+
import securesocial.core.{SocialUser, AuthenticationMethod, IdentityId}
4+
import org.scalacheck.Gen
5+
6+
object SocialUserGenerator {
7+
val nameGen = for {
8+
head <- Gen.alphaUpperChar
9+
size<- Gen.choose(1,10)
10+
tail <- Gen.listOfN(size,Gen.alphaLowerChar)
11+
} yield (head +: tail).mkString("")
12+
13+
def identityIdGen = for{
14+
pid <- nameGen
15+
uid <- nameGen
16+
} yield IdentityId(uid, pid)
17+
18+
def identityId = identityIdGen.sample.get
19+
20+
def authMethodGen = Gen.oneOf(AuthenticationMethod.OAuth1,AuthenticationMethod.OAuth2,AuthenticationMethod.OpenId,AuthenticationMethod.UserPassword)
21+
22+
def authMethod = authMethodGen.sample.get
23+
24+
def socialUserGen(id:IdentityId=identityId,authMethod: AuthenticationMethod=authMethod)= for{
25+
firstName <- nameGen
26+
lastName <- nameGen
27+
email = s"${firstName.head}.$lastName@example.com"
28+
}yield SocialUser(id, firstName, lastName, s"$firstName $lastName",Some(email),None, authMethod,None, None, None)
29+
30+
def socialUser(id:IdentityId=identityId,authMethod: AuthenticationMethod=authMethod)=socialUserGen(id, authMethod).sample.get
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package securesocial.testkit
2+
3+
import securesocial.core.{Authenticator, Identity, UserService}
4+
import org.specs2.execute.{Result, AsResult}
5+
import play.api.test.{WithApplication, FakeApplication}
6+
import org.specs2.mock.Mockito
7+
8+
abstract class WithLoggedUser(override val app: FakeApplication = FakeApplication(),val identity:Option[Identity]=None) extends WithApplication(app) with Mockito {
9+
10+
lazy val user = identity getOrElse SocialUserGenerator.socialUser()
11+
lazy val mockUserService=mock[UserService]
12+
13+
def cookie=Authenticator.create(user) match {
14+
case Right(authenticator) => authenticator.toCookie
15+
case _ => throw new IllegalArgumentException("Your FakeApplication _must_ configure a working AuthenticatorStore")
16+
}
17+
18+
override def around[T: AsResult](t: =>T): Result = super.around {
19+
mockUserService.find(user.identityId) returns Some(user)
20+
UserService.setService(mockUserService)
21+
t
22+
}
23+
}
24+
25+
object WithLoggedUser{
26+
val excludedPlugins = List( "securesocial.core.DefaultAuthenticatorStore" )
27+
val includedPlugins = List( "securesocial.testkit.FakeAuthenticatorStore" )
28+
def minimalApp = FakeApplication(withoutPlugins=excludedPlugins,additionalPlugins = includedPlugins)
29+
}
30+
31+

0 commit comments

Comments
 (0)