diff --git a/Gemfile.lock b/Gemfile.lock index c8a084c..3377616 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,7 +13,7 @@ GEM eventmachine (0.12.10) i18n (0.6.0) minitest (2.10.0) - multi_json (1.0.4) + multi_json (1.3.6) purdytest (1.0.0) minitest (~> 2.2) rack (1.3.5) @@ -22,11 +22,11 @@ GEM rack-test (0.6.1) rack (>= 1.0) rake (0.9.2.2) - riak-client (1.0.0) + riak-client (1.0.3) beefcake (~> 0.3.7) builder (>= 2.1.2) i18n (>= 0.4.0) - multi_json (~> 1.0.0) + multi_json (~> 1.0) sinatra (1.3.1) rack (~> 1.3, >= 1.3.4) rack-protection (~> 1.1, >= 1.1.2) diff --git a/lib/remote_storage/riak.rb b/lib/remote_storage/riak.rb index ab03cda..02289c1 100644 --- a/lib/remote_storage/riak.rb +++ b/lib/remote_storage/riak.rb @@ -1,4 +1,5 @@ require "riak" +require "json" module RemoteStorage module Riak @@ -18,14 +19,22 @@ module RemoteStorage end def get_data(user, category, key) - client.bucket("user_data").get("#{user}:#{category}:#{key}").data + object = client.bucket("user_data").get("#{user}:#{category}:#{key}") + headers["Content-Type"] = object.content_type + case object.content_type + when "application/json" + return object.data.to_json + else + return object.data + end rescue ::Riak::HTTPFailedRequest halt 404 end - def put_data(user, category, key, data) + def put_data(user, category, key, data, content_type=nil) object = client.bucket("user_data").new("#{user}:#{category}:#{key}") - object.content_type = "text/plain; charset=utf-8" + object.content_type = content_type || "text/plain; charset=utf-8" + data = JSON.parse(data) if content_type == "application/json" object.data = data object.indexes.merge!({:user_id_bin => [user]}) object.store diff --git a/liquor-cabinet.rb b/liquor-cabinet.rb index 1b628d1..f448dad 100644 --- a/liquor-cabinet.rb +++ b/liquor-cabinet.rb @@ -47,7 +47,14 @@ class LiquorCabinet < Sinatra::Base put "/:user/:category/:key" do data = request.body.read - put_data(@user, @category, @key, data) + + if env['CONTENT_TYPE'] == "application/x-www-form-urlencoded" + content_type = "text/plain; charset=utf-8" + else + content_type = env['CONTENT_TYPE'] + end + + put_data(@user, @category, @key, data, content_type) end delete "/:user/:category/:key" do diff --git a/spec/riak_spec.rb b/spec/riak_spec.rb index 66dee69..d53d1b1 100644 --- a/spec/riak_spec.rb +++ b/spec/riak_spec.rb @@ -73,23 +73,51 @@ describe "App with Riak backend" do end describe "PUT" do - before do - header "Authorization", "Bearer 123" - put "/jimmy/documents/bar", "another text" + describe "with implicit content type" do + before do + header "Authorization", "Bearer 123" + put "/jimmy/documents/bar", "another text" + end + + it "saves the value" do + last_response.status.must_equal 200 + data_bucket.get("jimmy:documents:bar").data.must_equal "another text" + end + + it "stores the data as plain text with utf-8 encoding" do + data_bucket.get("jimmy:documents:bar").content_type.must_equal "text/plain; charset=utf-8" + end + + it "indexes the data set" do + data_bucket.get("jimmy:documents:bar").indexes["user_id_bin"].must_be_kind_of Set + data_bucket.get("jimmy:documents:bar").indexes["user_id_bin"].must_include "jimmy" + end end - it "saves the value" do - last_response.status.must_equal 200 - data_bucket.get("jimmy:documents:bar").data.must_equal "another text" - end + describe "with explicit content type" do + before do + header "Authorization", "Bearer 123" + header "Content-Type", "application/json" + put "/jimmy/documents/jason", '{"foo": "bar", "unhosted": 1}' + end - it "stores the data as plain text with utf-8 encoding" do - data_bucket.get("jimmy:documents:bar").content_type.must_equal "text/plain; charset=utf-8" - end + it "saves the value (as JSON)" do + last_response.status.must_equal 200 + data_bucket.get("jimmy:documents:jason").data.must_be_kind_of Hash + data_bucket.get("jimmy:documents:jason").data.must_equal({"foo" => "bar", "unhosted" => 1}) + end - it "indexes the data set" do - data_bucket.get("jimmy:documents:bar").indexes["user_id_bin"].must_be_kind_of Set - data_bucket.get("jimmy:documents:bar").indexes["user_id_bin"].must_include "jimmy" + it "uses the requested content type" do + data_bucket.get("jimmy:documents:jason").content_type.must_equal "application/json" + end + + it "delivers the data correctly" do + header "Authorization", "Bearer 123" + get "/jimmy/documents/jason" + + last_response.body.must_equal '{"foo":"bar","unhosted":1}' + last_response.content_type.must_equal "application/json" + end end end