diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 75f2e0bc0..444032805 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -11,8 +11,8 @@ class DashboardController < Dashboard::BaseController proposal.publish redirect_to proposal_dashboard_path(proposal), notice: t('proposals.notice.published') end - - def progress + + def progress authorize! :dashboard, proposal end @@ -21,9 +21,12 @@ class DashboardController < Dashboard::BaseController end private - + def active_resources - @active_resources ||= Dashboard::Action.active.resources.order(required_supports: :asc, day_offset: :asc) + @active_resources ||= Dashboard::Action.active + .resources + .by_proposal(proposal) + .order(required_supports: :asc, day_offset: :asc) end def course diff --git a/app/models/dashboard/action.rb b/app/models/dashboard/action.rb index 88f94704d..7739f7838 100644 --- a/app/models/dashboard/action.rb +++ b/app/models/dashboard/action.rb @@ -14,7 +14,7 @@ class Dashboard::Action < ActiveRecord::Base enum action_type: [:proposed_action, :resource] - validates :title, + validates :title, presence: true, allow_blank: false, length: { in: 4..80 } @@ -39,13 +39,16 @@ class Dashboard::Action < ActiveRecord::Base scope :inactive, -> { where(active: false) } scope :resources, -> { where(action_type: 1) } scope :proposed_actions, -> { where(action_type: 0) } + scope :by_proposal, lambda { |proposal| + return where(published_proposal: false) if proposal.draft? + } - def self.active_for(proposal) + def self.active_for(proposal) published_at = proposal.published_at&.to_date || Date.today - active - .where('required_supports <= ?', proposal.cached_votes_up) - .where('day_offset <= ?', (Date.today - published_at).to_i) + active.where('required_supports <= ?', proposal.cached_votes_up) + .where('day_offset <= ?', (Date.today - published_at).to_i) + .by_proposal(proposal) end def self.course_for(proposal) diff --git a/spec/features/dashboard/dashboard_spec.rb b/spec/features/dashboard/dashboard_spec.rb index d2b433d6a..c10735046 100644 --- a/spec/features/dashboard/dashboard_spec.rb +++ b/spec/features/dashboard/dashboard_spec.rb @@ -56,47 +56,120 @@ feature "Proposal's dashboard" do expect(page).not_to have_selector(:css, "#dashboard_action_#{action.id}_execute") end - scenario 'Dashboard progress show available resources' do + scenario "Dashboard progress dont show proposed actions with published_proposal: true" do + action = create(:dashboard_action, :proposed_action, :active, published_proposal: true) + + visit progress_proposal_dashboard_path(proposal) + + expect(page).not_to have_content(action.title) + end + + scenario "Dashboard progress show available resources for proposal draft" do available = create(:dashboard_action, :resource, :active) requested = create(:dashboard_action, :resource, :admin_request, :active) - executed_action = create(:dashboard_executed_action, action: requested, proposal: proposal, executed_at: Time.current) + executed_action = create(:dashboard_executed_action, action: requested, + proposal: proposal, executed_at: Time.current) _task = create(:dashboard_administrator_task, :pending, source: executed_action) solved = create(:dashboard_action, :resource, :admin_request, :active) - executed_solved_action = create(:dashboard_executed_action, action: solved, proposal: proposal, executed_at: Time.current) + executed_solved_action = create(:dashboard_executed_action, action: solved, + proposal: proposal, executed_at: Time.current) _solved_task = create(:dashboard_administrator_task, :done, source: executed_solved_action) - unavailable = create(:dashboard_action, :resource, :active, required_supports: proposal.votes_for.size + 1_000) + unavailable = create(:dashboard_action, :resource, :active, + required_supports: proposal.votes_for.size + 1_000) visit progress_proposal_dashboard_path(proposal) - within 'div#available-resources-section' do - expect(page).to have_content('Polls') - expect(page).to have_content('E-mail') - expect(page).to have_content('Poster') + within "div#available-resources-section" do + expect(page).to have_content("Polls") + expect(page).to have_content("E-mail") + expect(page).to have_content("Poster") expect(page).to have_content(available.title) expect(page).to have_content(unavailable.title) expect(page).to have_content(requested.title) expect(page).to have_content(solved.title) within "div#dashboard_action_#{available.id}" do - expect(page).to have_link('Request resource') + expect(page).to have_link("Request resource") end within "div#dashboard_action_#{requested.id}" do - expect(page).to have_content('Resource already requested') + expect(page).to have_content("Resource already requested") end within "div#dashboard_action_#{unavailable.id}" do - expect(page).to have_content('1.000 supports required') + expect(page).to have_content("1.000 supports required") end within "div#dashboard_action_#{solved.id}" do - expect(page).to have_link('See resource') + expect(page).to have_link("See resource") end end end + scenario "Dashboard progress show available resources for published proposal" do + proposal.update(published_at: Date.today) + available = create(:dashboard_action, :resource, :active) + + requested = create(:dashboard_action, :resource, :admin_request, :active) + executed_action = create(:dashboard_executed_action, action: requested, + proposal: proposal, executed_at: Time.current) + _task = create(:dashboard_administrator_task, :pending, source: executed_action) + + solved = create(:dashboard_action, :resource, :admin_request, :active) + executed_solved_action = create(:dashboard_executed_action, action: solved, + proposal: proposal, executed_at: Time.current) + _solved_task = create(:dashboard_administrator_task, :done, source: executed_solved_action) + + unavailable = create(:dashboard_action, :resource, :active, + required_supports: proposal.votes_for.size + 1_000) + + visit progress_proposal_dashboard_path(proposal) + within "div#available-resources-section" do + expect(page).to have_content("Polls") + expect(page).to have_content("E-mail") + expect(page).to have_content("Poster") + expect(page).to have_content(available.title) + expect(page).to have_content(unavailable.title) + expect(page).to have_content(requested.title) + expect(page).to have_content(solved.title) + + within "div#dashboard_action_#{available.id}" do + expect(page).to have_link("Request resource") + end + + within "div#dashboard_action_#{requested.id}" do + expect(page).to have_content("Resource already requested") + end + + within "div#dashboard_action_#{unavailable.id}" do + expect(page).to have_content("1.000 supports required") + end + + within "div#dashboard_action_#{solved.id}" do + expect(page).to have_link("See resource") + end + end + end + + scenario "Dashboard progress dont show resources with published_proposal: true" do + available = create(:dashboard_action, :resource, :active, published_proposal: true) + unavailable = create(:dashboard_action, :resource, :active, + required_supports: proposal.votes_for.size + 1_000, + published_proposal: true) + + visit progress_proposal_dashboard_path(proposal) + + within "div#available-resources-section" do + expect(page).to have_content("Polls") + expect(page).to have_content("E-mail") + expect(page).to have_content("Poster") + expect(page).not_to have_content(available.title) + expect(page).not_to have_content(unavailable.title) + end + end + scenario 'Dashboard has a link to polls feature' do expect(page).to have_link('Polls') end diff --git a/spec/models/dashboard/action_spec.rb b/spec/models/dashboard/action_spec.rb index 675924308..738282992 100644 --- a/spec/models/dashboard/action_spec.rb +++ b/spec/models/dashboard/action_spec.rb @@ -1,9 +1,9 @@ require 'rails_helper' describe Dashboard::Action do - subject do - build :dashboard_action, - title: title, + subject do + build :dashboard_action, + title: title, description: description, day_offset: day_offset, required_supports: required_supports, @@ -79,7 +79,7 @@ describe Dashboard::Action do it 'is active when published after day_offset' do action = build(:dashboard_action, required_supports: 0, day_offset: 10) proposal = build(:proposal, published_at: Time.current - 10.days) - + expect(action).to be_active_for(proposal) end @@ -93,7 +93,7 @@ describe Dashboard::Action do it 'is not active when not enough time published' do action = build(:dashboard_action, required_supports: 0, day_offset: 10) proposal = build(:proposal, published_at: Time.current - 9.days) - + expect(action).not_to be_active_for(proposal) end @@ -155,23 +155,50 @@ describe Dashboard::Action do let!(:not_enough_supports_action) { create :dashboard_action, :active, day_offset: 0, required_supports: 10_000 } let!(:inactive_action) { create :dashboard_action, :inactive } let!(:future_action) { create :dashboard_action, :active, day_offset: 300, required_supports: 0 } + let!(:action_for_published_proposal) { create :dashboard_action, + :active, + day_offset: 0, + required_supports: 0, + published_proposal: true } + let!(:action_for_draft_proposal) { create :dashboard_action, + :active, + day_offset: 0, + required_supports: 0, + published_proposal: false } let(:proposal) { create :proposal } + let(:draft_proposal) { create :proposal, :draft } - it 'actions with enough supports or days are active' do + it "actions with enough supports or days are active" do expect(described_class.active_for(proposal)).to include(active_action) end - it 'inactive actions are not included' do + it "inactive actions are not included" do expect(described_class.active_for(proposal)).not_to include(inactive_action) end - it 'actions without enough supports are not active' do + it "actions without enough supports are not active" do expect(described_class.active_for(proposal)).not_to include(not_enough_supports_action) end - it 'actions planned to be active in the future are not active' do + it "actions planned to be active in the future are not active" do expect(described_class.active_for(proposal)).not_to include(future_action) - end + end + + it "actions with published_proposal: true, are not included on draft proposal" do + expect(described_class.active_for(draft_proposal)).not_to include(action_for_published_proposal) + end + + it "actions with published_proposal: true, are included on published proposal" do + expect(described_class.active_for(proposal)).to include(action_for_published_proposal) + end + + it "actions with published_proposal: false, are included on draft proposal" do + expect(described_class.active_for(draft_proposal)).to include(action_for_draft_proposal) + end + + it "actions with published_proposal: false, are included on published proposal" do + expect(described_class.active_for(proposal)).to include(action_for_draft_proposal) + end end context '#course_for' do