require 'rails_helper' describe Dashboard::Action do subject do build :dashboard_action, title: title, description: description, day_offset: day_offset, required_supports: required_supports, request_to_administrators: request_to_administrators, action_type: action_type end let(:title) { Faker::Lorem.sentence } let(:description) { Faker::Lorem.sentence } let(:day_offset) { 0 } let(:required_supports) { 0 } let(:request_to_administrators) { true } let(:action_type) { 'resource' } it 'is invalid when title is blank' do action = build(:dashboard_action, title: '') expect(action).not_to be_valid end it 'is invalid when title is too short' do action = build(:dashboard_action, title: 'abc') expect(action).not_to be_valid end it 'is invalid when title is too long' do action = build(:dashboard_action, title: 'a' * 81) expect(action).not_to be_valid end it 'is invalid when day_offset is not defined' do action = build(:dashboard_action, day_offset: nil) expect(action).not_to be_valid end it 'is invalid when day_offset is negative' do action = build(:dashboard_action, day_offset: -1) expect(action).not_to be_valid end it 'is invalid when day_offset not an integer' do action = build(:dashboard_action, day_offset: 1.23) expect(action).not_to be_valid end it 'is invalid when required_supports is nil' do action = build(:dashboard_action, required_supports: nil) expect(action).not_to be_valid end it 'is invalid when required_supports is negative' do action = build(:dashboard_action, required_supports: -1) expect(action).not_to be_valid end it 'is invalid when required_supports is not an integer' do action = build(:dashboard_action, required_supports: 1.23) expect(action).not_to be_valid end it 'is invalid when action_type is nil' do action = build(:dashboard_action, action_type: nil) expect(action).not_to be_valid end context '#active_for?' do it 'is active when required supports is 0 and day_offset is 0' do action = build(:dashboard_action, required_supports: 0, day_offset: 0) proposal = build(:proposal) expect(action).to be_active_for(proposal) end 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 it 'is active when have enough supports' do action = build(:dashboard_action, required_supports: 10, day_offset: 0) proposal = build(:proposal, cached_votes_up: 10) expect(action).to be_active_for(proposal) end 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 it 'is not active when not enough supports' do action = build(:dashboard_action, required_supports: 10, day_offset: 0) proposal = build(:proposal, cached_votes_up: 9) expect(action).not_to be_active_for(proposal) end end context '#requested_for?' do it 'is not requested when no administrator task' do proposal = create(:proposal) action = create(:dashboard_action, :active, :admin_request, :resource) expect(action).not_to be_requested_for(proposal) end it 'is requested when administrator task' do proposal = create(:proposal) action = create(:dashboard_action, :active, :admin_request, :resource) executed_action = create(:dashboard_executed_action, proposal: proposal, action: action) _task = create(:dashboard_administrator_task, :pending, source: executed_action) expect(action).to be_requested_for(proposal) end end context '#executed_for?' do it 'is not executed when no administrator task' do proposal = create(:proposal) action = create(:dashboard_action, :active, :admin_request, :resource) expect(action).not_to be_executed_for(proposal) end it 'is not executed when pending administrator task' do proposal = create(:proposal) action = create(:dashboard_action, :active, :admin_request, :resource) executed_action = create(:dashboard_executed_action, proposal: proposal, action: action) _task = create(:dashboard_administrator_task, :pending, source: executed_action) expect(action).not_to be_executed_for(proposal) end it 'is executed when done administrator task' do proposal = create(:proposal) action = create(:dashboard_action, :active, :admin_request, :resource) executed_action = create(:dashboard_executed_action, proposal: proposal, action: action) _task = create(:dashboard_administrator_task, :done, source: executed_action) expect(action).to be_executed_for(proposal) end end context '#active_for' do let!(:active_action) { create :dashboard_action, :active, day_offset: 0, required_supports: 0 } 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 expect(described_class.active_for(proposal)).to include(active_action) end 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 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 expect(described_class.active_for(proposal)).not_to include(future_action) 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 let!(:proposed_action) { create :dashboard_action, :active, required_supports: 0 } let!(:inactive_resource) { create :dashboard_action, :inactive, :resource, required_supports: 0 } let!(:resource) { create :dashboard_action, :active, :resource, required_supports: 10_000 } let!(:achieved_resource) { create :dashboard_action, :active, :resource, required_supports: 0 } let(:proposal) { create :proposal } it "proposed actions are not part of proposal's course" do expect(described_class.course_for(proposal)).not_to include(proposed_action) end it "inactive resources are not part of proposal's course" do expect(described_class.course_for(proposal)).not_to include(inactive_resource) end it "achievements are not part of the proposal's course" do expect(described_class.course_for(proposal)).not_to include(achieved_resource) end it "active resources are part of proposal's course" do expect(described_class.course_for(proposal)).to include(resource) end end context "#detect_new_actions_since" do describe "No detect new actions" do let!(:action) { create(:dashboard_action, :proposed_action, :active, day_offset: 1) } let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 1) } it "when there are not news actions actived for published proposals" do proposal = create(:proposal) action.update(published_proposal: true) resource.update(published_proposal: true) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to eq [] end it "when there are news actions actived for draft_proposal but proposal is published" do proposal = create(:proposal) action.update(published_proposal: false, day_offset: 0) resource.update(published_proposal: false, day_offset: 0) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to eq [] end it "when there are not news actions actived for draft proposals" do proposal = create(:proposal, :draft) action.update(published_proposal: false) resource.update(published_proposal: false) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to eq [] end it "when there are news actions actived for published_proposal but proposal is draft" do proposal = create(:proposal, :draft) action.update(published_proposal: true, day_offset: 0) resource.update(published_proposal: true, day_offset: 0) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to eq [] end end describe "Detect new actions when there are news actions actived" do context "for published proposals" do let!(:proposal) { create(:proposal) } let!(:action) { create(:dashboard_action, :proposed_action, :active, day_offset: 0, published_proposal: true) } let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 0, published_proposal: true) } it "when proposal has been created today and day_offset is valid only for today" do expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to include(resource.id) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to include(action.id) end it "when proposal has received a new vote today" do proposal.update(created_at: Date.yesterday, published_at: Date.yesterday) action.update(required_supports: 1) resource.update(required_supports: 0) create(:vote, voter: proposal.author, votable: proposal) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to include(action.id) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).not_to include(resource.id) end end context "for draft proposals" do let!(:proposal) { create(:proposal, :draft) } let!(:action) { create(:dashboard_action, :proposed_action, :active, day_offset: 0, published_proposal: false) } let!(:resource) { create(:dashboard_action, :resource, :active, day_offset: 0, published_proposal: false) } it "when day_offset field is valid for today and invalid for yesterday" do expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to include(resource.id) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to include(action.id) end it "when proposal has received a new vote today" do proposal.update(created_at: Date.yesterday) action.update(required_supports: 1) resource.update(required_supports: 2) create(:vote, voter: proposal.author, votable: proposal) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).to include(action.id) expect(described_class.detect_new_actions_since(Date.yesterday, proposal)).not_to include(resource.id) end end end end end