diff --git a/lib/remote_storage/swift.rb b/lib/remote_storage/swift.rb index 197d1f8..913f683 100644 --- a/lib/remote_storage/swift.rb +++ b/lib/remote_storage/swift.rb @@ -152,6 +152,7 @@ module RemoteStorage end do_delete_request(url) + delete_metadata_objects(user, directory, key) delete_dir_objects(user, directory) server.halt 200 @@ -299,13 +300,23 @@ module RemoteStorage false end + def delete_metadata_objects(user, directory, key) + redis_key = "rs_meta:#{user}:#{directory}/#{key}" + redis.del(redis_key) + redis.srem "rs_meta:#{user}:#{directory}/:items", key + end + def delete_dir_objects(user, directory) parent_directories_for(directory).each do |dir| if dir_empty?(user, dir) do_delete_request("#{url_for_directory(user, dir)}/") + redis.del "rs_meta:#{user}:#{directory}/" + redis.srem "rs_meta:#{user}:#{parent_directory_for(dir)}:items", "#{dir}/" else timestamp = (Time.now.to_f * 1000).to_i - do_put_request("#{url_for_directory(user, dir)}/", timestamp.to_s, "text/plain") + res = do_put_request("#{url_for_directory(user, dir)}/", timestamp.to_s, "text/plain") + metadata = {etag: res.headers[:etag], modified: timestamp} + redis.hmset("rs_meta:#{user}:#{dir}/", *metadata) end end end diff --git a/spec/swift/app_spec.rb b/spec/swift/app_spec.rb index a7e25c8..17d1555 100644 --- a/spec/swift/app_spec.rb +++ b/spec/swift/app_spec.rb @@ -46,7 +46,6 @@ describe "App" do metadata = redis.hgetall "rs_meta:phil:food/" metadata["etag"].must_equal "bla" metadata["modified"].length.must_equal 13 - metadata = redis.hgetall "rs_meta:phil:food/" food_items = redis.smembers "rs_meta:phil:food/:items" food_items.each do |food_item| @@ -58,5 +57,86 @@ describe "App" do end end end + + describe "DELETE requests" do + context "authorized" do + before do + redis.sadd "authorizations:phil:amarillo", [":rw"] + header "Authorization", "Bearer amarillo" + + 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" + put "/phil/food/camaron", "yummi" + end + end + end + + it "deletes the metadata object in redis" do + put_stub = OpenStruct.new(headers: {etag: "bla"}) + RemoteStorage::Swift.stub_any_instance :dir_empty?, false do + RestClient.stub :put, put_stub do + RestClient.stub :delete, "" do + delete "/phil/food/aguacate" + end + end + end + + metadata = redis.hgetall "rs_meta:phil:food/aguacate" + metadata.must_be_empty + end + + it "deletes the directory objects metadata in redis" do + old_metadata = redis.hgetall "rs_meta:phil:food/" + + put_stub = OpenStruct.new(headers: {etag: "newetag"}) + RemoteStorage::Swift.stub_any_instance :dir_empty?, false do + RestClient.stub :put, put_stub do + RestClient.stub :delete, "" do + delete "/phil/food/aguacate" + end + end + end + + metadata = redis.hgetall "rs_meta:phil:food/" + metadata["etag"].must_equal "newetag" + metadata["modified"].length.must_equal 13 + metadata["modified"].wont_equal old_metadata["modified"] + + food_items = redis.smembers "rs_meta:phil:food/:items" + food_items.must_equal ["camaron"] + + root_items = redis.smembers "rs_meta:phil:/:items" + root_items.must_equal ["food/"] + end + + it "deletes the parent directory objects metadata when deleting all items" do + put_stub = OpenStruct.new(headers: {etag: "bla"}) + RemoteStorage::Swift.stub_any_instance :dir_empty?, false do + RestClient.stub :put, put_stub do + RestClient.stub :delete, "" do + delete "/phil/food/aguacate" + end + end + end + + RemoteStorage::Swift.stub_any_instance :dir_empty?, true do + RestClient.stub :delete, "" do + delete "/phil/food/camaron" + end + end + + metadata = redis.hgetall "rs_meta:phil:food/" + metadata.must_be_empty + + food_items = redis.smembers "rs_meta:phil:food/:items" + food_items.must_be_empty + + root_items = redis.smembers "rs_meta:phil:/:items" + root_items.must_be_empty + end + end + end end