Skip to content

Commit

Permalink
Check for invitations in invite request status.
Browse files Browse the repository at this point in the history
  • Loading branch information
tickinginstant authored and weeklies committed Oct 27, 2023
1 parent 53fc408 commit 0812a2a
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 42 deletions.
26 changes: 22 additions & 4 deletions app/controllers/invite_requests_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,35 @@ def index
# GET /invite_requests/1
def show
@invite_request = InviteRequest.find_by(email: params[:email])
@position_in_queue = @invite_request.position if @invite_request.present?
unless (request.xml_http_request?) || @invite_request
flash[:error] = "You can search for the email address you signed up with below. If you can't find it, your invitation may have already been emailed to that address; please check your email spam folder as your spam filters may have placed it there."
redirect_to status_invite_requests_path and return

if @invite_request.present?
@position_in_queue = @invite_request.position
else
@invitation = Invitation.unredeemed.from_queue.find_by(invitee_email: params[:email])
end

respond_to do |format|
format.html
format.js
end
end

def resend
@invitation = Invitation.unredeemed.from_queue.find_by(invitee_email: params[:email])

if @invitation.nil?
flash[:error] = ts("Could not find an invitation associated with that email.")
elsif @invitation.sent_at < ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION.hours.ago
@invitation.send_and_set_date
flash[:notice] = ts("Invitation resent to %{email}.", email: @invitation.invitee_email)
else
flash[:error] = ts("You cannot resend an invitation that was sent in the last %{count} hours.",
count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION)
end

redirect_to status_invite_requests_path
end

# POST /invite_requests
def create
unless AdminSetting.current.invite_from_queue_enabled?
Expand Down
43 changes: 22 additions & 21 deletions app/models/invitation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ def recipient_is_not_registered
scope :unsent, -> { where(invitee_email: nil, redeemed_at: nil) }
scope :unredeemed, -> { where('invitee_email IS NOT NULL and redeemed_at IS NULL') }
scope :redeemed, -> { where('redeemed_at IS NOT NULL') }
scope :from_queue, -> { where(external_author: nil).where(creator_type: [nil, "Admin"]) }

before_validation :generate_token, on: :create
after_save :send_and_set_date
after_save :send_and_set_date, if: :saved_change_to_invitee_email?
after_save :adjust_user_invite_status

#Create a certain number of invitations for all valid users
Expand Down Expand Up @@ -54,32 +55,32 @@ def mark_as_redeemed(user=nil)
save
end

private

def generate_token
self.token = Digest::SHA1.hexdigest([Time.now, rand].join)
end

def send_and_set_date
if self.saved_change_to_invitee_email? && !self.invitee_email.blank?
begin
if self.external_author
archivist = self.external_author.external_creatorships.collect(&:archivist).collect(&:login).uniq.join(", ")
# send invite synchronously for now -- this should now work delayed but just to be safe
UserMailer.invitation_to_claim(self.id, archivist).deliver_now
else
# send invitations actively sent by a user synchronously to avoid delays
UserMailer.invitation(self.id).deliver_now
end
return if invitee_email.blank?

# Skip callbacks within after_save by using update_column to avoid a callback loop
self.update_column(:sent_at, Time.now)
rescue Exception => exception
errors.add(:base, "Notification email could not be sent: #{exception.message}")
begin
if self.external_author
archivist = self.external_author.external_creatorships.collect(&:archivist).collect(&:login).uniq.join(", ")
# send invite synchronously for now -- this should now work delayed but just to be safe
UserMailer.invitation_to_claim(self.id, archivist).deliver_now
else
# send invitations actively sent by a user synchronously to avoid delays
UserMailer.invitation(self.id).deliver_now
end

# Skip callbacks within after_save by using update_column to avoid a callback loop
self.update_column(:sent_at, Time.now)
rescue Exception => exception
errors.add(:base, "Notification email could not be sent: #{exception.message}")
end
end

private

def generate_token
self.token = Digest::SHA1.hexdigest([Time.now, rand].join)
end

#Update the user's out_of_invites status
def adjust_user_invite_status
if self.creator.respond_to?(:out_of_invites)
Expand Down
15 changes: 15 additions & 0 deletions app/views/invite_requests/_invitation.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!--Descriptive page name, messages and instructions-->
<h2 class="heading">
<%= t(".title", email: invitation.invitee_email) %>
</h2>
<!--/descriptions-->

<!--main content-->
<p>
<%= t(".date", date: l(invitation.sent_at.to_date)) %>
<% if invitation.sent_at < ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION.hours.ago %>
<%= t(".resend", count: ArchiveConfig.HOURS_BEFORE_RESEND_INVITATION) %>
<%= button_to t(".resend_button"), resend_invite_requests_path(email: invitation.invitee_email) %>
<% end %>
</p>
<!--/content-->
8 changes: 7 additions & 1 deletion app/views/invite_requests/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
<%= render "invite_request", invite_request: @invite_request %>
<% if @invite_request %>
<%= render "invite_request", invite_request: @invite_request %>
<% elsif @invitation %>
<%= render "invitation", invitation: @invitation %>
<% else %>
<p class="notice">Sorry, we can't find the email address you entered.</p>
<% end %>

<p>
<%= ts("To check on the status of your invitation, go to the %{status_page} and enter your email in the space provided!", status_page: link_to("Invitation Request Status page", status_invite_requests_path)).html_safe %>
Expand Down
4 changes: 3 additions & 1 deletion app/views/invite_requests/show.js.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<% if @invite_request %>
$j("#invite-status").html("<%= escape_javascript(render "invite_requests/invite_request", invite_request: @invite_request) %>");
<% elsif @invitation %>
$j("#invite-status").html("<%= escape_javascript(render "invitation", invitation: @invitation) %>");
<% else %>
$j("#invite-status").html("<p>Sorry, we can't find the email address you entered. If you had used it to join our invitation queue, it's possible that your invitation may have already been emailed to you; please check your spam folder, as your spam filters may have placed it there.</p>");
$j("#invite-status").html("<p>Sorry, we can't find the email address you entered.</p>");
<% end %>
2 changes: 2 additions & 0 deletions config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ DELIMITER_FOR_OUTPUT: ', '
INVITE_FROM_QUEUE_ENABLED: true
INVITE_FROM_QUEUE_NUMBER: 10
INVITE_FROM_QUEUE_FREQUENCY: 7

HOURS_BEFORE_RESEND_INVITATION: 24
# this is whether or not people without invitations can create accounts
ACCOUNT_CREATION_ENABLED: false
DAYS_TO_PURGE_UNACTIVATED: 7
Expand Down
7 changes: 7 additions & 0 deletions config/locales/views/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,13 @@ en:
date: 'At our current rate, you should receive an invitation on or around: %{date}.'
position_html: You are currently number %{position} on our waiting list!
title: Invitation Status for %{email}
invitation:
title: Invitation Status for %{email}
date: Your invitation was emailed to this address on %{date}. If you can't find it, please check your email spam folder as your spam filters may have placed it there.
resend:
one: Because your invitation was sent more than an hour ago, you can have your invitation resent.
other: Because your invitation was sent more than %{count} hours ago, you can have your invitation resent.
resend_button: Resend Invitation
kudos:
guest_header:
one: "%{count} guest has also left kudos"
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
collection do
get :manage
get :status
post :resend
end
end

Expand Down
30 changes: 28 additions & 2 deletions features/other_a/invite_queue.feature
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Feature: Invite queue management
# check your place in the queue - invalid address
When I check how long "[email protected]" will have to wait in the invite request queue
Then I should see "Invitation Request Status"
And I should see "If you can't find it, your invitation may have already been emailed to that address; please check your email spam folder as your spam filters may have placed it there."
And I should see "Sorry, we can't find the email address you entered."
And I should not see "You are currently number"

# check your place in the queue - correct address
Expand Down Expand Up @@ -98,7 +98,7 @@ Feature: Invite queue management
Then 1 email should be delivered to test@archiveofourown.org
When I check how long "[email protected]" will have to wait in the invite request queue
Then I should see "Invitation Request Status"
And I should see "If you can't find it, your invitation may have already been emailed to that address;"
And I should see "If you can't find it, please check your email spam folder as your spam filters may have placed it there."

# invite can be used
When I am logged in as an admin
Expand Down Expand Up @@ -155,3 +155,29 @@ Feature: Invite queue management
And I fill in "invite_request_email" with "[email protected]"
And I press "Add me to the list"
Then I should see "Email is already being used by an account holder."

Scenario: Users can resend their invitation after enough time has passed
Given account creation is enabled
And the invitation queue is enabled
And account creation requires an invitation
And the invite_from_queue_at is yesterday
And an invitation request for "[email protected]"
When the scheduled check_invite_queue job is run
Then 1 email should be delivered to invitee@example.org

When I check how long "[email protected]" will have to wait in the invite request queue
Then I should see "Invitation Request Status"
And I should see "If you can't find it, please check your email spam folder as your spam filters may have placed it there."
And I should not see "Because your invitation was sent more than 24 hours ago, you can have your invitation resent."
And I should not see a "Resend Invitation" button

When all emails have been delivered
And it is currently 25 hours from now
And I check how long "[email protected]" will have to wait in the invite request queue
Then I should see "Invitation Request Status"
And I should see "If you can't find it, please check your email spam folder as your spam filters may have placed it there."
And I should see "Because your invitation was sent more than 24 hours ago, you can have your invitation resent."
And I should see a "Resend Invitation" button

When I press "Resend Invitation"
Then 1 email should be delivered to invitee@example.org
39 changes: 26 additions & 13 deletions spec/controllers/invite_requests_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,14 @@

describe "GET #show" do
context "when given invalid emails" do
it "redirects to index with error" do
message = "You can search for the email address you signed up with below. If you can't find it, your invitation may have already been emailed to that address; please check your email spam folder as your spam filters may have placed it there."
get :show, params: { id: 0 }
it_redirects_to_with_error(status_invite_requests_path, message)
expect(assigns(:invite_request)).to be_nil
get :show, params: { id: 0, email: "[email protected]" }
it_redirects_to_with_error(status_invite_requests_path, message)
it "renders" do
get :show, params: { email: "[email protected]" }
expect(response).to render_template("show")
expect(assigns(:invite_request)).to be_nil
end

it "renders for an ajax call" do
get :show, params: { id: 0 }, xhr: true
expect(response).to render_template("show")
expect(assigns(:invite_request)).to be_nil
get :show, params: { id: 0, email: "[email protected]" }, xhr: true
get :show, params: { email: "[email protected]" }, xhr: true
expect(response).to render_template("show")
expect(assigns(:invite_request)).to be_nil
end
Expand All @@ -41,19 +34,39 @@
let(:invite_request) { create(:invite_request) }

it "renders" do
get :show, params: { id: 0, email: invite_request.email }
get :show, params: { email: invite_request.email }
expect(response).to render_template("show")
expect(assigns(:invite_request)).to eq(invite_request)
end

it "renders for an ajax call" do
get :show, params: { id: 0, email: invite_request.email }, xhr: true
get :show, params: { email: invite_request.email }, xhr: true
expect(response).to render_template("show")
expect(assigns(:invite_request)).to eq(invite_request)
end
end
end

describe "POST #resend" do
context "when the email doesn't match any invitations" do
it "redirects with an error" do
post :resend, params: { email: "[email protected]" }
it_redirects_to_with_error(status_invite_requests_path,
"Could not find an invitation associated with that email.")
end
end

context "when the invitation is too recent" do
let(:invitation) { create(:invitation) }

it "redirects with an error" do
post :resend, params: { email: invitation.invitee_email }
it_redirects_to_with_error(status_invite_requests_path,
"You cannot resend an invitation that was sent in the last 24 hours.")
end
end
end

describe "POST #create" do
it "redirects to index with error given invalid emails" do
post :create, params: { invite_request: { email: "wat" } }
Expand Down

0 comments on commit 0812a2a

Please sign in to comment.