Skip to content

Commit 129c595

Browse files
authored
Merge pull request #6634 from rubyforgood/fix-invite-accept
Fix invite accept
2 parents 1d17bbf + 0a40488 commit 129c595

File tree

4 files changed

+416
-1
lines changed

4 files changed

+416
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Users::InvitationsController < Devise::InvitationsController
2+
# Override the edit action to ensure the invitation_token is properly set in the form
3+
def edit
4+
self.resource = resource_class.new
5+
set_minimum_password_length if respond_to?(:set_minimum_password_length, true)
6+
resource.invitation_token = params[:invitation_token]
7+
render :edit
8+
end
9+
end

config/routes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
mount Rswag::Api::Engine => "/api-docs"
66

77
devise_for :all_casa_admins, path: "all_casa_admins", controllers: {sessions: "all_casa_admins/sessions"}
8-
devise_for :users, controllers: {sessions: "users/sessions", passwords: "users/passwords"}
8+
devise_for :users, controllers: {sessions: "users/sessions", passwords: "users/passwords", invitations: "users/invitations"}
99
authenticate :all_casa_admins do
1010
mount PgHero::Engine, at: "pg_dashboard", constraints: lambda { |request|
1111
admin = request.env["warden"].user(:all_casa_admin)
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
require "rails_helper"
2+
3+
RSpec.describe "Users::InvitationsController", type: :request do
4+
let(:casa_org) { create(:casa_org) }
5+
let(:admin) { create(:casa_admin, casa_org: casa_org) }
6+
let(:volunteer) { create(:volunteer, casa_org: casa_org) }
7+
8+
describe "GET /users/invitation/accept" do
9+
context "with valid invitation token" do
10+
let(:invitation_token) do
11+
volunteer.invite!(admin)
12+
volunteer.raw_invitation_token
13+
end
14+
15+
it "renders the invitation acceptance form" do
16+
get accept_user_invitation_path(invitation_token: invitation_token)
17+
18+
expect(response).to have_http_status(:success)
19+
expect(response.body).to include("Set my password")
20+
end
21+
22+
it "sets the invitation_token on the resource" do
23+
get accept_user_invitation_path(invitation_token: invitation_token)
24+
25+
# Check that the hidden field contains the token
26+
expect(response.body).to include('name="user[invitation_token]"')
27+
expect(response.body).to include("value=\"#{invitation_token}\"")
28+
end
29+
end
30+
31+
context "without invitation token" do
32+
it "redirects to root path" do
33+
get accept_user_invitation_path
34+
35+
expect(response).to redirect_to(root_path)
36+
end
37+
end
38+
end
39+
40+
describe "PUT /users/invitation" do
41+
let(:invitation_token) do
42+
volunteer.invite!(admin)
43+
volunteer.raw_invitation_token
44+
end
45+
46+
context "with valid password" do
47+
let(:params) do
48+
{
49+
user: {
50+
invitation_token: invitation_token,
51+
password: "SecurePassword123!",
52+
password_confirmation: "SecurePassword123!"
53+
}
54+
}
55+
end
56+
57+
it "accepts the invitation" do
58+
put user_invitation_path, params: params
59+
60+
volunteer.reload
61+
expect(volunteer.invitation_accepted_at).not_to be_nil
62+
end
63+
64+
it "redirects to the dashboard" do
65+
put user_invitation_path, params: params
66+
67+
expect(response).to redirect_to(root_path)
68+
end
69+
70+
it "signs in the user" do
71+
put user_invitation_path, params: params
72+
73+
# Follow redirects until we reach the final authenticated page
74+
follow_redirect! while response.status == 302
75+
76+
# User should be on an authenticated page
77+
expect(response).to have_http_status(:success)
78+
end
79+
end
80+
81+
context "with mismatched passwords" do
82+
let(:params) do
83+
{
84+
user: {
85+
invitation_token: invitation_token,
86+
password: "SecurePassword123!",
87+
password_confirmation: "DifferentPassword456!"
88+
}
89+
}
90+
end
91+
92+
it "does not accept the invitation" do
93+
put user_invitation_path, params: params
94+
95+
volunteer.reload
96+
expect(volunteer.invitation_accepted_at).to be_nil
97+
end
98+
99+
it "renders the edit page with errors" do
100+
put user_invitation_path, params: params
101+
102+
expect(response).to have_http_status(:ok)
103+
expect(response.body).to include("Password confirmation doesn&#39;t match")
104+
end
105+
end
106+
107+
context "with password too short" do
108+
let(:params) do
109+
{
110+
user: {
111+
invitation_token: invitation_token,
112+
password: "short",
113+
password_confirmation: "short"
114+
}
115+
}
116+
end
117+
118+
it "does not accept the invitation" do
119+
put user_invitation_path, params: params
120+
121+
volunteer.reload
122+
expect(volunteer.invitation_accepted_at).to be_nil
123+
end
124+
125+
it "renders the edit page with errors" do
126+
put user_invitation_path, params: params
127+
128+
expect(response).to have_http_status(:ok)
129+
expect(response.body).to include("Password is too short")
130+
end
131+
end
132+
133+
context "with blank password" do
134+
let(:params) do
135+
{
136+
user: {
137+
invitation_token: invitation_token,
138+
password: "",
139+
password_confirmation: ""
140+
}
141+
}
142+
end
143+
144+
it "does not accept the invitation" do
145+
put user_invitation_path, params: params
146+
147+
volunteer.reload
148+
expect(volunteer.invitation_accepted_at).to be_nil
149+
end
150+
151+
it "renders the edit page with errors" do
152+
put user_invitation_path, params: params
153+
154+
expect(response).to have_http_status(:ok)
155+
expect(response.body).to include("can&#39;t be blank")
156+
end
157+
end
158+
159+
context "without invitation token" do
160+
let(:params) do
161+
{
162+
user: {
163+
password: "SecurePassword123!",
164+
password_confirmation: "SecurePassword123!"
165+
}
166+
}
167+
end
168+
169+
it "does not accept the invitation" do
170+
put user_invitation_path, params: params
171+
172+
volunteer.reload
173+
expect(volunteer.invitation_accepted_at).to be_nil
174+
end
175+
176+
it "renders the edit page with errors" do
177+
put user_invitation_path, params: params
178+
179+
expect(response).to have_http_status(:ok)
180+
expect(response.body).to include("Invitation token can&#39;t be blank")
181+
end
182+
end
183+
end
184+
end

0 commit comments

Comments
 (0)