Skip to content

Commit 555a3fe

Browse files
committed
Reject invalid coupon discount
1 parent c088a40 commit 555a3fe

File tree

4 files changed

+61
-7
lines changed

4 files changed

+61
-7
lines changed

ecommerce/pricing/test/coupons_test.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,19 @@ def test_100_is_ok
3636
def test_0_01_is_ok
3737
register_coupon(@uid, fake_name, @code, "0.01")
3838
end
39+
40+
def test_negative_discount_is_rejected
41+
assert_raises(Infra::Command::Invalid) do
42+
register_coupon(@uid, fake_name, @code, -0.01)
43+
end
44+
end
45+
46+
def test_negative_discount_string_is_rejected
47+
assert_raises(Infra::Command::Invalid) do
48+
register_coupon(@uid, fake_name, @code, "-150")
49+
end
50+
end
51+
52+
3953
end
4054
end

rails_application/app/controllers/coupons_controller.rb

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@ def new
88
end
99

1010
def create
11-
coupon_id = params[:coupon_id]
11+
@coupon_id = params[:coupon_id].presence || SecureRandom.uuid
12+
13+
discount = validated_discount(params[:discount])
14+
return render_invalid_discount unless discount
1215

1316
ActiveRecord::Base.transaction do
14-
create_coupon(coupon_id)
17+
create_coupon(@coupon_id, discount)
1518
end
1619
rescue Pricing::Coupon::AlreadyRegistered
1720
flash[:notice] = "Coupon is already registered"
@@ -22,13 +25,13 @@ def create
2225

2326
private
2427

25-
def create_coupon(coupon_id)
28+
def create_coupon(coupon_id,discount)
2629
command_bus.(
2730
Pricing::RegisterCoupon.new(
2831
coupon_id: coupon_id,
2932
name: params[:name],
3033
code: params[:code],
31-
discount: params[:discount]
34+
discount: discount
3235
)
3336
)
3437
command_bus.(
@@ -39,4 +42,20 @@ def create_coupon(coupon_id)
3942
)
4043
end
4144

45+
def validated_discount(raw)
46+
return nil if raw.blank?
47+
48+
value = BigDecimal(raw.to_s)
49+
return nil unless value > 0 && value <= 100
50+
51+
value
52+
rescue ArgumentError
53+
nil
54+
end
55+
56+
def render_invalid_discount
57+
flash.now[:alert] = "Discount must be greater than 0 and less than or equal to 100"
58+
render "new", status: :unprocessable_entity
59+
end
60+
4261
end

rails_application/app/views/coupons/new.html.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@
1818
<label for="coupon" class="block font-bold">
1919
Name
2020
</label>
21-
<%= text_field_tag :name, "", required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
21+
<%= text_field_tag :name, params[:name], required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
2222

2323
<label for="coupon" class="block font-bold">
2424
Code
2525
</label>
26-
<%= text_field_tag :code, "", required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
26+
<%= text_field_tag :code, params[:code], required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
2727

2828
<label for="coupon" class="block font-bold">
2929
Discount
3030
</label>
31-
<%= number_field_tag :discount, nil, min: 1, max: 100, step: 0.01, id: "discount", required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
31+
<%= number_field_tag :discount, params[:discount], min: 1, max: 100, step: 0.01, id: "discount", required: true, class: "mt-1 focus:ring-blue-500 focus:border-blue-500 block shadow-sm sm:text-sm border-gray-300 rounded-md" %>
3232
<% end %>

rails_application/test/integration/coupons_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@ def test_creation
2323
assert_select("td", "6.69")
2424
end
2525

26+
def test_creation_with_negative_discount_is_rejected
27+
register_store("Test Store")
28+
29+
get "/coupons/new"
30+
coupon_id = css_select("input[name='coupon_id']").first["value"]
31+
32+
post "/coupons", params: {
33+
coupon_id: coupon_id,
34+
name: "Bad Coupon",
35+
code: "NEG",
36+
discount: "-150"
37+
}
38+
39+
assert_response :unprocessable_entity
40+
41+
get "/coupons"
42+
assert_response :success
43+
assert_select("td", text: "Bad Coupon", count: 0)
44+
assert_select("td", text: "NEG", count: 0)
45+
end
46+
2647
private
2748

2849
def register_coupon(name, code, discount)

0 commit comments

Comments
 (0)