Skip to content

Commit

Permalink
Backport 'Fix conference invitations' to v0.27 (#10003)
Browse files Browse the repository at this point in the history
* Fix conference invitations

* Fix conference invitations

* Clarify the unauthorized errors when accepting/rejecting conference invitation

* Fix redirecting back to the same URL (accept/reject) after sign in

* Clarify the conference invitation text when inviting a new user

* Fix decline conference invitation link

* Add spaces to the links

* Fix re-joining already joined conference

In case the user already joined the conference, broadcast ok.

* Change the i18n key for invite existing users

* Add omitted value in keyword argument

* Add omitted value in keyword argument

Co-authored-by: Antti Hukkanen <antti.hukkanen@mainiotech.fi>
  • Loading branch information
andreslucena and ahukkanen committed Nov 3, 2022
1 parent 788f402 commit 0e07750
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def user

def invite_user_to_sign_up
user.skip_reconfirmation!
user.invite!(invited_by, invitation_instructions: "join_conference", conference: conference)
user.invite!(invited_by, invitation_instructions: "join_conference", conference: conference, registration_type: form.registration_type)
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def initialize(conference, registration_type, user)
# Broadcasts :ok if successful, :invalid otherwise.
def call
return broadcast(:invalid) unless can_join_conference?
return broadcast(:ok) if already_joined_conference?

conference.with_lock do
create_registration
Expand Down Expand Up @@ -58,6 +59,10 @@ def can_join_conference?
conference.registrations_enabled? && conference.has_available_slots?
end

def already_joined_conference?
conference.conference_registrations.where(user: user).any?
end

def send_email_pending_validation
Decidim::Conferences::ConferenceRegistrationMailer.pending_validation(user, conference, @registration_type).deliver_later
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ module Decidim
module Conferences
# Exposes the registration resource so users can join and leave conferences.
class ConferenceRegistrationsController < Decidim::Conferences::ApplicationController
before_action :ensure_signed_in

def create
enforce_permission_to :join, :conference, conference: conference

Expand Down Expand Up @@ -54,6 +56,20 @@ def decline_invitation

private

def ensure_signed_in
return if user_signed_in?

case action_name
when "create"
flash[:alert] = t("conference_registrations.create.unauthorized", scope: "decidim.conferences")
when "decline_invitation"
flash[:alert] = t("conference_registrations.decline_invitation.unauthorized", scope: "decidim.conferences")
else
raise Decidim::ActionForbidden
end
redirect_to(user_has_no_permission_referer || user_has_no_permission_path)
end

def conference
@conference ||= Conference.find_by(slug: params[:conference_slug])
end
Expand All @@ -65,6 +81,7 @@ def registration_type
def redirect_after_path
referer = request.headers["Referer"]
return redirect_to(conference_path(conference)) if referer =~ /invitation_token/
return redirect_to(conference_path(conference)) if referer =~ %r{users/sign_in}

redirect_back fallback_location: conference_path(conference)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def can_leave_conference?
end

def can_decline_invitation?
return unless user
return unless conference.presence
return unless conference.registrations_enabled? &&
conference.conference_invites.exists?(user: user) &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<p class="email-greeting"><%= t("devise.mailer.invitation_instructions.hello", email: @user.name) %></p>

<p class="email-instructions">
<%= t ".invited_you_to_join_a_conference", invited_by: @invited_by.name, application: @user.organization.name %>
<%= t ".invited_existing_user_to_join_a_conference", invited_by: @invited_by.name, application: @user.organization.name %>
</p>

<p class="email-button email-button__cta cta-decline">
<%= link_to t(".decline", conference_title: translated_attribute(@conference.title)),routes.decline_invitation_conference_registration_type_conference_registration_path(conference_slug: @conference.slug, registration_type_id: @registration_type.id) %>
<%= link_to t(".decline", conference_title: translated_attribute(@conference.title)), routes.decline_invitation_conference_registration_type_conference_registration_url(conference_slug: @conference.slug, registration_type_id: @registration_type.id) %>
</p>
<p class="email-button email-button__cta cta-accept">
<%= link_to t(".registration", conference_title: translated_attribute(@conference.title)),routes.conference_registration_type_conference_registration_url(conference_slug: @conference.slug, registration_type_id: @registration_type.id) %>
<%= link_to t(".registration", conference_title: translated_attribute(@conference.title)), routes.conference_registration_type_conference_registration_url(conference_slug: @conference.slug, registration_type_id: @registration_type.id) %>
</p>
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<p class="email-greeting"><%= t("devise.mailer.invitation_instructions.hello", email: @resource.name) %></p>

<p class="email-instructions">
<%= t("decidim.conferences.admin.invite_join_conference_mailer.invite.invited_you_to_join_a_conference", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
<%= t("decidim.conferences.admin.invite_join_conference_mailer.invite.invited_user_to_join_a_conference", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
</p>

<p class="email-button email-button__cta"><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token, invite_redirect: Decidim::EngineRouter.main_proxy(@opts[:conference]).conference_conference_registration_path(conference_slug: @opts[:conference]), host: @resource.organization.host) %></p>
<p class="email-button email-button__cta"><%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token, invite_redirect: Decidim::EngineRouter.main_proxy(@opts[:conference]).conference_registration_type_conference_registration_path(conference_slug: @opts[:conference], registration_type_id: @opts[:registration_type]), host: @resource.organization.host) %></p>

<% if @resource.invitation_due_at %>
<p class="email-small"><%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :long)) %></p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<%= t("devise.mailer.invitation_instructions.hello", email: @resource.name) %>
<%= t("decidim.conferences.admin.invite_join_conference_mailer.invite.invited_you_to_join_a_conference", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
<%= t("decidim.conferences.admin.invite_join_conference_mailer.invite.invited_existing_user_to_join_a_conference", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
<%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token, invite_redirect: Decidim::EngineRouter.main_proxy(@opts[:conference]).conference_conference_registration_path(conference_slug: @opts[:conference]), host: @resource.organization.host) %>
<%= link_to t("devise.mailer.invitation_instructions.accept"), accept_invitation_url(@resource, invitation_token: @token, invite_redirect: Decidim::EngineRouter.main_proxy(@opts[:conference]).conference_registration_type_conference_registration_path(conference_slug: @opts[:conference], registration_type_id: @opts[:registration_type]), host: @resource.organization.host) %>
<% if @resource.invitation_due_at %>
<%= t("devise.mailer.invitation_instructions.accept_until", due_date: l(@resource.invitation_due_at, format: :long)) %>
Expand Down
5 changes: 4 additions & 1 deletion decidim-conferences/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ en:
invite_join_conference_mailer:
invite:
decline: Decline invitation '%{conference_title}'
invited_you_to_join_a_conference: "%{invited_by} has invited you to join a conference at %{application}. You can decline or accept it through the links below."
invited_existing_user_to_join_a_conference: "%{invited_by} has invited you to join a conference at %{application}. You can decline or accept it through the links below."
invited_user_to_join_a_conference: "%{invited_by} has invited you to join a conference at %{application}. You can accept it through the link below."
registration: Registration for '%{conference_title}'
partners:
index:
Expand Down Expand Up @@ -431,9 +432,11 @@ en:
create:
invalid: There was a problem joining this conference.
success: You have successfully joined the conference.
unauthorized: You need to sign in before registering to the conference.
decline_invitation:
invalid: There was a problem declining the invitation.
success: You have successfully declined the invitation.
unauthorized: You need to sign in before declining the invitation.
destroy:
invalid: There was a problem leaving this conference.
success: You have successfully left the conference.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim::Conferences::Admin
describe InviteUserToJoinConference do
let(:command) { described_class.new(form, conference, invited_by) }

let(:conference) { create :conference }
let(:invited_by) { create :user, :admin, :confirmed, organization: conference.organization }
let(:invited_user) { create :user, :confirmed, organization: conference.organization }
let(:form) do
double(
invalid?: invalid,
existing_user: true,
current_organization: conference.organization,
user: invited_user,
registration_type: registration_type
)
end
let(:invalid) { false }
let(:registration_type) { create(:registration_type, conference: conference) }

describe "call" do
it "broadcasts ok" do
expect { command.call }.to broadcast(:ok)
end

it "sends the invitation to the existing user" do
perform_enqueued_jobs { command.call }

email = last_email
expect(email.to).to eq([invited_user.email])
expect(email.subject).to eq("Invitation to join a conference")
end

describe "when the user is a new user" do
let(:form) do
double(
invalid?: invalid,
existing_user: false,
current_organization: conference.organization,
email: "jdoe@example.org",
name: "John Doe",
registration_type: registration_type
)
end

it "broadcasts ok" do
expect { command.call }.to broadcast(:ok)
end

it "sends the invitation to the user" do
perform_enqueued_jobs { command.call }

email = last_email
expect(email.to).to eq(["jdoe@example.org"])
expect(email.subject).to eq("Invitation to join a conference")
end
end
end
end
end
8 changes: 8 additions & 0 deletions decidim-conferences/spec/commands/join_conference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,13 @@ module Decidim::Conferences
expect { subject.call }.to broadcast(:invalid)
end
end

context "when the user has already joined the conference" do
let!(:registration) { create(:conference_registration, conference: conference, user: user) }

it "broadcasts ok" do
expect { subject.call }.to broadcast(:ok)
end
end
end
end
22 changes: 22 additions & 0 deletions decidim-conferences/spec/system/conference_registrations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def visit_conference_registration_types
visit decidim_conferences.conference_registration_types_path(conference)
end

def visit_conference_registration_type
visit decidim_conferences.conference_registration_type_conference_registration_path(conference_slug: conference, registration_type_id: registration_type)
end

before do
switch_to_host(organization.host)

Expand Down Expand Up @@ -136,4 +140,22 @@ def visit_conference_registration_types
end
end
end

context "and the user has been invited to the conference" do
let!(:invite) { create(:conference_invite, user: user, registration_type: registration_type) }

it "requires the user to sign in" do
visit_conference_registration_type
expect(page).to have_current_path("/users/sign_in")
end

context "when the user is signed in" do
before { login_as user, scope: :user }

it "accepts the invitation successfully" do
visit_conference_registration_type
expect(page).to have_content("successfully")
end
end
end
end

0 comments on commit 0e07750

Please sign in to comment.