Skip to content

Commit

Permalink
Task/nudge reviewer invitations (#865)
Browse files Browse the repository at this point in the history
* Add Send Reminders link/email to reviewer invitations

* Move get_login_url_by_email_address to helper method

* Add specs
  • Loading branch information
jseraf committed Oct 1, 2021
1 parent 3ab8eb4 commit 5847c4a
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module GrantReviewers
module Invitations
class RemindersController < InvitationsController
def index
authorize @grant, :edit?
@open_invitations = GrantReviewer::Invitation
.with_inviter
.where(grant_id: @grant.id)
.open
if @open_invitations.any?
send_reminder_emails
flash[:notice] = 'Reminder emails have been sent to those who have not yet responded.'
else
flash[:warning] = 'There are no open reviewer invitations for this grant. No reminders have been sent'
end
redirect_to grant_invitations_path(@grant)
end

private

def send_reminder_emails
@open_invitations.each do |invitation|
GrantReviewerInvitationMailer.reminder(invitation: invitation, grant: @grant).deliver_now
invitation.update(reminded_at: Time.now)
end
end
end
end
end
3 changes: 2 additions & 1 deletion app/controllers/grant_reviewers/invitations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ class InvitationsController < ApplicationController

def index
authorize @grant, :edit?
@invitations = GrantReviewer::Invitation.with_inviter.by_grant(@grant)
@invitations = GrantReviewer::Invitation.with_inviter.by_grant(@grant)
@has_open_invitations = @invitations.any?{ |invite| invite.confirmed_at.nil? && invite.opted_out_at.nil? }
end

def update;end
Expand Down
4 changes: 4 additions & 0 deletions app/helpers/users_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ def full_name_list(users)
def sortable_full_name_list(users)
users.map{ |user| full_name(user) }.to_sentence(words_connector: '; ')
end

def get_login_url_by_email_address(email)
User.is_saml_email_address?(email: email) ? login_index_url : new_registered_user_registration_url
end
end
12 changes: 8 additions & 4 deletions app/mailers/grant_creator_request_review_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,24 @@ class GrantCreatorRequestReviewMailer < ApplicationMailer
def approved(request:)
set_attributes(request: request)

mail(to: @requester.email, subject: I18n.t('mailers.grant_creator_request_review.approved.subject', application_name: @application_name))
mail(to: @requester.email,
subject: I18n.t('mailers.grant_creator_request_review.approved.subject',
application_name: @application_name))
end

def rejected(request:)
set_attributes(request: request)

mail(to: @requester.email, subject: I18n.t('mailers.grant_creator_request_review.rejected.subject', application_name: @application_name))
mail(to: @requester.email,
subject: I18n.t('mailers.grant_creator_request_review.rejected.subject',
application_name: @application_name))
end

private

def set_attributes(request:)
@request = request
@requester = @request.requester
@request = request
@requester = @request.requester
@application_name = COMPETITIONS_CONFIG[:application_name]
end
end
11 changes: 9 additions & 2 deletions app/mailers/grant_reviewer_invitation_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ class GrantReviewerInvitationMailer < ApplicationMailer
def invite(invitation:, grant:, inviter:)
@email = invitation.email
@grant = grant
@login_url = User.is_saml_email_address?(email: @email) ? login_index_url : new_registered_user_registration_url
@inviter = inviter

mail(to: @email, subject: "Reviewer Invitation - #{@grant.name}")
mail(to: @email, subject: I18n.t('mailers.grant_reviewer_invitations.invite.subject', grant: @grant.name))
end

def reminder(invitation:, grant:)
@email = invitation.email
@grant = grant
@inviter = invitation.inviter

mail(to: @email, subject: I18n.t('mailers.grant_reviewer_invitations.reminder.subject', grant: @grant.name))
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
%br
#{@grant.name}
%br
a grant in #{link_to COMPETITIONS_CONFIG[:application_name], @login_url}.
a grant in #{link_to COMPETITIONS_CONFIG[:application_name], get_login_url_by_email_address(@email)}.

%p
By clicking the link above you will be prompted to create your account.
Expand Down
15 changes: 15 additions & 0 deletions app/views/grant_reviewer_invitation_mailer/reminder.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
%p
This is a friendly reminder that you have been invited by #{full_name(@inviter)} to be a reviewer for
%br
#{@grant.name}
%br
a grant in #{link_to COMPETITIONS_CONFIG[:application_name], get_login_url_by_email_address(@email)}.

%p
Once you have logged in, you may also opt out of this request.

%p
If you have questions, you can contact #{full_name(@inviter)} at #{@inviter.email}.

%p
Thank you.
3 changes: 3 additions & 0 deletions app/views/grant_reviewers/invitations/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
%ul.menu
%li.menu-text
Actions:
- if @has_open_invitations
%li
= link_to 'Send Reminder to Invited Reviewers', grant_invitation_reminders_path(@grant)
%li
= link_to 'Back to Reviewers', grant_reviewers_path(@grant)

Expand Down
7 changes: 7 additions & 0 deletions config/locales/mailers/grant_reviewer_invitations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
en:
mailers:
grant_reviewer_invitations:
invite:
subject: "Reviewer Invitation for %{grant}"
reminder:
subject: "Reminder - Reviewer Invitation for %{grant}"
18 changes: 16 additions & 2 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,38 +32,52 @@
resources :grant_permissions, except: :show, controller: 'grant_permissions' do
get :users_query, on: :collection, to: 'grant_permissions/users_query#index', as: :users_query
end

resource :duplicate, only: %i[new create], controller: 'grants/duplicate'

resource :state, only: %i[publish draft], controller: 'grants/state' do
get 'publish', on: :member
get 'draft', on: :member
end

resources :reviews, only: :index, controller: 'grants/reviews' do
get 'reminders', to: 'grants/reviews/reminders#index', on: :collection
end

member do
get 'criteria', to: 'grants/criteria#index', as: :criteria
patch 'criteria/update', to: 'grants/criteria#update', as: :update_criteria
end

resources :forms, only: %i[update edit update_fields], controller: 'grant_submissions/forms' do
member do
put :update_fields
end
end

resources :submissions, except: %i[new], controller: 'grant_submissions/submissions' do
resources 'applicants', only: %i[index create destroy], controller: 'grant_submissions/submissions/submission_applicants'
resources 'applicants', only: %i[index create destroy], controller: 'grant_submissions/submissions/submission_applicants'

member do
patch 'unsubmit', to: 'grant_submissions/submissions/unsubmit#update'
end

resources :reviews, except: %i[new], controller: 'grant_submissions/submissions/reviews' do
delete 'opt_out', to: 'grant_submissions/submissions/reviews/opt_out#destroy', on: :member
end
end

resources :reviewers, only: %i[index create destroy], controller: 'grant_reviewers' do
collection do
post 'invite', to: 'grant_reviewers/invitations#create'
resources 'invitations', only: %i[index update], controller: 'grant_reviewers/invitations'
resources 'invitations', only: %i[index update], controller: 'grant_reviewers/invitations' do
collection do
resources :reminders, only: :index, as: 'invitation_reminders', controller: 'grant_reviewers/invitations/reminders'
end
end
end
end

resource :panel, only: %i[show edit update], on: :member, controller: 'panels' do
resources :submissions, only: %i[index show], controller: 'panels/submissions' do
resources :reviews, only: %i[index show], controller: 'panels/submissions/reviews'
Expand Down
23 changes: 12 additions & 11 deletions spec/helpers/users_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

require 'rails_helper'

# Specs in this file have access to a helper object that includes
# the UsersHelper. For example:
#
# describe UsersHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# expect(helper.concat_strings("this","that")).to eq("this that")
# end
# end
# end
RSpec.describe UsersHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
let(:saml_user_email) { Faker::Internet.email(domain: COMPETITIONS_CONFIG[:devise][:registerable][:saml_domains].last) }
let(:registered_user_email) { Faker::Internet.email }

context '#get_login_url_by_email_address' do
it 'returns SAML login when given a configured saml user domain' do
expect(get_login_url_by_email_address(saml_user_email)).to eql login_index_url
end

it 'returns Devise login url when given a configured non-saml domain' do
expect(get_login_url_by_email_address(registered_user_email)).to eql new_registered_user_registration_url
end
end
end
37 changes: 29 additions & 8 deletions spec/requests/grant_reviewer_requests/invitations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,43 @@
let(:email) { Faker::Internet.email }
let(:invited) { create(:grant_reviewer_invitation, grant: grant) }

context '#create' do
context 'invite' do
context '#create' do
before(:each) do
ActionMailer::Base.deliveries.clear
login_user inviter
end

it 'mails the invitee' do
post(invite_grant_reviewers_path(grant_id: grant.slug, params: { email: email }))
expect(ActionMailer::Base.deliveries.count).to be 1
end

context 'invalid' do
it 'does not mail when email was previously invited' do
post(invite_grant_reviewers_path(grant_id: grant.slug, params: { email: invited.email }))
expect(ActionMailer::Base.deliveries.count).to be 0
end
end
end
end

context 'reminder' do
before(:each) do
ActionMailer::Base.deliveries.clear
invited.save
login_user inviter
end

it 'mails the invitee' do
post(invite_grant_reviewers_path(grant_id: grant.slug, params: {email: email }))
it 'sends reminder mail to the invitee' do
get(grant_invitation_reminders_path(grant))
expect(ActionMailer::Base.deliveries.count).to be 1
end

context 'invalid' do
it 'does not mail when email was previously invited' do
post(invite_grant_reviewers_path(grant_id: grant.slug, params: {email: invited.email }))
expect(ActionMailer::Base.deliveries.count).to be 0
end
it "updates the invitation's reminded_at attribute" do
expect do
get(grant_invitation_reminders_path(grant))
end.to change{invited.reload.reminded_at}.from nil
end
end
end
14 changes: 14 additions & 0 deletions spec/system/grant_reviewers/grant_reviewer_invitations_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@
expect(registered_invite_row).to have_content '-'
expect(saml_invite_row).to have_content '-'
end

it 'includes link to send reminder emails' do
expect(page).to have_link 'Send Reminder to Invited Reviewers', href: grant_invitation_reminders_path(grant)
end
end

context 'confirmed invites' do
Expand All @@ -81,6 +85,16 @@
expect(saml_invite_row).not_to have_content '-'
expect(registered_invite_row).to have_content today_string
end

it 'does not include link to send reminder emails' do
expect(page).not_to have_link 'Send Reminder to Invited Reviewers', href: grant_invitation_reminders_path(grant)
end

it 'displays no email sent text' do
visit grant_invitation_reminders_path(grant)
expect(page).to have_text 'There are no open reviewer invitations for this grant. No reminders have been sent'
end

end
end

Expand Down

0 comments on commit 5847c4a

Please sign in to comment.