diff --git a/app/controllers/post_visibilities_controller.rb b/app/controllers/post_visibilities_controller.rb index ccc165940..eb0c46855 100644 --- a/app/controllers/post_visibilities_controller.rb +++ b/app/controllers/post_visibilities_controller.rb @@ -9,17 +9,36 @@ class PostVisibilitiesController < ApplicationController def update #note :id references a postvisibility - @post = Post.where(:id => params[:post_id]).select("id, guid, author_id").first + @post = accessible_post @contact = current_user.contact_for(@post.author) if @contact && @vis = PostVisibility.where(:contact_id => @contact.id, :post_id => params[:post_id]).first @vis.hidden = !@vis.hidden if @vis.save + update_cache(@vis) render 'update' return end end render :nothing => true, :status => 403 end + + protected + + def update_cache(visibility) + return unless RedisCache.configured? + + cache = RedisCache.new(current_user, 'created_at') + + if visibility.hidden? + cache.remove(accessible_post.id) + else + cache.add(accessible_post.created_at.to_i, accessible_post.id) + end + end + + def accessible_post + @post ||= Post.where(:id => params[:post_id]).select("id, guid, author_id, created_at").first + end end diff --git a/lib/diaspora/redis_cache.rb b/lib/diaspora/redis_cache.rb index 7756f2e3e..b41f184b6 100644 --- a/lib/diaspora/redis_cache.rb +++ b/lib/diaspora/redis_cache.rb @@ -81,6 +81,11 @@ class RedisCache self.trim! end + def remove(id) + return unless self.cache_exists? + self.redis.zrem(set_key, id) + end + # exposing the need to tie cache to a stream # @return [Array] Acceptable Post types for the given cache def self.acceptable_types diff --git a/spec/controllers/post_visibilities_controller_spec.rb b/spec/controllers/post_visibilities_controller_spec.rb index 75d4bef1f..cf2ae329d 100644 --- a/spec/controllers/post_visibilities_controller_spec.rb +++ b/spec/controllers/post_visibilities_controller_spec.rb @@ -8,11 +8,12 @@ describe PostVisibilitiesController do before do @status = alice.post(:status_message, :text => "hello", :to => alice.aspects.first) @vis = @status.post_visibilities.first + sign_in :user, bob end describe '#update' do before do - sign_in :user, bob + @controller.stub(:update_cache) end context "on a post you can see" do @@ -21,6 +22,11 @@ describe PostVisibilitiesController do response.should be_success end + it 'calls #update_cache' do + @controller.should_receive(:update_cache).with(an_instance_of(PostVisibility)) + put :update, :format => :js, :id => 42, :post_id => @status.id + end + it 'marks hidden if visible' do put :update, :format => :js, :id => 42, :post_id => @status.id @vis.reload.hidden.should be_true @@ -51,4 +57,42 @@ describe PostVisibilitiesController do end end end + + describe '#update_cache' do + before do + @controller.params[:post_id] = @status.id + @cache = RedisCache.new(bob, 'created_at') + RedisCache.stub(:new).and_return(@cache) + RedisCache.stub(:configured?).and_return(true) + end + + it 'does nothing if cache is not configured' do + RedisCache.stub(:configured?).and_return(false) + RedisCache.should_not_receive(:new) + @controller.send(:update_cache, @vis) + end + + it 'removes the post from the cache if visibility is marked as hidden' do + @vis.hidden = true + @cache.should_receive(:remove).with(@vis.post_id) + @controller.send(:update_cache, @vis) + end + + it 'adds the post from the cache if visibility is marked as hidden' do + @vis.hidden = false + @cache.should_receive(:add).with(@status.created_at.to_i, @vis.post_id) + @controller.send(:update_cache, @vis) + end + end + + describe "#accessible_post" do + it "memoizes a query for a post given a post_id param" do + id = 1 + @controller.params[:post_id] = id + Post.should_receive(:where).with(hash_including(:id => id)).once.and_return(stub.as_null_object) + 2.times do |n| + @controller.send(:accessible_post) + end + end + end end diff --git a/spec/lib/diaspora/redis_cache_spec.rb b/spec/lib/diaspora/redis_cache_spec.rb index 253535dcf..56500fc42 100644 --- a/spec/lib/diaspora/redis_cache_spec.rb +++ b/spec/lib/diaspora/redis_cache_spec.rb @@ -160,7 +160,27 @@ describe RedisCache do @cache.stub(:cache_exists?).and_return(false) @redis.should_not_receive(:zadd) - @cache.add(@score, @id).should be_false + @cache.add(@score, @id) + end + end + + describe "#remove" do + before do + @id = 1 + end + + it "doesn't add if the cache does not exist" do + @cache.stub(:cache_exists?).and_return(false) + + @redis.should_not_receive(:zrem) + @cache.remove(@id).should be_false + end + + it "removes a given id" do + @cache.stub(:cache_exists?).and_return(true) + + @redis.should_receive(:zrem).with(@cache.send(:set_key), @id) + @cache.remove(@id) end end @@ -190,6 +210,4 @@ describe RedisCache do RedisCache.acceptable_types.should =~ AspectStream::TYPES_OF_POST_IN_STREAM end end - - describe "#remove" end