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/12/06 23:45:03 UTC

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

Author: rhirsch
Date: Sun Dec  6 22:45:02 2009
New Revision: 887790

URL: http://svn.apache.org/viewvc?rev=887790&view=rev
Log:
[ESME-137] Update existing API2 methods: response conditions other than 200 and 403
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/main/scala/org/apache/esme/api/XMLHelper.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=887790&r1=887789&r2=887790&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 Sun Dec  6 22:45:02 2009
@@ -177,10 +177,13 @@
       future.get(60L * 1000L)
 
     val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] = 
-      for (act <- restActor.is ?~ "No REST actor";
+      for (act <- restActor.is ?~ S.?("base_rest_api_err_no_rest_actor");
 		   val ignore = act ! ListenFor(future, 0 seconds);
-           answer <- waitForAnswer ?~ "Didn't get an answer")
-      yield (200,Map(),Full(<messages>{answer.flatMap{ case (msg, reason) => msgToXml(msg) }}</messages>))
+	       answer <- waitForAnswer ?~ S.?("base_rest_api_err_no_answer")) 
+      yield { 
+        if(answer.isEmpty) (204,Map(),Empty)          
+        else (200,Map(),Full(<messages>{answer.flatMap{ case (msg, reason) => msgToXml(msg) }}</messages>))
+      }
 
     val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
       if(ret.isDefined) ret else Full((403,Map(),Empty))
@@ -199,7 +202,10 @@
 		length <- S.param("timeout").map(_.toInt * 1000);
         val ignore = act ! ListenFor(future, TimeSpan(length));
         answer <- waitForAnswer ?~ "Didn't get an answer")
-      yield (200,Map(),Full(<messages>{answer.flatMap{ case (msg, reason) => msgToXml(msg) }}</messages>))
+      yield {
+        if(answer.isEmpty) (204,Map(),Empty)          
+        else (200,Map(),Full(<messages>{answer.flatMap{ case (msg, reason) => msgToXml(msg) }}</messages>))
+      }
 
     val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
       if(ret.isDefined) ret else Full((403,Map(),Empty))
@@ -230,7 +236,7 @@
       for (user <- calcUser.map(_.id.is) ?~ S.?("base_rest_api_err_param_not_found", "User");
         msg <- S.param("message") ?~ S.?("base_rest_api_err_missing_param", "message"))
       yield {
-        val from: String = S.param("via") openOr "api"
+        val from: String = S.param("via") openOr "api2"
         val pool = for (poolName <- S.param("pool");
                         p <- AccessPool.findPool(poolName,
                         S.param("realm") openOr AccessPool.Native)
@@ -342,8 +348,8 @@
 
   def addTracking(): LiftResponse = {
     val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] = 
-      for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
-           toTrack <- (S.param("track") ?~ S.?("base_rest_api_err_missing_param", "track")) if toTrack.trim.length > 0)
+      for (user <- User.currentUser;
+           toTrack <- S.param("track") if toTrack.trim.length > 0)
       yield
         (200,Map(),Full(<track>{Tracking.create.user(user).regex(toTrack).save}</track>))
 
@@ -355,10 +361,10 @@
 
   def removeTracking(trackId: Box[String]): LiftResponse = {
     val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
-      for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
-           id <- trackId ?~ S.?("base_rest_api_err_missing_param", "id");
+      for (user <- User.currentUser;
+           id <- trackId;
            track <- Tracking.find(By(Tracking.id, id.toLong),
-                                  By(Tracking.user, user)) ?~ "Couldn't find tracking item")
+                                  By(Tracking.user, user)) ?~ S.?("base_rest_api_err_param_no_tracking"))
       yield {
         track.removed(true).save
         (200,Map(),Empty)
@@ -498,12 +504,18 @@
 
   def getConversation(conversationId: Box[String]): LiftResponse = {
     val ret: Box[Tuple3[Int,Map[String,String],Box[Elem]]] = 
-      for (user <- User.currentUser ?~ S.?("base_rest_api_err_not_logged_in");
-           id <- conversationId.map(toLong) ?~ S.?("base_rest_api_err_missing_param", "id"))
-      yield (200,Map(),Full(<conversation id={id.toString}>{
-        Message.findAndPrime(By(Message.conversation, id),
-                             OrderBy(Message.id, Ascending)).map(_.toXml)
-      }</conversation>))
+      for (user <- User.currentUser;
+           id <- conversationId.map(toLong))
+      yield {
+        val messages = 
+          Message.findAndPrime(By(Message.conversation, id),
+                               OrderBy(Message.id, Ascending))
+        
+        if(messages.isEmpty)
+          (404,Map(),Empty)
+        else
+          (200,Map(),Full(<conversation id={id.toString}>{messages.map(_.toXml)}</conversation>))
+      }
 
 	val r: Box[Tuple3[Int,Map[String,String],Box[Elem]]] =
 	  if(ret.isDefined) ret else Full((403,Map(),Empty))

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=887790&r1=887789&r2=887790&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 Sun Dec  6 22:45:02 2009
@@ -48,6 +48,7 @@
 
   implicit def rackResponse(in: Box[Tuple3[Int,Map[String,String],Box[Elem]]]): LiftResponse = in match {
     case Full((200,_,xml)) => buildResponse(true, Empty, xml openOr Text(""))
+    case Full((204,_,_)) => NoContentResponse()
     case Full((403,_,_)) => ForbiddenResponse()
     case Full((404,_,_)) => NotFoundResponse()
     case _ => InternalServerErrorResponse()   

Modified: incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/XMLHelper.scala
URL: http://svn.apache.org/viewvc/incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/XMLHelper.scala?rev=887790&r1=887789&r2=887790&view=diff
==============================================================================
--- incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/XMLHelper.scala (original)
+++ incubator/esme/trunk/server/src/main/scala/org/apache/esme/api/XMLHelper.scala Sun Dec  6 22:45:02 2009
@@ -43,12 +43,19 @@
   protected def userToXml(user: User): Elem =
 <user><id>{user.id.toString}</id><nickname>{user.niceName}</nickname><image>{user.image}</image><whole_name>{user.wholeName}</whole_name></user> 
 	
-  protected def msgToXml(msg: Message): Elem = 
-<message>
+  protected def msgToXml(msg: Message): Elem = { 
+    val replyToTag: Elem =
+      if(msg.conversation.defined_?) <replyto>{msg.conversation}</replyto>
+      else <replyto></replyto>
+
+    val ret: Elem = <message>
   <id>{msg.id.toString}</id>
   <date>{toInternetDate(msg.when.is)}</date>
   <source>{msg.source.sourceAttr.getOrElse(Text(""))}</source>
   <body>{msg.body}</body>
-  <tags>{msg.tags}</tags>
-</message>        
+  <tags>{msg.tags}</tags>{replyToTag}
+</message>
+
+   ret        
+  }
 }

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=887790&r1=887789&r2=887790&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 Sun Dec  6 22:45:02 2009
@@ -1,6 +1,6 @@
 /**
  * Copyright 2008-2009 WorldWide Conferencing, LLC
- * 
+ *
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
  * distributed with this work for additional information
@@ -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,10 +36,10 @@
 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                 
+import _root_.junit.framework.AssertionFailedError
 
 class Api2SpecsAsTest extends JUnit3(Api2Specs)
 object Api2SpecsRunner extends ConsoleRunner(Api2Specs)
@@ -48,58 +48,63 @@
   JettyTestServer.start
 
   val baseUrl = JettyTestServer.urlFor("/api2/")
-  
-  val session = new LiftSession(Helpers.randomString(20), "", Empty)
 
-  val theUser = S.initIfUninitted(session) {User.createAndPopulate.nickname("api_test").saveMe}
+  val session = new LiftSession(Helpers.randomString(20), "", Empty)    
+
+  val theUser = S.initIfUninitted(session) {User.createAndPopulate.nickname("api_test").saveMe}    
   val token = {
     val toke = AuthToken.create.user(theUser).saveMe
     toke.uniqueId.is
-  }     
+  }           
 
   val post_session = post("session", "token" -> token)
-  
+
+  def sleep(wait: Long): Box[Boolean] = {
+    Thread.sleep(wait)
+    Full(true)
+  }
+
   "API2" should {
-	"/session POST" in {  
-	  "Attempt to log in with a valid token should succeed with a 200 response" in {
-	    for{
-	      session <- post_session    
-	    } {
-	      (session.xml \ "session" \ "user" \ "id").text must be equalTo(theUser.id.toString)
-		  session.code must be equalTo 200
-	    } 
-	  }
-
-	  "Attempt to create session with an invalid token returns 403 response" in {
-	    for{
-	      session <- post("session", "token" -> "000000")
-	    } {                  
+    "/session POST" in {
+      "Attempt to log in with a valid token should succeed with a 200 response" in {
+        for{
+          session <- post_session
+        } {
+          (session.xml \ "session" \ "user" \ "id").text must be equalTo (theUser.id.toString)
+          session.code must be equalTo 200
+        }
+      }
+
+      "Attempt to create session with an invalid token returns 403 forbidden response" in {
+        for{
+          session <- post("session", "token" -> "000000")
+        } {
           session.code must be equalTo 403
-	    } 
-	  }
-	}
-	
-	"/session GET" in {
-	  "with valid session" in {
-	    for {
-	      session <- post_session
+        }
+      }
+    }
+
+    "/session GET" in {
+      "with valid session" in {
+        for{
+          session <- post_session
           session_response <- session.get("session")
-	    } {
-	      session_response.code must be equalTo 200
-	      ( session_response.xml \ "session" \ "user" \ "id").text must be equalTo(theUser.id.toString)
-	    }
-	  }
-	
-	  "with no session returns 404 (not found)" in {
-	    for(session_res <- get("session")) {
-	      session_res.code must be equalTo 404
-	    }
-	  }  
+        } {
+          session_response.code must be equalTo 200
+          (session_response.xml \ "session" \ "user" \ "id").text must be equalTo (theUser.id.toString)
+        }
+      }
+
+      "with no session returns 404 (not found)" in {
+        for (session_res <- get("session")) {
+          session_res.code must be equalTo 404
+        }
+      }
     }
 
     "/session DELETE" in {
       "with valid session" in {
-        for {
+        for{
           session <- post_session
           session_del_response <- session.delete("session")
           //session_response <- session.get("session")
@@ -109,16 +114,16 @@
         }
       }
 
-	  "with no session returns 404 (not found)" in {
-	    for(session_res <- delete("session")) {
-	      session_res.code must be equalTo 404
-	    }
-	  }
-    }	
+      "with no session returns 404 (not found)" in {
+        for (session_res <- delete("session")) {
+          session_res.code must be equalTo 404
+        }
+      }
+    }
 
     "/users GET" in {
-      "with valid session" in {     
-        for {
+      "with valid session" in {
+        for{
           session <- post_session
           users <- session.get("users")
         } {
@@ -126,337 +131,382 @@
         }
       }
 
-	  "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("users")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+      "with no session returns 403 (forbidden)" in {
+        for (session_res <- get("users")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/messages GET" in {
-      "with valid session" in {
-        for {
+      "with valid session and new messages" in {
+        for{
           session <- post_session
+          mess_res1 <- session.post("user/messages", "message" -> "test message") 
+          timeout <- sleep(2000)
           mess_res <- session.get("user/messages")
-        } {
+        } {    
           mess_res.code must be equalTo 200
         }
       }
 
-	  "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("user/messages")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+      "with no session returns 403 (forbidden)" in {
+        for (session_res <- get("user/messages")) {
+          session_res.code must be equalTo 403
+        }
+      }
+
+
+// Should be a 304, but this response type isn't implemented in Lift yet...
+      "when no new messages exist, returns 204 (no content)" in {
+        for (session <- post_session;
+             session_res1 <- session.get("user/messages");
+             session_res <- session.get("user/messages"))
+        {             
+          session_res.code must be equalTo 204
+        }                                                   
+      }
     }
 
     "/user/messages?history=10 GET" in {
       "with valid session" in {
-        for {
+        for{
           session <- post_session
           res <- session.get("user/messages?history=10")
-        } {
+        } {           
           res.code must be equalTo 200
-        }                     
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("user/messages?history=10")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+        for (session_res <- get("user/messages?history=10")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/messages?timeout=2 GET" in {
       "with valid session" in {
-        for {
-          sess <- post_session
+        for{
+          sess <- post_session   
+          mess_res1 <- sess.post("user/messages", "message" -> "test message")  
           res <- sess.get("user/messages?timeout=2")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("user/messages?timeout=2")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
-    } 
+        for (session_res <- get("user/messages?timeout=2")) {
+          session_res.code must be equalTo 403
+        }
+      }
+
+// Should be a 304, but this response type isn't implemented in Lift yet...
+	  "when no new messages exist, returns 204 (no content)" in {
+        for (session <- post_session;
+          session_res1 <- session.get("user/messages");
+          session_res <- session.get("user/messages?timeout=2"))
+        {             
+          session_res.code must be equalTo 204
+        }                                                   
+      }
+    }
 
     "/user/messages POST" in {
       "with valid session" in {
-        for {
+        for{
           session <- post_session
-          mess_res <- session.post("user/messages","message"->"test message")
+          mess_res <- session.post("user/messages", "message" -> "test message")
         } {
           mess_res.code must be equalTo 200
         }
       }
 
-	  "with no session returns 403 (forbidden)" in {
-	    for(session_res <- post("user/messages","message"->"test message")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+      "with no session returns 403 (forbidden)" in {
+        for (session_res <- post("user/messages", "message" -> "test message")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/followees GET" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.get("user/followees")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("user/followees")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+        for (session_res <- get("user/followees")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/followees POST" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.post("user/followees", "userId" -> "1")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(res <- post("user/followees", "userId" -> "1")) {
-	      res.code must be equalTo 403
-	    }
-	  }
-    } 
+        for (res <- post("user/followees", "userId" -> "1")) {
+          res.code must be equalTo 403
+        }
+      }
+    }
 
     "/user/followers GET" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.get("user/followers")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("user/followers")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+        for (session_res <- get("user/followers")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/tracks GET" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.get("user/tracks")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(session_res <- get("user/tracks")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+        for (session_res <- get("user/tracks")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/tracks POST" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
-          res <- sess.post("user/tracks","track" -> ".*")
+          res <- sess.post("user/tracks", "track" -> ".*")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(session_res <- post("user/tracks","track" -> ".*")) {
-	      session_res.code must be equalTo 403
-	    }
-	  }
+        for (session_res <- post("user/tracks", "track" -> ".*")) {
+          session_res.code must be equalTo 403
+        }
+      }
     }
 
-/*
- *   "/user/tracks/TRACKID DELETE" in {
- *     "with valid session" in {
- *       for {
- *         sess <- post_session
- *         create_track <- sess.post("user/tracks","track"->".*")
- *         res <- sess.delete("user/tracks/1")
- *       } {
- *         res.code must be equalTo 200
- *       }          
- *     }
- *
- *     "with no session returns 403 (forbidden)" in {
- *       for(session_res <- delete("user/tracks/1")) {
- *         session_res.code must be equalTo 403
- *       }
- *     }
- *   } 
- */
+    /*
+    *   "/user/tracks/TRACKID DELETE" in {
+    *     "with valid session" in {
+    *       for {
+    *         sess <- post_session
+    *         create_track <- sess.post("user/tracks","track"->".*")
+    *         res <- sess.delete("user/tracks/1")
+    *       } {
+    *         res.code must be equalTo 200
+    *       }
+    *     }
+    *
+    *     "with no session returns 403 (forbidden)" in {
+    *       for(session_res <- delete("user/tracks/1")) {
+    *         session_res.code must be equalTo 403
+    *       }
+    *     }
+    *   }
+    */
 
     "/user/actions GET" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.get("user/actions")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(res <- get("user/actions")) {
-	      res.code must be equalTo 403
-	    }
-	  }
+        for (res <- get("user/actions")) {
+          res.code must be equalTo 403
+        }
+      }
     }
 
     "/user/actions POST" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.post("user/actions",
-                           "name"->"Test action",
-                           "test"->"every 5 mins",
-                           "action"->"rss:http://blog.com/feed.rss")
-        } {
-          res.code must be equalTo 200
-        }          
+            "name" -> "Test action",
+            "test" -> "every 5 mins",
+            "action" -> "rss:http://blog.com/feed.rss")
+        } {
+          res.code must be equalTo 200
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(res <- post("user/actions",
-	                    "name"->"Test action",
-	                    "test"->"every 5 mins",
-	                    "action"->"rss:http://blog.com/feed.rss")) {
-	      res.code must be equalTo 403
-	    }
-	  }
-    }   
-
-/*
- *    "/user/actions/ACTIONID PUT" in {
- *     "with valid session" in {
- *       for {
- *         sess <- post_session
- *         res <- sess.put("user/actions/1","enabled"->0)
- *       } {
- *         res.code must be equalTo 200
- *       }          
- *     }
- *
- *     "with no session returns 403 (forbidden)" in {
- *       for(res <- post("user/actions/1","enabled"->0)) {
- *         res.code must be equalTo 403
- *       }
- *     }
- *   }
- */
+        for (res <- post("user/actions",
+          "name" -> "Test action",
+          "test" -> "every 5 mins",
+          "action" -> "rss:http://blog.com/feed.rss")) {
+          res.code must be equalTo 403
+        }
+      }
+    }
 
-/*
- *   "/user/actions/ACTIONID DELETE" in {
- *     "with valid session" in {
- *       for {
- *         sess <- post_session
- *         res <- sess.delete("user/actions/1")
- *       } {
- *         res.code must be equalTo 200
- *       }          
- *     }
- *
- *     "with no session returns 403 (forbidden)" in {
- *       for(res <- delete("user/actions/1")) {
- *         res.code must be equalTo 403
- *       }
- *     }
- *   } 
- */
+    /*
+    *    "/user/actions/ACTIONID PUT" in {
+    *     "with valid session" in {
+    *       for {
+    *         sess <- post_session
+    *         res <- sess.put("user/actions/1","enabled"->0)
+    *       } {
+    *         res.code must be equalTo 200
+    *       }
+    *     }
+    *
+    *     "with no session returns 403 (forbidden)" in {
+    *       for(res <- post("user/actions/1","enabled"->0)) {
+    *         res.code must be equalTo 403
+    *       }
+    *     }
+    *   }
+    */
+
+    /*
+    *   "/user/actions/ACTIONID DELETE" in {
+    *     "with valid session" in {
+    *       for {
+    *         sess <- post_session
+    *         res <- sess.delete("user/actions/1")
+    *       } {
+    *         res.code must be equalTo 200
+    *       }
+    *     }
+    *
+    *     "with no session returns 403 (forbidden)" in {
+    *       for(res <- delete("user/actions/1")) {
+    *         res.code must be equalTo 403
+    *       }
+    *     }
+    *   }
+    */
 
+
+// This is very ... shall we say ... brittle
     "conversations/CONVERSATIONID GET" in {
       "with valid session" in {
-        for {
-          sess <- post_session
-          res <- sess.get("conversations/1")
+        for{
+          sess <- post_session 
+          mess_res <- sess.post("user/messages", "message"->"test")
+          wait <- sleep(1000)
+          messages <- sess.get("user/messages")                    
+          mess_res <- sess.post("user/messages",
+                                "message" -> "test_convo",
+                                "replyto" -> 42)
+          wait2 <- sleep(1000)
+          messages2 <- sess.get("user/messages")
+          res <- sess.get("conversations/42")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(res <- get("conversations/1")) {
-	      res.code must be equalTo 403
-	    }
-	  }
+        for (res <- get("conversations/1")) {
+          res.code must be equalTo 403
+        }
+      }
+
+      "with an invalid conversation ID return a 404 (not found)" in {
+      	for{
+          sess <- post_session
+          res <- sess.get("conversations/10000")
+        } {
+          res.code must be equalTo 404
+        }
+      } 
     }
 
     "/pools GET" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
           res <- sess.get("pools")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(res <- get("pools")) {
-	      res.code must be equalTo 403
-	    }
-	  }
+        for (res <- get("pools")) {
+          res.code must be equalTo 403
+        }
+      }
     }
 
     "/pools POST" in {
       "with valid session" in {
-        for {
+        for{
           sess <- post_session
-          res <- sess.post("pools","poolName"->"test_pool")
+          res <- sess.post("pools", "poolName" -> "test_pool")
         } {
           res.code must be equalTo 200
-        }          
+        }
       }
 
       "with no session returns 403 (forbidden)" in {
-	    for(res <- post("pools","poolName"->"test_pool")) {
-	      res.code must be equalTo 403
-	    }
-	  }
-    }  
+        for (res <- post("pools", "poolName" -> "test_pool")) {
+          res.code must be equalTo 403
+        }
+      }
+    }
 
     "/pools/POOLID/users POST" in {
 
-/*
- *     "with valid session" in {
- *       for {
- *         sess <- post_session
- *         res <- sess.post("pools/1/users",{"realm"->"test_realm";
- *                                                "userId"->1;
- *                                                "permission"->"Write"})
- *       } {
- *         res.code must be equalTo 200
- *       }          
- *     }
- */
-
-      "with no session returns 403 (forbidden)" in {
-	    for(res <- post("pools/1/users",{"realm"->"test_realm";
-                                                 "userId"->2;
-                                                 "permission"->"Write"})) {
-	      res.code must be equalTo 403
-	    }
-	  }
-    }        
-  }  
+      /*
+      *     "with valid session" in {
+      *       for {
+      *         sess <- post_session
+      *         res <- sess.post("pools/1/users",{"realm"->"test_realm";
+      *                                                "userId"->1;
+      *                                                "permission"->"Write"})
+      *       } {
+      *         res.code must be equalTo 200
+      *       }
+      *     }
+      */
+
+      "with no session returns 403 (forbidden)" in {
+        for (res <- post("pools/1/users", {
+          "realm" -> "test_realm";
+          "userId" -> 2;
+          "permission" -> "Write"
+        })) {
+          res.code must be equalTo 403
+        }
+      }
+    }
+  }
 }
\ No newline at end of file