diff --git a/Gemfile b/Gemfile index f5ee5c7..694b773 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ group :test do gem 'rake' gem 'purdytest', :require => false gem 'm' + gem 'minitest-stub_any_instance' end group :staging, :production do diff --git a/Gemfile.lock b/Gemfile.lock index d234198..9d3cc8f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -50,6 +50,7 @@ GEM method_source (0.8.2) mime-types (2.6.1) minitest (5.7.0) + minitest-stub_any_instance (1.0.1) multi_json (1.11.1) multipart-post (2.0.0) net-scp (1.0.4) @@ -109,6 +110,7 @@ DEPENDENCIES fog m mime-types (~> 2.6.1) + minitest-stub_any_instance purdytest rainbows rake diff --git a/lib/remote_storage/swift.rb b/lib/remote_storage/swift.rb index 5fabbab..c3f5c2f 100644 --- a/lib/remote_storage/swift.rb +++ b/lib/remote_storage/swift.rb @@ -125,7 +125,16 @@ module RemoteStorage res = do_put_request(url, data, content_type) - if update_dir_objects(user, directory) + # TODO get last modified from response and add to metadata + metadata = { + etag: res.headers[:etag], + size: data.length, + type: content_type + } + + if update_metadata_object(user, directory, key, metadata) && + # TODO provide the last modified to use for the dir objects as well + update_dir_objects(user, directory) server.headers["ETag"] = %Q("#{res.headers[:etag]}") server.halt 200 else @@ -255,7 +264,13 @@ module RemoteStorage parent_directories end + def update_metadata_object(user, directory, key, metadata) + key = "users:#{user}:data:#{directory}/#{key}" + redis.hmset(key, *metadata) + end + def update_dir_objects(user, directory) + # TODO use actual last modified time from the document put request timestamp = (Time.now.to_f * 1000).to_i parent_directories_for(directory).each do |dir| diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ee4daac..585725a 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,6 +9,10 @@ require 'minitest/autorun' require 'rack/test' require 'purdytest' require 'riak' +require "redis" +require "rest_client" +require "minitest/stub_any_instance" +require "ostruct" def app LiquorCabinet @@ -28,6 +32,11 @@ def write_last_response_to_file(filename = "last_response.html") end alias context describe + +def redis + @redis ||= Redis.new(host: app.settings.redis["host"], port: app.settings.redis["port"]) +end + if app.settings.respond_to? :riak ::Riak.disable_list_keys_warnings = true diff --git a/spec/swift/app_spec.rb b/spec/swift/app_spec.rb new file mode 100644 index 0000000..bc3ec0a --- /dev/null +++ b/spec/swift/app_spec.rb @@ -0,0 +1,40 @@ +require_relative "../spec_helper" + +describe "App" do + include Rack::Test::Methods + + def app + LiquorCabinet + end + + it "returns 404 on non-existing routes" do + get "/virginmargarita" + last_response.status.must_equal 404 + end + + describe "PUT requests" do + context "authorized" do + before do + redis.sadd "authorizations:phil:amarillo", [":rw"] + header "Authorization", "Bearer amarillo" + + end + + it "creates the metadata object in redis" do + put_stub = OpenStruct.new(headers: {etag: "bla"}) + RemoteStorage::Swift.stub_any_instance :has_name_collision?, false do + RestClient.stub :put, put_stub do + put "/phil/food/aguacate", "si" + end + end + + metadata = redis.hgetall "users:phil:data:food/aguacate" + metadata["size"].must_equal "2" + metadata["type"].must_equal "text/plain; charset=utf-8" + metadata["etag"].must_equal "bla" + metadata["modified"].must_equal nil + end + end + end +end +