Skip to content

Commit 87ada2d

Browse files
committed
BL-2008: Flip flop sessionless quickpay callback feature.
1 parent f1ef7d4 commit 87ada2d

File tree

3 files changed

+116
-32
lines changed

3 files changed

+116
-32
lines changed

app/controllers/concerns/quik_pay.rb

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module QuikPay
77
ERROR_MESSAGE = "There was a problem with your transaction. Please call 215-204-8212."
88

99
included do
10-
before_action :authenticate_user!, only: [ :quik_pay ]
10+
before_action :authenticate_quik_pay_user!, only: [:quik_pay, :quik_pay_callback]
1111

1212
rescue_from ::QuikPay::AccessDenied do |exception|
1313
Honeybadger.notify(exception)
@@ -38,7 +38,7 @@ def quik_pay_callback
3838
validate_quik_pay_timestamp(params["timestamp"])
3939
validate_quik_pay_trasaction_status(params["transactionStatus"])
4040

41-
user_id = current_user&.uid || params["orderNumber"]
41+
user_id = quik_pay_user_id
4242
log = { type: "alma_pay", user: user_id, transactionStatus: params["transactionStatus"] }
4343

4444
# The return value for the do_with_json_logger block should implement Loggable.
@@ -58,7 +58,7 @@ def quik_pay_url(params = {}, secret = "")
5858
orderType: "Temple Library",
5959
timestamp: DateTime.now.strftime("%Q").to_i,
6060
redirectUrl: Rails.configuration.quik_pay["redirect_url"],
61-
redirectUrlParameters: "transactionStatus,transactionTotalAmount,orderNumber",
61+
redirectUrlParameters: quik_pay_redirect_url_parameters,
6262
)
6363

6464
# Use fixed params and order. This order MUST NOT be ammended or feature will stop working.
@@ -103,6 +103,27 @@ class InvalidBalance < StandardError
103103
class InvalidTransaction < StandardError
104104
end
105105

106+
def authenticate_quik_pay_user!
107+
if params[:action] == "quik_pay_callback" && Flipflop.quik_pay_sessionless_callback?
108+
return
109+
end
110+
111+
authenticate_user!
112+
end
113+
114+
def quik_pay_user_id
115+
return current_user&.uid || params["orderNumber"] if Flipflop.quik_pay_sessionless_callback?
116+
117+
current_user.uid
118+
end
119+
120+
def quik_pay_redirect_url_parameters
121+
base_params = "transactionStatus,transactionTotalAmount"
122+
return base_params unless Flipflop.quik_pay_sessionless_callback?
123+
124+
"#{base_params},orderNumber"
125+
end
126+
106127
def validate_quik_pay_timestamp(timestamp)
107128
raise InvalidTime.new("A timestamp is required. This probably means this is an invalid attempt at using quikpay.") if timestamp.nil?
108129

config/features.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@
1414
group :citations do
1515
feature :citeproc_citations
1616
end
17+
18+
group :quik_pay do
19+
feature :quik_pay_sessionless_callback
20+
end
1721
end

spec/controllers/quik_pay_spec.rb

Lines changed: 88 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,44 +32,72 @@
3232
end
3333

3434
describe "quik_pay_url" do
35-
context "no arguments" do
35+
shared_examples "quik pay redirect parameters" do
3636
it "generates a url with only default params" do
37-
expect(controller.quik_pay_url).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
37+
expect(controller.quik_pay_url).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=#{redirect_params}&timestamp=.*&hash=.*$/)
3838
end
39-
end
4039

41-
context "with param as args" do
4240
it "does not diviate from the order URL contrat" do
43-
expect(controller.quik_pay_url(foo: "bar")).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
41+
expect(controller.quik_pay_url(foo: "bar")).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=#{redirect_params}&timestamp=.*&hash=.*$/)
4442
end
45-
end
4643

47-
context "with param as args + secret" do
4844
it "generates a url with params" do
49-
expect(controller.quik_pay_url({ foo: "bar" }, "buzz")).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
45+
expect(controller.quik_pay_url({ foo: "bar" }, "buzz")).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=#{redirect_params}&timestamp=.*&hash=.*$/)
5046
end
5147
end
48+
49+
context "when quik pay sessionless callback is disabled" do
50+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(false) }
51+
let(:redirect_params) { "transactionStatus%2CtransactionTotalAmount" }
52+
53+
include_examples "quik pay redirect parameters"
54+
end
55+
56+
context "when quik pay sessionless callback is enabled" do
57+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(true) }
58+
let(:redirect_params) { "transactionStatus%2CtransactionTotalAmount%2CorderNumber" }
59+
60+
include_examples "quik pay redirect parameters"
61+
end
5262
end
5363

5464
describe "GET #quik_pay_callback" do
55-
context "user is not logged in but parameters are valid" do
56-
let (:params) { with_validation_params(transactionStatus: "1") }
57-
before(:each) do
58-
resp = OpenStruct.new(total_sum: 0.0)
59-
balance = Alma::PaymentResponse.new(resp)
60-
allow(Alma::User).to receive(:send_payment) { balance }
61-
end
65+
context "when quik pay sessionless callback is disabled" do
66+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(false) }
67+
68+
context "user is not logged in" do
69+
it "redirects you to login page" do
70+
get :quik_pay_callback
71+
expect(response).to redirect_to new_user_session_path
6272

63-
it "redirects GET requests to the users account page with success notice" do
64-
get(:quik_pay_callback, params:)
65-
expect(response).to redirect_to users_account_path
66-
expect(flash[:notice]).to include("Your fees have been paid.");
73+
post :quik_pay_callback
74+
expect(response).to redirect_to new_user_session_path
75+
end
6776
end
77+
end
78+
79+
context "when quik pay sessionless callback is enabled" do
80+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(true) }
81+
82+
context "user is not logged in but parameters are valid" do
83+
let (:params) { with_validation_params(transactionStatus: "1") }
84+
before(:each) do
85+
resp = OpenStruct.new(total_sum: 0.0)
86+
balance = Alma::PaymentResponse.new(resp)
87+
allow(Alma::User).to receive(:send_payment) { balance }
88+
end
89+
90+
it "redirects GET requests to the users account page with success notice" do
91+
get(:quik_pay_callback, params:)
92+
expect(response).to redirect_to users_account_path
93+
expect(flash[:notice]).to include("Your fees have been paid.");
94+
end
6895

69-
it "redirects POST requests to the users account page with success notice" do
70-
post(:quik_pay_callback, params:)
71-
expect(response).to redirect_to users_account_path
72-
expect(flash[:notice]).to include("Your fees have been paid.");
96+
it "redirects POST requests to the users account page with success notice" do
97+
post(:quik_pay_callback, params:)
98+
expect(response).to redirect_to users_account_path
99+
expect(flash[:notice]).to include("Your fees have been paid.");
100+
end
73101
end
74102
end
75103

@@ -194,20 +222,51 @@
194222
end
195223

196224
context "user can pay online" do
197-
it "redirects to users account paths" do
225+
before do
198226
session["can_pay_online?"] = true;
199-
get :quik_pay
200-
expect(response.location).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
227+
end
228+
229+
context "when quik pay sessionless callback is disabled" do
230+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(false) }
231+
232+
it "redirects to users account paths" do
233+
get :quik_pay
234+
expect(response.location).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount&timestamp=.*&hash=.*$/)
235+
end
236+
end
237+
238+
context "when quik pay sessionless callback is enabled" do
239+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(true) }
240+
241+
it "redirects to users account paths" do
242+
get :quik_pay
243+
expect(response.location).to match(/quikpay.*?orderNumber=.*&orderType=Temple%20Library&amountDue=.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
244+
end
201245
end
202246
end
203247

204248
context "the fine has cent amounts" do
205-
it "does not lose precision when coverting total_fines to cents" do
249+
before do
206250
session["can_pay_online?"] = true;
207251
session["total_fines"] = "25.11"
252+
end
208253

209-
get :quik_pay
210-
expect(response.location).to match(/#{Rails.configuration.quik_pay["url"]}.*orderNumber=.*&orderType=Temple%20Library&amountDue=2511.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
254+
context "when quik pay sessionless callback is disabled" do
255+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(false) }
256+
257+
it "does not lose precision when converting total_fines to cents" do
258+
get :quik_pay
259+
expect(response.location).to match(/#{Rails.configuration.quik_pay["url"]}.*orderNumber=.*&orderType=Temple%20Library&amountDue=2511.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount&timestamp=.*&hash=.*$/)
260+
end
261+
end
262+
263+
context "when quik pay sessionless callback is enabled" do
264+
before { allow(Flipflop).to receive(:quik_pay_sessionless_callback?).and_return(true) }
265+
266+
it "does not lose precision when converting total_fines to cents" do
267+
get :quik_pay
268+
expect(response.location).to match(/#{Rails.configuration.quik_pay["url"]}.*orderNumber=.*&orderType=Temple%20Library&amountDue=2511.*&redirectUrl=.*&redirectUrlParameters=transactionStatus%2CtransactionTotalAmount%2CorderNumber&timestamp=.*&hash=.*$/)
269+
end
211270
end
212271
end
213272

0 commit comments

Comments
 (0)