Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ end
**Added**:

- **decidim-meetings**: Add Minutes entity to manage Minutes. [\#3213](https://github.com/decidim/decidim/pull/3213)
- **decidim-initiatives**: Notify initiatives milestones [\#3341](https://github.com/decidim/decidim/pull/3341)
- **decidim-admin**: Links to participatory space index & show pages from the admin dashboard. [\#3325](https://github.com/decidim/decidim/pull/3325)

**Changed**:
Expand Down
1 change: 1 addition & 0 deletions config/i18n-tasks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ ignore_unused:
- decidim.initiatives.initiatives.orders.*
- decidim.initiatives.states.*
- decidim.initiatives.admin_states.*
- decidim.initiatives.events.*
- decidim.events.*
- doorkeeper.scopes.*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ def call
build_initiative_vote
return broadcast(:invalid) unless vote.valid?

percentage_before = @initiative.percentage
vote.save!
send_notification
percentage_after = @initiative.reload.percentage

notify_percentage_change(percentage_before, percentage_after)

broadcast(:ok, vote)
end
Expand All @@ -52,6 +56,24 @@ def send_notification
recipient_ids: @initiative.author.followers.pluck(:id)
)
end

def notify_percentage_change(before, after)
percentage = [25, 50, 75, 100].find do |milestone|
before < milestone && after >= milestone
end

return unless percentage

Decidim::EventsManager.publish(
event: "decidim.events.initiatives.milestone_completed",
event_class: Decidim::Initiatives::MilestoneCompletedEvent,
resource: @initiative,
recipient_ids: @initiative.followers.pluck(:id),
extra: {
percentage: percentage
}
)
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,11 @@

module Decidim
module Initiatives
class EndorseInitiativeEvent < Decidim::Events::BaseEvent
include Decidim::Events::EmailEvent
include Decidim::Events::NotificationEvent
class EndorseInitiativeEvent < Decidim::Events::SimpleEvent
include Decidim::Events::AuthorEvent

def email_subject
I18n.t(
"decidim.initiatives.events.endorse_initiative_event.email_subject",
resource_title: resource_title,
author_nickname: author.nickname,
author_name: author.name
)
end

def email_intro
I18n.t(
"decidim.initiatives.events.endorse_initiative_event.email_intro",
resource_title: resource_title,
author_nickname: author.nickname,
author_name: author.name
)
end

def email_outro
I18n.t(
"decidim.initiatives.events.endorse_initiative_event.email_outro",
resource_title: resource_title,
author_nickname: author.nickname,
author_name: author.name
)
end

def notification_title
I18n.t(
"decidim.initiatives.events.endorse_initiative_event.notification_title",
resource_title: resource_title,
resource_path: resource_path,
author_nickname: author.nickname,
author_name: author.name,
author_path: author.profile_path
).html_safe
end

private

def author
@author ||= Decidim::UserPresenter.new(resource.author)
def i18n_scope
"decidim.initiatives.events.endorse_initiative_event"
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen-string_literal: true

module Decidim
module Initiatives
class MilestoneCompletedEvent < Decidim::Events::SimpleEvent
i18n_attributes :percentage

def percentage
extra[:percentage]
end

def participatory_space
resource
end
end
end
end
7 changes: 7 additions & 0 deletions decidim-initiatives/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ en:
titles:
initiatives: Initiatives
initiatives_types: Initiative types
events:
initiatives:
milestone_completed:
email_intro: The initiative %{resource_title} has achieved the %{percentage}% of votes!
email_outro: You have received this notification because you are following %{resource_title}. You can stop receiving notifications following the previous link.
email_subject: New milestone completed!
notification_title: The <a href="%{resource_path}">%{resource_title}</a> initiative has achieved the %{percentage}% of votes.
initiatives:
admin:
committee_requests:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,44 @@ module Initiatives

command.call
end

context "when a new milestone is completed" do
let(:organization) { create(:organization) }
let(:initiative) do
create(:initiative,
organization: organization,
scoped_type: create(
:initiatives_type_scope,
supports_required: 4,
type: create(:initiatives_type, organization: organization)
))
end

before do
create(:initiative_user_vote, initiative: initiative)
create(:initiative_user_vote, initiative: initiative)
end

it "notifies the followers" do
follower = create(:user, organization: initiative.organization)
create(:follow, followable: initiative, user: follower)

expect(Decidim::EventsManager).to receive(:publish)
.with(kind_of(Hash))

expect(Decidim::EventsManager)
.to receive(:publish)
.with(
event: "decidim.events.initiatives.milestone_completed",
event_class: Decidim::Initiatives::MilestoneCompletedEvent,
resource: initiative,
recipient_ids: [follower.id],
extra: { percentage: 75 }
)

command.call
end
end
end

describe "Organization supports initiative" do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require "spec_helper"

describe Decidim::Initiatives::MilestoneCompletedEvent do
include_context "when a simple event"

let(:event_name) { "decidim.events.initiatives.milestone_completed" }
let(:resource) { initiative }

let(:initiative) { create :initiative }
let(:extra) { { percentage: 75 } }
let(:participatory_space) { initiative }

it_behaves_like "a simple event"

describe "types" do
subject { described_class }

it "supports notifications" do
expect(subject.types).to include :notification
end

it "supports emails" do
expect(subject.types).to include :email
end
end

describe "email_subject" do
it "is generated correctly" do
expect(subject.email_subject).to eq("New milestone completed!")
end
end

describe "email_intro" do
it "is generated correctly" do
expect(subject.email_intro)
.to eq("The initiative #{resource_title} has achieved the 75% of votes!")
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> initiative has achieved the 75% of votes")
end
end
end