You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@esme.apache.org by rh...@apache.org on 2009/11/23 14:46:36 UTC

svn commit: r883340 - in /incubator/esme/trunk/server/src: main/scala/org/apache/esme/api/API2.scala main/scala/org/apache/esme/api/ApiHelper.scala test/scala/org/apache/esme/api/API2Test.scala

Author: rhirsch
Date: Mon Nov 23 13:46:35 2009
New Revision: 883340

URL: http://svn.apache.org/viewvc?rev=883340&view=rev
Log:
[ESME-14] Redesign, rework, write unit tests for, and fully document API
Patch from Ethan Jewett applied

Modified:
    incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala
    incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala
    incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala

Modified: incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala?rev=883340&r1=883339&r2=883340&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala (original)
+++ incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/API2.scala Mon Nov 23 13:46:35 2009
@@ -59,9 +59,11 @@
 
 // Document the fact that tag is no longer a parameter here                   
     case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest)
- 		if S.param("timeout").isDefined => waitForMsgs 
-    case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest) => allUserMsgs
-// Document the new method for getting messages belonging to a particular tag
+ 	  if S.param("timeout").isDefined => waitForMsgs
+    case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest)
+      if S.param("history").isDefined => allUserMsgs   
+    case Req("api2" :: "user" :: "messages" :: Nil, _, GetRequest) => getNewMsgs
+// Document the new method for getting messages belonging to a particular tag      
     case Req("api2" :: "user" :: "messages" :: "tag" :: tag :: Nil, _, GetRequest)
   		    => () => allUserMsgs(tag)
 // Possibly deprecate and move to api2/messages or api2/pools/poolName/messages
@@ -117,12 +119,11 @@
 
   def addSession(): LiftResponse = {
     val r: Box[Elem] = if (User.loggedIn_?) Empty else
-    for (token <- S.param("token") ?~ S.?("base_rest_api_err_missing_param", "token");
+    for{ token <- S.param("token")
          auth <- AuthToken.find(By(AuthToken.uniqueId, token))
-         ?~ "Token not found";
-         user <- auth.user.obj;
+         user <- auth.user.obj
          session <- S.session
-    ) yield {
+    } yield {
       User.logUserIn(user)
       val myActor = buildActor(user.id)
       restActor(Full(myActor))
@@ -149,7 +150,8 @@
   def allUserMsgs(): LiftResponse = {
     val r: Box[Elem] = 
       for (user <- calcUser ?~  S.?("base_rest_api_err_param_not_found", "User");
-        val lst = Mailbox.mostRecentMessagesFor(user.id, 40))
+		val num = S.param("history").map(_.toInt) openOr 40;
+        val lst = Mailbox.mostRecentMessagesFor(user.id, num))
       yield {
 		<messages>{lst.flatMap{ case (msg, _, _) => msgToXml(msg)}}</messages>
 	  }
@@ -157,6 +159,37 @@
     r
   }
 
+  def getNewMsgs(): LiftResponse = {
+    val future = new LAFuture[List[(Message, MailboxReason)]]()
+  
+    def waitForAnswer: Box[List[(Message, MailboxReason)]] = 
+      future.get(60L * 1000L)
+
+    val r: Box[NodeSeq] = 
+      for (act <- restActor.is ?~ "No REST actor";
+		   val ignore = act ! ListenFor(future, 0 seconds);
+           answer <- waitForAnswer ?~ "Didn't get an answer")
+      yield answer.flatMap{ case (msg, reason) => msgToXml(msg) }
+
+    r
+  } 
+
+  def waitForMsgs(): LiftResponse = {
+    val future = new LAFuture[List[(Message, MailboxReason)]]()
+    
+    def waitForAnswer: Box[List[(Message, MailboxReason)]] = 
+      future.get(6L * 60L * 1000L)
+
+    var r: Box[NodeSeq] = 
+    for (act <- restActor.is ?~ "No REST actor";
+		 length <- S.param("timeout").map(_.toInt * 1000);
+         val ignore = act ! ListenFor(future, TimeSpan(length));
+         answer <- waitForAnswer ?~ "Didn't get an answer")
+    yield answer.flatMap{ case (msg, reason) => msgToXml(msg) }
+
+    r
+  }
+
   def allUserMsgs(tag: String): LiftResponse = {
 	val r: Box[Elem] =
       for (tagName <- Box(List(tag));
@@ -368,21 +401,6 @@
     ret
   }
 
-  def waitForMsgs(): LiftResponse = {
-    val future = new LAFuture[List[(Message, MailboxReason)]]()
-    
-    def waitForAnswer: Box[List[(Message, MailboxReason)]] = 
-      future.get(6L * 60L * 1000L)
-
-    var r: Box[NodeSeq] = 
-    for (act <- restActor.is ?~ "No REST actor";
-         val ignore = act ! ListenFor(future, 5 minutes);
-         answer <- waitForAnswer ?~ "Didn't get an answer")
-    yield answer.flatMap{ case (msg, reason) => msgToXml(msg) }
-
-    r
-  }
-
   private def findAction(actionId: Box[String]): Box[Action] =
   	for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
          id <- actionId ?~ S.?("base_rest_api_err_missing_param", "id");
@@ -436,15 +454,15 @@
       
       case ListenFor(who, len) =>
         msgs match {
-            case Nil =>
-              listener.foreach(_.satisfy(Nil))
-              listener = Full(who)
-              ActorPing.schedule(this, ReleaseListener, len)
+          case Nil =>
+            listener.foreach(_.satisfy(Nil))
+            listener = Full(who)
+            ActorPing.schedule(this, ReleaseListener, len)
              
-            case xs =>
-              who.satisfy(xs)
-              msgs = Nil
-              listener = Empty
+          case xs =>
+            who.satisfy(xs)
+            msgs = Nil
+            listener = Empty
         }
     }
   }
@@ -453,7 +471,7 @@
   private case class StartUp(userId: Long)
   private case object ByeBye
   private case class ListenFor(who: LAFuture[List[(Message, MailboxReason)]],
-			       howLong: TimeSpan)
+			       howLong: TimeSpan)                                  
   private case object ReleaseListener       
 }                                                          
 

Modified: incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala?rev=883340&r1=883339&r2=883340&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala (original)
+++ incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/ApiHelper.scala Mon Nov 23 13:46:35 2009
@@ -83,9 +83,14 @@
    * Build the Response based on the body 
    */  
   protected def buildResponse(success: Boolean, msg: Box[NodeSeq],  
-                            body: NodeSeq): LiftResponse =  
-  XmlResponse(createTag(body)) 
-
+                            body: NodeSeq): LiftResponse = {
+    if(success) {
+      XmlResponse(createTag(body))
+    } else {
+      XmlResponse(createTag(body))  // Need to return a 401 response here
+    }
+  }  
+  
   protected def buildResponseFromElem(success: Boolean, msg: Box[NodeSeq], body: Elem): LiftResponse = {
   	XmlResponse(createTag(body))                                                                                   
   }

Modified: incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala?rev=883340&r1=883339&r2=883340&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala (original)
+++ incubator/esme/trunk/server/src/test/scala/org/apache/esme/api/API2Test.scala Mon Nov 23 13:46:35 2009
@@ -19,13 +19,13 @@
  * under the License.
  */
 
-package org.apache.esme.api
+package org.apache.esme.api 
 
 import org.specs._
 import org.specs.runner.JUnit3
 import org.specs.runner.ConsoleRunner
 import net.liftweb.util._
-import net.liftweb.common._
+import net.liftweb.common._ 
 import org.specs.matcher._
 import Helpers._
 import net.sourceforge.jwebunit.junit.WebTester
@@ -36,7 +36,7 @@
 import org.apache.esme._
 import model._
 import net.liftweb.http._
-import testing.{ReportFailure, TestKit, HttpResponse, TestFramework}
+import testing.{ReportFailure, TestKit, HttpResponse, TestFramework}  
 
 import net.sourceforge.jwebunit.junit.WebTester
 import _root_.junit.framework.AssertionFailedError                 
@@ -48,31 +48,43 @@
   JettyTestServer.start
 
   val baseUrl = JettyTestServer.urlFor("")
-
-  implicit val reportError = new ReportFailure {
-    def fail(msg: String): Nothing = Api2Specs.this.fail(msg)
-  }
   
-    def shouldnt(f: => Unit): Unit =
-    try {
-      val x = f
-      fail("Shouldn't succeed")
-    } catch {
-      case _ => ()
-    }
-                         
-  "allUsers" should {
-    "have a response code of 200" in {
-      API2.allUsers().toResponse.code must be equalTo(200)
+  val theUser = User.createAndPopulate.nickname("api_test").saveMe
+  val token = {
+    val toke = AuthToken.create.user(theUser).saveMe
+    toke.uniqueId.is
+  }                
+  
+  "API2" should {
+	"Login with a valid token results in a 200 response and a proper response body" in {
+      for{
+        session <- post("/api2/session", "token" -> token)    
+      } {
+        (session.xml \ "session" \ "user" \ "id").text must be equalTo(theUser.id.toString)
+		session.code must be equalTo(200)
+      }
     }
 
-	"return a node listing all users" in {                    
-	  API2.allUsers().toResponse.toString must include(
-"""<api_response><users><user><id>1</id><nickname>hash</nickname><image>None</image><whole_name>hash</whole_name></user></users></api_response>"""
-	  )                                         
-	}
-  }
+	"Attempt to create session with an invalid token returns 400 response" in {
+      for{
+        session <- post("/api2/session", "token" -> "0000000")
+      } {                   
+		session.code must be equalTo(400)
+      }
+    }
 
-                                    
+    "/users" in {
+      "Valid session" in {     
+        "have a response code of 200" in {
+          for {
+            session <- post("/api2/session", "token" -> token)
+            users <- session.get("/api2/users")
+          } {
+            users.code must be equalTo(200)
+          }
+        }
+	  }                
+    }
+  }                                    
 }
  
\ No newline at end of file