diff --git a/app/controllers/asciicasts_controller.rb b/app/controllers/asciicasts_controller.rb index 528b4b8..a12cb70 100644 --- a/app/controllers/asciicasts_controller.rb +++ b/app/controllers/asciicasts_controller.rb @@ -9,8 +9,12 @@ class AsciicastsController < ApplicationController def index render locals: { - page: BrowsePagePresenter.build(params[:category], params[:order], - params[:page]) + page: BrowsePagePresenter.build( + policy_scope(Asciicast), + params[:category], + params[:order], + params[:page] + ) } end diff --git a/app/models/asciicast.rb b/app/models/asciicast.rb index 83aa00b..0845be9 100644 --- a/app/models/asciicast.rb +++ b/app/models/asciicast.rb @@ -50,7 +50,7 @@ class Asciicast < ActiveRecord::Base end def self.for_category_ordered(category, order, page = nil, per_page = nil) - collection = non_private + collection = self if category == :featured collection = collection.featured diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 019d7e0..1c7860e 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -1,5 +1,14 @@ class ApplicationPolicy + class Scope + attr_reader :user, :scope + + def initialize(user, scope) + @user = user || User.new + @scope = scope + end + end + attr_reader :user, :record def initialize(user, record) diff --git a/app/policies/asciicast_policy.rb b/app/policies/asciicast_policy.rb index 1f5d9e5..927281f 100644 --- a/app/policies/asciicast_policy.rb +++ b/app/policies/asciicast_policy.rb @@ -1,8 +1,12 @@ class AsciicastPolicy < ApplicationPolicy - class Scope < Struct.new(:user, :scope) + class Scope < Scope def resolve - scope + if user.admin? + scope.all + else + scope.non_private + end end end diff --git a/app/presenters/browse_page_presenter.rb b/app/presenters/browse_page_presenter.rb index d1fb81a..c8a5560 100644 --- a/app/presenters/browse_page_presenter.rb +++ b/app/presenters/browse_page_presenter.rb @@ -4,10 +4,11 @@ class BrowsePagePresenter DEFAULT_ORDER = :recency PER_PAGE = 12 - attr_reader :category, :order, :page, :per_page + attr_reader :scope, :category, :order, :page, :per_page - def self.build(category, order, page = nil, per_page = nil) + def self.build(scope, category, order, page = nil, per_page = nil) new( + scope, (category || DEFAULT_CATEGORY).to_sym, (order || DEFAULT_ORDER).to_sym, page || 1, @@ -15,7 +16,8 @@ class BrowsePagePresenter ) end - def initialize(category, order, page, per_page) + def initialize(scope, category, order, page, per_page) + @scope = scope @category = category @order = order @page = page @@ -34,7 +36,7 @@ class BrowsePagePresenter def get_items PaginatingDecorator.new( - Asciicast.for_category_ordered(category, order, page, per_page) + scope.for_category_ordered(category, order, page, per_page) ) end diff --git a/spec/controllers/asciicasts_controller_spec.rb b/spec/controllers/asciicasts_controller_spec.rb index 4c0afee..3b10486 100644 --- a/spec/controllers/asciicasts_controller_spec.rb +++ b/spec/controllers/asciicasts_controller_spec.rb @@ -18,22 +18,11 @@ describe AsciicastsController do subject { response } describe '#index' do - let(:asciicast_list_presenter) { double('asciicast_list_presenter') } - before do - allow(controller).to receive(:render) - allow(BrowsePagePresenter).to receive(:build). - with('featured', 'recency', '2') { asciicast_list_presenter } - get :index, category: 'featured', order: 'recency', page: '2' end it { should be_success } - - it "renders template with BrowsePagePresenter as page" do - expect(controller).to have_received(:render). - with(locals: { page: asciicast_list_presenter }) - end end describe '#show' do diff --git a/spec/models/asciicast_spec.rb b/spec/models/asciicast_spec.rb index 1f5b4fb..a823fb1 100644 --- a/spec/models/asciicast_spec.rb +++ b/spec/models/asciicast_spec.rb @@ -62,7 +62,6 @@ describe Asciicast do let!(:asciicast_4) { create(:asciicast, created_at: 3.hours.ago, views_count: 40, featured: true) } - let!(:asciicast_5) { create(:asciicast, private: true) } context "when category is :all" do let(:category) { :all } diff --git a/spec/policies/asciicast_policy_spec.rb b/spec/policies/asciicast_policy_spec.rb index 86cff0d..b15e0cf 100644 --- a/spec/policies/asciicast_policy_spec.rb +++ b/spec/policies/asciicast_policy_spec.rb @@ -2,6 +2,27 @@ require 'rails_helper' describe AsciicastPolicy do + describe AsciicastPolicy::Scope do + let(:policy_scope) { AsciicastPolicy::Scope.new(user, Asciicast.all) } + + subject { policy_scope.resolve } + + let!(:asciicast_1) { create(:asciicast, private: false) } + let!(:asciicast_2) { create(:asciicast, private: true) } + + context "when user is not admin" do + let(:user) { double(:user, admin?: false) } + + it { should eq([asciicast_1]) } + end + + context "when user is admin" do + let(:user) { double(:user, admin?: true) } + + it { should eq([asciicast_1, asciicast_2]) } + end + end + subject { described_class } describe '#permitted_attributes' do diff --git a/spec/presenters/browse_page_presenter_spec.rb b/spec/presenters/browse_page_presenter_spec.rb index 01d841f..443969a 100644 --- a/spec/presenters/browse_page_presenter_spec.rb +++ b/spec/presenters/browse_page_presenter_spec.rb @@ -3,8 +3,9 @@ require 'rails_helper' describe BrowsePagePresenter do describe '.build' do - subject { described_class.build(category, order, page, per_page) } + subject { described_class.build(scope, category, order, page, per_page) } + let(:scope) { double('scope') } let(:category) { 'awesome' } let(:order) { 'awesomeness' } let(:page) { 2 } @@ -59,7 +60,8 @@ describe BrowsePagePresenter do end end - let(:presenter) { described_class.new(category, order, page, per_page) } + let(:presenter) { described_class.new(scope, category, order, page, per_page) } + let(:scope) { double('scope') } let(:category) { :awesome } let(:order) { :awesomeness } let(:page) { 2 } @@ -78,13 +80,13 @@ describe BrowsePagePresenter do let(:asciicast) { double('asciicast', decorate: double(title: 'quux')) } before do - allow(Asciicast).to receive(:for_category_ordered) { collection } + allow(scope).to receive(:for_category_ordered) { collection } end it "gets the asciicasts for given category, order, page and per_page" do subject - expect(Asciicast).to have_received(:for_category_ordered). + expect(scope).to have_received(:for_category_ordered). with(:awesome, :awesomeness, 2, 5) end