Skip to content

Commit

Permalink
Fix more specs
Browse files Browse the repository at this point in the history
  • Loading branch information
alecslupu committed Dec 6, 2023
1 parent c1977b5 commit 04937c9
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

# i18n-tasks-use t('decidim.events.proposals.proposal_state_changed.affected_user.notification_title')
# i18n-tasks-use t('decidim.events.proposals.proposal_state_changed.affected_user.email_subject')
# i18n-tasks-use t('decidim.events.proposals.proposal_state_changed.affected_user.email_outro')
# i18n-tasks-use t('decidim.events.proposals.proposal_state_changed.affected_user.email_intro')
module Decidim
module CustomProposalStates
class ProposalStateChangedEvent < Decidim::Events::SimpleEvent
include Decidim::Events::AuthorEvent

def resource_text
translated_attribute(resource.answer)
end

def event_has_roles?
true
end

def default_i18n_options
super.merge({ state: state })
end

def state
if resource.emendation?
humanize_proposal_state(model.state)
else
translated_attribute(resource.proposal_state&.title)
end
end
end
end
end
4 changes: 4 additions & 0 deletions lib/decidim/custom_proposal_states.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ module Overrides
autoload :Proposal, "decidim/custom_proposal_states/overrides/proposal"
autoload :ImportProposalsToBudgets, "decidim/custom_proposal_states/overrides/import_proposals_to_budgets"
autoload :ImportProposalsToElections, "decidim/custom_proposal_states/overrides/import_proposals_to_elections"
autoload :WithdrawProposal, "decidim/custom_proposal_states/overrides/withdraw_proposal"
autoload :ImportProposals, "decidim/custom_proposal_states/overrides/import_proposals"
autoload :AnswerProposal, "decidim/custom_proposal_states/overrides/answer_proposal"
autoload :NotifyProposalAnswer, "decidim/custom_proposal_states/overrides/notify_proposal_answer"
end

def self.create_default_states!(component, admin_user, with_traceability: true)
Expand Down
4 changes: 4 additions & 0 deletions lib/decidim/custom_proposal_states/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class Engine < ::Rails::Engine
initializer "decidim_custom_proposal_states.overrides.proposal" do
Rails.application.reloader.to_prepare do
Decidim::Proposals::Proposal.prepend Decidim::CustomProposalStates::Overrides::Proposal
Decidim::Proposals::WithdrawProposal.prepend Decidim::CustomProposalStates::Overrides::WithdrawProposal
Decidim::Proposals::Admin::ImportProposals.prepend Decidim::CustomProposalStates::Overrides::ImportProposals
Decidim::Proposals::Admin::AnswerProposal.prepend Decidim::CustomProposalStates::Overrides::AnswerProposal
Decidim::Proposals::Admin::NotifyProposalAnswer.prepend Decidim::CustomProposalStates::Overrides::NotifyProposalAnswer
end
end
end
Expand Down
45 changes: 45 additions & 0 deletions lib/decidim/custom_proposal_states/overrides/answer_proposal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# frozen_string_literal: true

module Decidim
module CustomProposalStates
module Overrides
module AnswerProposal
def self.prepended(base)
base.class_eval do
def answer_proposal
Decidim.traceability.perform_action!(
"answer",
proposal,
form.current_user
) do
attributes = {
# state: form.state,
answer: form.answer,
cost: form.cost,
cost_report: form.cost_report,
execution_period: form.execution_period
}

proposal.assign_state(form.state)
if form.state == "not_answered"
attributes[:answered_at] = nil
attributes[:state_published_at] = nil
else
attributes[:answered_at] = Time.current
attributes[:state_published_at] = Time.current if !initial_has_state_published && form.publish_answer?
end

proposal.update!(attributes)
end
end

def store_initial_proposal_state
@initial_has_state_published = proposal.published_state?
@initial_state = proposal.proposal_state
end
end
end
end
end
end
end
34 changes: 34 additions & 0 deletions lib/decidim/custom_proposal_states/overrides/import_proposals.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

module Decidim
module CustomProposalStates
module Overrides
module ImportProposals
def self.prepended(base)
base.class_eval do
def proposals
@proposals = Decidim::Proposals::Proposal
.where(component: origin_component)
.only_status(@form.states)
@proposals = @proposals.where(scope: proposal_scopes) unless proposal_scopes.empty?
@proposals
end

def proposal_answer_attributes(original_proposal)
return {} unless form.keep_answers

state = Decidim::CustomProposalStates::ProposalState.where(component: target_component, token: original_proposal.state).first!

{
answer: original_proposal.answer,
answered_at: original_proposal.answered_at,
proposal_state: state,
state_published_at: original_proposal.state_published_at
}
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

module Decidim
module CustomProposalStates
module Overrides
module NotifyProposalAnswer
def self.prepended(base)
base.class_eval do
def initialize(proposal, initial_state)
@proposal = proposal
@initial_state = initial_state
end

def state_changed?
initial_state != proposal.proposal_state
end

def notify_followers
return unless proposal.proposal_state.notifiable?

Decidim::EventsManager.publish(
event: "decidim.events.proposals.proposal_state_changed",
event_class: Decidim::CustomProposalStates::ProposalStateChangedEvent,
resource: proposal,
affected_users: proposal.notifiable_identities,
followers: proposal.followers - proposal.notifiable_identities
)
end

def increment_score
previously_gamified = initial_state.present? && initial_state.gamified?

if !previously_gamified && proposal.proposal_state.gamified?
proposal.coauthorships.find_each do |coauthorship|
Decidim::Gamification.increment_score(coauthorship.user_group || coauthorship.author, :accepted_proposals)
end
elsif previously_gamified && !proposal.proposal_state.gamified?
proposal.coauthorships.find_each do |coauthorship|
Decidim::Gamification.decrement_score(coauthorship.user_group || coauthorship.author, :accepted_proposals)
end
end
end
end
end
end
end
end
end
18 changes: 18 additions & 0 deletions lib/decidim/custom_proposal_states/overrides/withdraw_proposal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

module Decidim
module CustomProposalStates
module Overrides
module WithdrawProposal
def self.prepended(base)
base.class_eval do
def change_proposal_state_to_withdrawn
@proposal.assign_state("withdrawn")
@proposal.save
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# frozen_string_literal: true

require "spec_helper"

describe Decidim::CustomProposalStates::ProposalStateChangedEvent do
context "when the proposal is evaluated" do
let(:resource) { create(:extended_proposal, title: "My super proposal") }
let(:event_name) { "decidim.events.proposals.proposal_evaluating" }

include_context "when a simple event"
it_behaves_like "a simple event"

describe "email_subject" do
it "is generated correctly" do
expect(subject.email_subject).to eq("A proposal you're following is being evaluated")
end
end

describe "email_intro" do
it "is generated correctly" do
expect(subject.email_intro)
.to eq("The proposal \"#{translated(resource.title)}\" is currently being evaluated. You can check for an answer in this page:")
end
end

describe "email_outro" do
it "is generated correctly" do
expect(subject.email_outro)
.to eq("You have received this notification because you are following \"#{translated(resource.title)}\". You can unfollow it from the previous link.")
end
end

describe "notification_title" do
it "is generated correctly" do
expect(subject.notification_title)
.to include("The <a href=\"#{resource_path}\">#{translated(resource.title)}</a> proposal is being evaluated")
end
end
end

context "when the proposal is rejected" do
let(:resource) { create(:extended_proposal, :with_answer, title: "It is my super proposal") }
let(:resource_title) { translated(resource.title) }
let(:event_name) { "decidim.events.proposals.proposal_rejected" }

include_context "when a simple event"
it_behaves_like "a simple event"

describe "email_subject" do
it "is generated correctly" do
expect(subject.email_subject).to eq("A proposal you're following has been rejected")
end
end

describe "email_intro" do
it "is generated correctly" do
expect(subject.email_intro)
.to eq("The proposal \"#{decidim_html_escape(resource_title)}\" has been rejected. You can read the answer in this page:")
end
end

describe "email_outro" do
it "is generated correctly" do
expect(subject.email_outro)
.to eq("You have received this notification because you are following \"#{decidim_html_escape(resource_title)}\". You can unfollow it from the previous link.")
end
end

describe "notification_title" do
it "is generated correctly" do
expect(subject.notification_title)
.to include("The <a href=\"#{resource_path}\">#{decidim_html_escape(resource_title)}</a> proposal has been rejected")
end
end

describe "resource_text" do
it "shows the proposal answer" do
expect(subject.resource_text).to eq translated(resource.answer)
end
end
end

context "when the proposal is accepted" do
let(:resource) { create(:extended_proposal, :with_answer, title: "My super proposal") }
let(:resource_title) { translated(resource.title) }
let(:event_name) { "decidim.events.proposals.proposal_accepted" }

include_context "when a simple event"
it_behaves_like "a simple event"

describe "email_subject" do
it "is generated correctly" do
expect(subject.email_subject).to eq("A proposal you're following has been accepted")
end
end

describe "email_intro" do
it "is generated correctly" do
expect(subject.email_intro)
.to eq("The proposal \"#{resource_title}\" has been accepted. You can read the answer in this page:")
end
end

describe "email_outro" do
it "is generated correctly" do
expect(subject.email_outro)
.to eq("You have received this notification because you are following \"#{resource_title}\". You can unfollow it from the previous link.")
end
end

describe "notification_title" do
it "is generated correctly" do
expect(subject.notification_title)
.to include("The <a href=\"#{resource_path}\">#{resource_title}</a> proposal has been accepted")
end
end

describe "resource_text" do
it "shows the proposal answer" do
expect(subject.resource_text).to eq translated(resource.answer)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,10 @@ module Admin
end

it "notifies the proposal answer" do
expect(proposal.proposal_state.token).to eq("not_answered")
expect(NotifyProposalAnswer)
.to receive(:call)
.with(proposal, nil)
.with(proposal, proposal.proposal_state)

subject
end
Expand Down Expand Up @@ -87,9 +88,10 @@ module Admin
end

it "notifies the proposal new answer" do
expect(proposal.proposal_state.token).to eq("accepted")
expect(NotifyProposalAnswer)
.to receive(:call)
.with(proposal, "accepted")
.with(proposal, proposal.proposal_state)

subject
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ module Admin
end

context "when the meeting is already linked to other proposals" do
let(:another_proposal) { create :proposal, component: component }
let(:another_proposal) { create :extended_proposal, component: component }

it "keeps the old proposals linked" do
another_proposal.link_resources(meeting_as_author, "proposals_from_meeting")
Expand Down Expand Up @@ -157,7 +157,7 @@ module Admin
end

context "when active record is slow" do
let(:proposal) { build :proposal, component: component }
let(:proposal) { build :extended_proposal, component: component }

before do
allow(command).to receive(:proposal).and_return(nil)
Expand Down
Loading

0 comments on commit 04937c9

Please sign in to comment.