diff --git a/akka-security/pom.xml b/akka-security/pom.xml
index 1a3e831dc9..ca9b907fc5 100644
--- a/akka-security/pom.xml
+++ b/akka-security/pom.xml
@@ -60,6 +60,28 @@
lift-util
1.1-SNAPSHOT
+
+
+
+ org.scalatest
+ scalatest
+ 1.0
+ test
+
+
+ junit
+ junit
+ 4.5
+ test
+
+
+ org.mockito
+ mockito-all
+ 1.8.0
+ test
+
+
+
diff --git a/akka-security/src/test/scala/AllTest.scala b/akka-security/src/test/scala/AllTest.scala
new file mode 100644
index 0000000000..71708b63b3
--- /dev/null
+++ b/akka-security/src/test/scala/AllTest.scala
@@ -0,0 +1,15 @@
+package se.scalablesolutions.akka.security
+
+import junit.framework.Test
+import junit.framework.TestCase
+import junit.framework.TestSuite
+
+object AllTest extends TestCase {
+ def suite(): Test = {
+ val suite = new TestSuite("All Scala tests")
+ suite.addTestSuite(classOf[BasicAuthenticatorSpec])
+ suite
+ }
+
+ def main(args: Array[String]) = junit.textui.TestRunner.run(suite)
+}
\ No newline at end of file
diff --git a/akka-security/src/test/scala/SecuritySpec.scala b/akka-security/src/test/scala/SecuritySpec.scala
new file mode 100644
index 0000000000..024fe6ad0a
--- /dev/null
+++ b/akka-security/src/test/scala/SecuritySpec.scala
@@ -0,0 +1,74 @@
+/**
+ * Copyright (C) 2009 Scalable Solutions.
+ */
+
+package se.scalablesolutions.akka.security
+
+import config.ScalaConfig._
+
+import org.scalatest.Suite
+import org.scalatest.junit.JUnitSuite
+import org.scalatest.matchers.MustMatchers
+import org.scalatest.mock.MockitoSugar
+import org.mockito.Mockito._
+import org.mockito.Matchers._
+import org.junit.{Before, After, Test}
+import _root_.javax.ws.rs.core.{SecurityContext,Context,Response}
+import _root_.com.sun.jersey.spi.container.{ResourceFilterFactory,ContainerRequest,ContainerRequestFilter,ContainerResponse,ContainerResponseFilter,ResourceFilter}
+import _root_.com.sun.jersey.core.util.Base64
+
+class BasicAuthenticatorSpec extends junit.framework.TestCase with Suite with MockitoSugar with MustMatchers {
+
+ val authenticator = new BasicAuthenticator
+ authenticator.start
+
+ @Test def testChallenge = {
+ val req = mock[ContainerRequest]
+
+ val result: Response = (authenticator !? Authenticate(req, List("foo")))
+
+ // the actor replies with a challenge for the browser
+ result.getStatus must equal (Response.Status.UNAUTHORIZED.getStatusCode)
+ result.getMetadata.get("WWW-Authenticate").get(0).toString must startWith ("Basic")
+ }
+
+ @Test def testAuthenticationSuccess = {
+ val req = mock[ContainerRequest]
+ // fake a basic auth header -> this will authenticate the user
+ when(req.getHeaderValue("Authorization")).thenReturn("Basic " + new String(Base64.encode("foo:bar")))
+ // fake a request authorization -> this will authorize the user
+ when(req.isUserInRole("chef")).thenReturn(true)
+
+ val result: AnyRef = (authenticator !? Authenticate(req, List("chef")))
+
+ result must be (OK)
+ // the authenticator must have set a security context
+ verify(req).setSecurityContext(any[SecurityContext])
+ }
+
+ @Test def testUnauthorized = {
+ val req = mock[ContainerRequest]
+ // fake a basic auth header -> this will authenticate the user
+ when(req.getHeaderValue("Authorization")).thenReturn("Basic " + new String(Base64.encode("foo:bar")))
+ when(req.isUserInRole("chef")).thenReturn(false) // this will deny access
+
+ val result: Response = (authenticator !? Authenticate(req, List("chef")))
+
+ result.getStatus must equal (Response.Status.FORBIDDEN.getStatusCode)
+ // the authenticator must have set a security context
+ verify(req).setSecurityContext(any[SecurityContext])
+
+ }
+
+ class BasicAuthenticator extends BasicAuthenticationActor {
+
+ def verify(odc : Option[BasicCredentials]) : Option[UserInfo] = odc match {
+ case Some(dc) => Some(UserInfo("foo","bar","ninja" :: "chef" :: Nil))
+ case _ => None
+ }
+
+ override def realm = "test"
+
+ }
+}
+