Merge branch 'release-0.5.0'
diff --git a/lib/predictionio/client.rb b/lib/predictionio/client.rb
index ac83e76..ba3a2c8 100644
--- a/lib/predictionio/client.rb
+++ b/lib/predictionio/client.rb
@@ -37,15 +37,15 @@
   # == Special Handling of Some Optional Arguments
   # Some optional arguments have additional special handling:
   # - For all requests that accept "itypes" as input, the value can be supplied as either an Array of String's, or a comma-delimited String.
-  # - For all requests that accept "latlng" as input, they will also accept "latitude" and "longitude".
-  #   When these are supplied, they will override any existing "latlng" value.
-  # - All time arguments (e.g. t, startT, endT, etc) can be supplied as either a Time or Float object.
+  # - For all requests that accept "pio_latlng" as input, they will also accept "pio_latitude" and "pio_longitude".
+  #   When these are supplied, they will override any existing "pio_latlng" value.
+  # - All time arguments (e.g. t, pio_startT, pio_endT, etc) can be supplied as either a Time or Float object.
   #   When supplied as a Float, the SDK will interpret it as a UNIX UTC timestamp in seconds.
   #   The SDK will automatically round to the nearest millisecond, e.g. 3.14159 => 3.142.
   #
   # == Installation
-  # Download the PredictionIO Ruby Gem from http://prediction.io
-  #     gem install predictionio-0.1.0.gem
+  # The easiest way is to use RubyGems:
+  #     gem install predictionio-0.5.0.gem
   #
   # == Synopsis
   # The recommended usage of the SDK is to fire asynchronous requests as early as you can in your code,
@@ -79,26 +79,28 @@
   #       log_and_email_error(...)
   #     end
   #
-  # === Import a User Action (View) form Your App (with synchronous/blocking requests)
+  # === Import a User Action (Rate) from Your App (with synchronous/blocking requests)
   #     # PredictionIO call to record the view action
   #     begin
-  #       result = client.user_view_item(4, 15)
+  #       client.identify("foouser")
+  #       result = client.record_action_on_item("rate", "baritem", "pio_rate" => 4)
   #     rescue U2IActionNotCreatedError => e
   #       ...
   #     end
   #
   # === Retrieving Top N Recommendations for a User
   #     # PredictionIO call to get recommendations
-  #     response = client.aget_recommendation(4, 10)
+  #     client.identify("foouser")
+  #     response = client.aget_itemrec_top_n("barengine", 10)
   #
   #     #
   #     # work you need to do for the page (rendering, db queries, etc)
   #     #
   #
   #     begin
-  #       result = client.get_recommendations(response)
+  #       result = client.get_itemrec_top_n(response)
   #       # display results, store results, or your other work...
-  #     rescue RecommendationsNotFoundError => e
+  #     rescue ItemRecNotFoundError => e
   #       # graceful error handling
   #     end
 
@@ -113,6 +115,9 @@
     # Only JSON is currently supported as API response format.
     attr_accessor :apiformat
 
+    # The UID used for recording user-to-item actions and retrieving recommendations.
+    attr_accessor :apiuid
+
     # Raised when a user is not created after a synchronous API call.
     class UserNotCreatedError < StandardError; end
 
@@ -171,10 +176,10 @@
     # See also #create_user.
     def acreate_user(uid, params = {})
       rparams = params
-      rparams["appkey"] = @appkey
-      rparams["uid"] = uid
-      if params["latitude"] != nil && params["longitude"] != nil then
-        rparams["latlng"] = "#{params["latitude"]},#{params["longitude"]}"
+      rparams["pio_appkey"] = @appkey
+      rparams["pio_uid"] = uid
+      if params["pio_latitude"] != nil && params["pio_longitude"] != nil then
+        rparams["pio_latlng"] = "#{params["pio_latitude"]},#{params["pio_longitude"]}"
       end
 
       @http.apost(PredictionIO::AsyncRequest.new(versioned_path("/users.#{@apiformat}"), rparams))
@@ -191,7 +196,6 @@
     def create_user(*args)
       uid_or_res = args[0]
       if uid_or_res.is_a?(PredictionIO::AsyncResponse) then
-        uid = uid_or_res.request.params["uid"]
         response = uid_or_res.get
       else
         uid = uid_or_res
@@ -219,8 +223,8 @@
     # See also #get_user.
     def aget_user(uid)
       @http.aget(PredictionIO::AsyncRequest.new(versioned_path("/users/#{uid}.#{@apiformat}"),
-                                            "appkey" => @appkey,
-                                            "uid" => uid))
+                                                "pio_appkey" => @appkey,
+                                                "pio_uid" => uid))
     end
 
     # :category: Synchronous Methods
@@ -243,12 +247,10 @@
       end
       if response.is_a?(Net::HTTPOK) then
         res = JSON.parse(response.body)
-        ct = Rational(res["ct"], 1000)
-        res["ct"] = Time.at(ct)
-        if res["latlng"] != nil then
-          latlng = res["latlng"]
-          res["latitude"] = latlng[0]
-          res["longitude"] = latlng[1]
+        if res["pio_latlng"] != nil then
+          latlng = res["pio_latlng"]
+          res["pio_latitude"] = latlng[0]
+          res["pio_longitude"] = latlng[1]
         end
         res
       else
@@ -269,8 +271,8 @@
     # See also #delete_user.
     def adelete_user(uid)
       @http.adelete(PredictionIO::AsyncRequest.new(versioned_path("/users/#{uid}.#{@apiformat}"),
-                                               "appkey" => @appkey,
-                                               "uid" => uid))
+                                                   "pio_appkey" => @appkey,
+                                                   "pio_uid" => uid))
     end
 
     # :category: Synchronous Methods
@@ -305,21 +307,21 @@
     # See also #create_item.
     def acreate_item(iid, itypes, params = {})
       rparams = params
-      rparams["appkey"] = @appkey
-      rparams["iid"] = iid
+      rparams["pio_appkey"] = @appkey
+      rparams["pio_iid"] = iid
       begin
-        rparams["itypes"] = itypes.join(",")
+        rparams["pio_itypes"] = itypes.join(",")
       rescue Exception
-        rparams["itypes"] = itypes
+        rparams["pio_itypes"] = itypes
       end
-      if params["latitude"] != nil && params["longitude"] != nil then
-        rparams["latlng"] = "#{params["latitude"]},#{params["longitude"]}"
+      if params["pio_latitude"] != nil && params["pio_longitude"] != nil then
+        rparams["pio_latlng"] = "#{params["pio_latitude"]},#{params["pio_longitude"]}"
       end
-      if params["startT"] != nil then
-        rparams["startT"] = ((params["startT"].to_r) * 1000).round(0).to_s
+      if params["pio_startT"] != nil then
+        rparams["pio_startT"] = ((params["pio_startT"].to_r) * 1000).round(0).to_s
       end
-      if params["endT"] != nil then
-        rparams["endT"] = ((params["endT"].to_r) * 1000).round(0).to_s
+      if params["pio_endT"] != nil then
+        rparams["pio_endT"] = ((params["pio_endT"].to_r) * 1000).round(0).to_s
       end
 
       @http.apost(PredictionIO::AsyncRequest.new(versioned_path("/items.#{@apiformat}"), rparams))
@@ -362,8 +364,8 @@
     # See also #get_item.
     def aget_item(iid)
       @http.aget(PredictionIO::AsyncRequest.new(versioned_path("/items/#{iid}.#{@apiformat}"),
-                                           "appkey" => @appkey,
-                                           "iid" => iid))
+                                                "pio_appkey" => @appkey,
+                                                "pio_iid" => iid))
     end
 
     # :category: Synchronous Methods
@@ -386,20 +388,18 @@
       end
       if response.is_a?(Net::HTTPOK) then
         res = JSON.parse(response.body)
-        ct = Rational(res["ct"], 1000)
-        res["ct"] = Time.at(ct)
-        if res["latlng"] != nil then
-          latlng = res["latlng"]
-          res["latitude"] = latlng[0]
-          res["longitude"] = latlng[1]
+        if res["pio_latlng"] != nil then
+          latlng = res["pio_latlng"]
+          res["pio_latitude"] = latlng[0]
+          res["pio_longitude"] = latlng[1]
         end
-        if res["startT"] != nil then
-          startT = Rational(res["startT"], 1000)
-          res["startT"] = Time.at(startT)
+        if res["pio_startT"] != nil then
+          startT = Rational(res["pio_startT"], 1000)
+          res["pio_startT"] = Time.at(startT)
         end
-        if res["endT"] != nil then
-          endT = Rational(res["endT"], 1000)
-          res["endT"] = Time.at(endT)
+        if res["pio_endT"] != nil then
+          endT = Rational(res["pio_endT"], 1000)
+          res["pio_endT"] = Time.at(endT)
         end
         res
       else
@@ -420,8 +420,8 @@
     # See also #delete_item.
     def adelete_item(iid)
       @http.adelete(PredictionIO::AsyncRequest.new(versioned_path("/items/#{iid}.#{@apiformat}"),
-                                               "appkey" => @appkey,
-                                               "iid" => iid))
+                                                   "pio_appkey" => @appkey,
+                                                   "pio_iid" => iid))
     end
 
     # :category: Synchronous Methods
@@ -448,32 +448,37 @@
       end
     end
 
+    # Set the user ID for use in all subsequent user-to-item action recording and user recommendation retrieval.
+    def identify(uid)
+      @apiuid = uid
+    end
+
     # :category: Asynchronous Methods
     # Asynchronously request to get the top n recommendations for a user from an ItemRec engine and return a PredictionIO::AsyncResponse object immediately.
     #
     # Corresponding REST API method: GET /engines/itemrec/:engine/topn
     #
     # See also #get_itemrec_top_n.
-    def aget_itemrec_top_n(engine, uid, n, params = {})
+    def aget_itemrec_top_n(engine, n, params = {})
       rparams = Hash.new
-      rparams["appkey"] = @appkey
-      rparams["uid"] = uid
-      rparams["n"] = n
-      if params["itypes"] != nil &&
-          params["itypes"].kind_of?(Array) &&
-          params["itypes"].length > 0 then
-        rparams["itypes"] = params["itypes"].join(",")
+      rparams["pio_appkey"] = @appkey
+      rparams["pio_uid"] = @apiuid
+      rparams["pio_n"] = n
+      if params["pio_itypes"] != nil &&
+          params["pio_itypes"].kind_of?(Array) &&
+          params["pio_itypes"].length > 0 then
+        rparams["pio_itypes"] = params["pio_itypes"].join(",")
       else
-        rparams["itypes"] = params["itypes"]
+        rparams["pio_itypes"] = params["pio_itypes"]
       end
-      if params["latitude"] != nil && params["longitude"] != nil then
-        rparams["latlng"] = "#{params["latitude"]},#{params["longitude"]}"
+      if params["pio_latitude"] != nil && params["pio_longitude"] != nil then
+        rparams["pio_latlng"] = "#{params["pio_latitude"]},#{params["pio_longitude"]}"
       end
-      if params["within"] != nil then
-        rparams["within"] = params["within"]
+      if params["pio_within"] != nil then
+        rparams["pio_within"] = params["pio_within"]
       end
-      if params["unit"] != nil then
-        rparams["unit"] = params["unit"]
+      if params["pio_unit"] != nil then
+        rparams["pio_unit"] = params["pio_unit"]
       end
       @http.aget(PredictionIO::AsyncRequest.new(versioned_path("/engines/itemrec/#{engine}/topn.#{@apiformat}"), rparams))
     end
@@ -484,8 +489,8 @@
     # See #aget_itemrec_top_n for a description of special argument handling.
     #
     # call-seq:
-    # get_recommendations(uid, n, params = {})
-    # get_recommendations(async_response)
+    # aget_itemrec_top_n(engine, n, params = {})
+    # aget_itemrec_top_n(async_response)
     def get_itemrec_top_n(*args)
       uid_or_res = args[0]
       if uid_or_res.is_a?(PredictionIO::AsyncResponse) then
@@ -495,7 +500,7 @@
       end
       if response.is_a?(Net::HTTPOK) then
         res = JSON.parse(response.body)
-        res["iids"]
+        res["pio_iids"]
       else
         begin
           msg = response.body
@@ -507,166 +512,40 @@
     end
 
     # :category: Asynchronous Methods
-    # Asynchronously request to record a user-rate-item action and return a PredictionIO::AsyncResponse object immediately.
+    # Asynchronously request to record an action on an item and return a PredictionIO::AsyncResponse object immediately.
     #
-    # Corresponding REST API method: POST /actions/u2i/rate
+    # Corresponding REST API method: POST /actions/u2i
     #
-    # See also #user_rate_item.
-    def auser_rate_item(uid, iid, rate, params = {})
-      params["rate"] = rate
-      auser_action_item("rate", uid, iid, params)
-    end
-
-    # :category: Synchronous Methods
-    # Synchronously request to record a user-rate-item action and block until a response is received.
-    #
-    # See #auser_rate_item.
-    #
-    # call-seq:
-    # user_rate_item(uid, iid, rate, params = {})
-    # user_rate_item(async_response)
-    def user_rate_item(*args)
-      if !args[0].is_a?(PredictionIO::AsyncResponse) then
-        args.unshift("rate")
-        params = args[4]
-        if params == nil then
-          params = Hash.new
-        end
-        params["rate"] = args[3]
-        args[3] = params
-      end
-      user_action_item(*args)
-    end
-
-    # :category: Asynchronous Methods
-    # Asynchronously request to record a user-like-item action and return a PredictionIO::AsyncResponse object immediately.
-    #
-    # Corresponding REST API method: POST /actions/u2i/like
-    #
-    # See also #user_like_item.
-    def auser_like_item(uid, iid, params = {})
-      auser_action_item("like", uid, iid, params)
-    end
-
-    # :category: Synchronous Methods
-    # Synchronously request to record a user-like-item action and block until a response is received.
-    #
-    # See also #auser_like_item.
-    #
-    # call-seq:
-    # user_like_item(uid, iid, params = {})
-    # user_like_item(async_response)
-    def user_like_item(*args)
-      if !args[0].is_a?(PredictionIO::AsyncResponse) then
-        args.unshift("like")
-      end
-      user_action_item(*args)
-    end
-
-    # :category: Asynchronous Methods
-    # Asynchronously request to record a user-dislike-item action and return a PredictionIO::AsyncResponse object immediately.
-    #
-    # Corresponding REST API method: POST /actions/u2i/dislike
-    #
-    # See also #user_dislike_item.
-    def auser_dislike_item(uid, iid, params = {})
-      auser_action_item("dislike", uid, iid, params)
-    end
-
-    # :category: Synchronous Methods
-    # Synchronously request to record a user-dislike-item action and block until a response is received.
-    #
-    # See also #auser_dislike_item.
-    #
-    # call-seq:
-    # user_dislike_item(uid, iid, params = {})
-    # user_dislike_item(async_response)
-    def user_dislike_item(*args)
-      if !args[0].is_a?(PredictionIO::AsyncResponse) then
-        args.unshift("dislike")
-      end
-      user_action_item(*args)
-    end
-
-    # :category: Asynchronous Methods
-    # Asynchronously request to record a user-view-item action and return a PredictionIO::AsyncResponse object immediately.
-    #
-    # Corresponding REST API method: POST /actions/u2i/view
-    #
-    # See also #user_view_item.
-    def auser_view_item(uid, iid, params = {})
-      auser_action_item("view", uid, iid, params)
-    end
-
-    # :category: Synchronous Methods
-    # Synchronously request to record a user-view-item action and block until a response is received.
-    #
-    # See also #auser_view_item.
-    #
-    # call-seq:
-    # user_view_item(uid, iid, params = {})
-    # user_view_item(async_response)
-    def user_view_item(*args)
-      if !args[0].is_a?(PredictionIO::AsyncResponse) then
-        args.unshift("view")
-      end
-      user_action_item(*args)
-    end
-
-    # :category: Asynchronous Methods
-    # Asynchronously request to record a user-conversion-item action and return a PredictionIO::AsyncResponse object immediately.
-    #
-    # Corresponding REST API method: POST /actions/u2i/conversion
-    #
-    # See also #user_conversion_item.
-    def auser_conversion_item(uid, iid, params = {})
-      auser_action_item("conversion", uid, iid, params)
-    end
-
-    # :category: Synchronous Methods
-    # Synchronously request to record a user-conversion-item action and block until a response is received.
-    #
-    # See also #auser_conversion_item.
-    #
-    # call-seq:
-    # user_conversion_item(uid, iid, params = {})
-    # user_conversion_item(async_response)
-    def user_conversion_item(*args)
-      if !args[0].is_a?(PredictionIO::AsyncResponse) then
-        args.unshift("conversion")
-      end
-      user_action_item(*args)
-    end
-
-    # :nodoc: all
-    private
-
-    def versioned_path(path)
-      # disabled for now
-      # "/#{@apiversion}#{path}"
-      path
-    end
-
-    def auser_action_item(action, uid, iid, params = {})
+    # See also #record_action_on_item.
+    def arecord_action_on_item(action, iid, params = {})
       rparams = params
-      rparams["appkey"] = @appkey
-      rparams["uid"] = uid
-      rparams["iid"] = iid
-      if params["t"] != nil then
-        rparams["t"] = ((params["t"].to_r) * 1000).round(0).to_s
+      rparams["pio_appkey"] = @appkey
+      rparams["pio_action"] = action
+      rparams["pio_uid"] = @apiuid
+      rparams["pio_iid"] = iid
+      if params["pio_t"] != nil then
+        rparams["pio_t"] = ((params["pio_t"].to_r) * 1000).round(0).to_s
       end
-      if params["latitude"] != nil && params["longitude"] != nil then
-        rparams["latlng"] = "#{params["latitude"]},#{params["longitude"]}"
+      if params["pio_latitude"] != nil && params["pio_longitude"] != nil then
+        rparams["pio_latlng"] = "#{params["pio_latitude"]},#{params["pio_longitude"]}"
       end
-      @http.apost(PredictionIO::AsyncRequest.new(versioned_path("/actions/u2i/#{action}.#{@apiformat}"), rparams))
+      @http.apost(PredictionIO::AsyncRequest.new(versioned_path("/actions/u2i.#{@apiformat}"), rparams))
     end
 
-    def user_action_item(*args)
+    # :category: Synchronous Methods
+    # Synchronously request to record an action on an item and block until a response is received.
+    #
+    # See also #arecord_action_on_item.
+    #
+    # call-seq:
+    # record_action_on_item(action, uid, iid, params = {})
+    # record_action_on_item(async_response)
+    def record_action_on_item(*args)
       action_or_res = args[0]
       if action_or_res.is_a?(PredictionIO::AsyncResponse) then
         response = action_or_res.get
       else
-        response = auser_action_item(*args).get
+        response = arecord_action_on_item(*args).get
       end
       unless response.is_a?(Net::HTTPCreated) then
         begin
@@ -677,5 +556,14 @@
         raise U2IActionNotCreatedError, msg
       end
     end
+
+    # :nodoc: all
+    private
+
+    def versioned_path(path)
+      # disabled for now
+      # "/#{@apiversion}#{path}"
+      path
+    end
   end
 end
diff --git a/predictionio.gemspec b/predictionio.gemspec
index 30a1634..46472f0 100644
--- a/predictionio.gemspec
+++ b/predictionio.gemspec
@@ -6,7 +6,7 @@
 provides convenient access of the PredictionIO API to Ruby programmers so that
 they can focus on their application logic.
   EOF
-  s.version = "0.3.1"
+  s.version = "0.5.0"
   s.author = "The PredictionIO Team"
   s.email = "support@prediction.io"
   s.homepage = "http://prediction.io"
diff --git a/test/test.rb b/test/test.rb
index d10a683..a2dbd43 100644
--- a/test/test.rb
+++ b/test/test.rb
@@ -6,7 +6,7 @@
   if ENV["APPKEY"] then
     APPKEY = ENV["APPKEY"]
   else
-    APPKEY = "6MBUgJBRQdjPBtYIIqNSt3uIK6XaH3Wv0iFQvSzaImeIQHJEOUXtkj88EO39LtPn"
+    APPKEY = "k4f6rCV8YTM5x0PbRdIG4yrWiKLhOv16V0Q8COE2AcvnYmSlxbAcXR5pucI5HO21"
   end
   if ENV["APIURL"] then
     APIURL = ENV["APIURL"]
@@ -28,21 +28,21 @@
   def test_user
     client = PredictionIO::Client.new(APPKEY, APITHREADS, APIURL)
     client.create_user("ruby_foobar")
-    assert_equal("ruby_foobar", client.get_user("ruby_foobar")["uid"], "uid: ruby_foobar")
+    assert_equal("ruby_foobar", client.get_user("ruby_foobar")["pio_uid"], "uid: ruby_foobar")
     client.delete_user("ruby_foobar")
     client.create_user("ruby_barbaz",
                        "gender" => "F",
                        "bday" => "1985-05-05",
-                       "latitude" => 21.109,
-                       "longitude" => -48.7479,
-                       "inactive" => true)
+                       "pio_latitude" => 21.109,
+                       "pio_longitude" => -48.7479,
+                       "pio_inactive" => true)
     ruby_barbaz = client.get_user("ruby_barbaz")
-    assert_equal("ruby_barbaz", ruby_barbaz["uid"], "uid: ruby_barbaz")
+    assert_equal("ruby_barbaz", ruby_barbaz["pio_uid"], "uid: ruby_barbaz")
     #assert_equal("F", ruby_barbaz["gender"], "gender: F")
-    assert_equal(21.109, ruby_barbaz["latitude"], "lat: 21.109")
-    assert_equal(-48.7479, ruby_barbaz["longitude"], "lng: -48.7479")
+    assert_equal(21.109, ruby_barbaz["pio_latitude"], "lat: 21.109")
+    assert_equal(-48.7479, ruby_barbaz["pio_longitude"], "lng: -48.7479")
     #assert_equal("1985-05-05", ruby_barbaz["bday"], "bday: 1985-05-05")
-    assert(ruby_barbaz["inactive"], "inactive: true")
+    assert(ruby_barbaz["pio_inactive"], "inactive: true")
     client.delete_user("ruby_barbaz")
   end
 
@@ -50,32 +50,38 @@
     client = PredictionIO::Client.new(APPKEY, APITHREADS, APIURL)
     client.create_item("ruby_barbaz",
                        ["218", "55"],
-                       "latitude" => -58.24089,
-                       "longitude" => 48.17890,
-                       "startT" => Time.at(478308922000))
+                       "pio_latitude" => -58.24089,
+                       "pio_longitude" => 48.17890,
+                       "pio_startT" => Time.at(478308922000))
     assert_raises(PredictionIO::Client::ItemNotFoundError) { client.get_item("randomstuff") }
     ruby_barbaz = client.get_item("ruby_barbaz")
-    assert_equal("ruby_barbaz", ruby_barbaz["iid"], "iid: ruby_barbaz")
-    assert(ruby_barbaz["itypes"].include?("218"), "itypes: 218")
-    assert(ruby_barbaz["itypes"].include?("55"), "itypes: 55")
-    assert_equal(-58.24089, ruby_barbaz["latitude"], "lat: -58.24089")
-    assert_equal(48.1789, ruby_barbaz["longitude"], "lng: 48.1789")
-    assert_equal(Time.at(478308922000), ruby_barbaz["startT"], "startT: 478308922000")
+    assert_equal("ruby_barbaz", ruby_barbaz["pio_iid"], "iid: ruby_barbaz")
+    assert(ruby_barbaz["pio_itypes"].include?("218"), "itypes: 218")
+    assert(ruby_barbaz["pio_itypes"].include?("55"), "itypes: 55")
+    assert_equal(-58.24089, ruby_barbaz["pio_latitude"], "lat: -58.24089")
+    assert_equal(48.1789, ruby_barbaz["pio_longitude"], "lng: 48.1789")
+    assert_equal(Time.at(478308922000), ruby_barbaz["pio_startT"], "startT: 478308922000")
     client.delete_item("ruby_barbaz")
   end
 
   def test_u2i
     client = PredictionIO::Client.new(APPKEY, APITHREADS, APIURL)
-    client.user_rate_item("foo1", "bar2", 4)
-    client.user_like_item("foo2", "bar4")
-    client.user_dislike_item("foo4", "bar8")
-    client.user_view_item("foo8", "bar16")
-    client.user_conversion_item("foo16", "bar32")
+    client.identify("foo1")
+    client.record_action_on_item("rate", "bar2", "pio_rate" => 4)
+    client.identify("foo2")
+    client.record_action_on_item("like", "bar4")
+    client.identify("foo4")
+    client.record_action_on_item("dislike", "bar8")
+    client.identify("foo8")
+    client.record_action_on_item("view", "bar16")
+    client.identify("foo16")
+    client.record_action_on_item("conversion", "bar32")
   end
 
   def test_itemrec
     client = PredictionIO::Client.new(APPKEY, APITHREADS, APIURL)
-    iids = client.get_itemrec_top_n("test", "218", 5)
+    client.identify("218")
+    iids = client.get_itemrec_top_n("test", 5)
     assert(iids.include?("itemrec"))
     assert(iids.include?("218"))
     assert(iids.include?("1"))