diff --git a/app/controllers/asciicasts_controller.rb b/app/controllers/asciicasts_controller.rb index a92b81c..99fd004 100644 --- a/app/controllers/asciicasts_controller.rb +++ b/app/controllers/asciicasts_controller.rb @@ -2,7 +2,6 @@ class AsciicastsController < ApplicationController PER_PAGE = 15 before_filter :load_resource, :only => [:show, :raw, :edit, :update, :destroy] - before_filter :count_view, :only => [:show] before_filter :ensure_authenticated!, :only => [:edit, :update, :destroy] before_filter :ensure_owner!, :only => [:edit, :update, :destroy] @@ -33,6 +32,7 @@ class AsciicastsController < ApplicationController format.html do @asciicast = AsciicastDecorator.new(@asciicast) @title = @asciicast.title + ViewCounter.new(@asciicast, cookies).increment respond_with @asciicast end @@ -78,12 +78,6 @@ class AsciicastsController < ApplicationController @asciicast = Asciicast.find(params[:id]) end - def count_view - unless request.xhr? - Asciicast.increment_counter :views_count, @asciicast.id - end - end - def ensure_owner! if current_user != @asciicast.user redirect_to asciicast_path(@asciicast), :alert => "You can't do that." diff --git a/app/services/view_counter.rb b/app/services/view_counter.rb new file mode 100644 index 0000000..dcc552e --- /dev/null +++ b/app/services/view_counter.rb @@ -0,0 +1,22 @@ +class ViewCounter + attr_reader :asciicast, :storage + + def initialize(asciicast, storage) + @asciicast = asciicast + @storage = storage + end + + def increment + unless storage[key] + Asciicast.increment_counter(:views_count, asciicast.id) + asciicast.reload + storage[key] = '1' + end + end + + private + + def key + @key ||= :"asciicast_#{asciicast.id}_viewed" + end +end diff --git a/spec/controllers/asciicasts_controller_spec.rb b/spec/controllers/asciicasts_controller_spec.rb index df1764f..0803143 100644 --- a/spec/controllers/asciicasts_controller_spec.rb +++ b/spec/controllers/asciicasts_controller_spec.rb @@ -64,9 +64,14 @@ describe AsciicastsController do end context 'for html request' do + let(:view_counter) { mock('view_counter') } + before do AsciicastDecorator.should_receive(:new).with(asciicast). and_return(asciicast) + ViewCounter.should_receive(:new).with(asciicast, cookies). + and_return(view_counter) + view_counter.should_receive(:increment) get :show, :id => asciicast.id, :format => :html end @@ -82,6 +87,7 @@ describe AsciicastsController do before do AsciicastJSONDecorator.should_receive(:new).with(asciicast). and_return(asciicast) + ViewCounter.should_not_receive(:new) get :show, :id => asciicast.id, :format => :json end diff --git a/spec/services/view_counter_spec.rb b/spec/services/view_counter_spec.rb new file mode 100644 index 0000000..3b1ec90 --- /dev/null +++ b/spec/services/view_counter_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +describe ViewCounter do + let(:view_counter) { ViewCounter.new(asciicast, storage) } + let(:asciicast) { create(:asciicast) } + let(:storage) { {} } + + describe '#increment' do + context "when called for the first time" do + it "increments the views_count" do + expect { view_counter.increment }. + to change(asciicast, :views_count).by(1) + end + end + + context "when called for the second time" do + before do + view_counter.increment + end + + it "doesn't increment the views_count" do + expect { view_counter.increment }. + not_to change(asciicast, :views_count) + end + end + end +end