Skip to content

Commit 5f383fc

Browse files
committed
add Offer lifecycle guards, more Offer tests
1 parent 8fd34dd commit 5f383fc

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

ecommerce/pricing/lib/pricing/offer.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Pricing
22
class Offer
33
include AggregateRoot
44

5+
InvalidState = Class.new(StandardError)
56
IsEmpty = Class.new(StandardError)
67

78
def initialize(id)
@@ -129,6 +130,7 @@ def use_coupon(coupon_id, discount)
129130

130131
def accept
131132
raise IsEmpty if @list.products.empty?
133+
raise InvalidState.new("Only draft offer can be accepted") unless @state == :draft
132134
apply OfferAccepted.new(
133135
data: {
134136
order_id: @id,
@@ -138,10 +140,12 @@ def accept
138140
end
139141

140142
def reject
143+
raise InvalidState.new("Only accepted offer can be rejected") unless @state == :accepted
141144
apply OfferRejected.new(data: { order_id: @id })
142145
end
143146

144147
def expire
148+
raise InvalidState.new("Only draft offer can be expired") unless @state == :draft
145149
apply OfferExpired.new(data: { order_id: @id })
146150
end
147151

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
require_relative 'test_helper'
2+
3+
module Pricing
4+
class OfferLifecycleTest < Test
5+
cover "Pricing*"
6+
7+
def test_accept_draft_offer
8+
product_id = SecureRandom.uuid
9+
order_id = SecureRandom.uuid
10+
11+
set_price(product_id, 33)
12+
add_item(order_id, product_id)
13+
stream = "Pricing::Offer$#{order_id}"
14+
15+
assert_events(
16+
stream,
17+
OfferAccepted.new(
18+
data: {
19+
order_id: order_id,
20+
order_lines: [
21+
{ product_id:, quantity: 1 },
22+
]
23+
}
24+
)
25+
) { accept_offer(order_id) }
26+
end
27+
28+
def test_empty_offer_cant_be_accepted
29+
order_id = SecureRandom.uuid
30+
31+
assert_raises(Pricing::Offer::IsEmpty) do
32+
accept_offer(order_id)
33+
end
34+
end
35+
36+
def test_accepted_offer_can_be_rejected
37+
product_id = SecureRandom.uuid
38+
order_id = SecureRandom.uuid
39+
40+
set_price(product_id, 33)
41+
add_item(order_id, product_id)
42+
accept_offer(order_id)
43+
stream = "Pricing::Offer$#{order_id}"
44+
45+
46+
assert_events(
47+
stream,
48+
OfferRejected.new(
49+
data: {
50+
order_id: order_id,
51+
}
52+
)
53+
) { reject_offer(order_id) }
54+
55+
end
56+
57+
def test_draft_offer_cant_be_rejected
58+
product_id = SecureRandom.uuid
59+
order_id = SecureRandom.uuid
60+
61+
set_price(product_id, 33)
62+
add_item(order_id, product_id)
63+
64+
exp = assert_raises(Pricing::Offer::InvalidState, "Only accepted offer can be rejected") do
65+
reject_offer(order_id)
66+
end
67+
assert_equal("Only accepted offer can be rejected", exp.message)
68+
end
69+
70+
def test_draft_offer_can_be_expired
71+
product_id = SecureRandom.uuid
72+
order_id = SecureRandom.uuid
73+
74+
set_price(product_id, 33)
75+
add_item(order_id, product_id)
76+
stream = "Pricing::Offer$#{order_id}"
77+
78+
assert_events(
79+
stream,
80+
OfferExpired.new(
81+
data: {
82+
order_id: order_id,
83+
}
84+
)
85+
) { expire_offer(order_id) }
86+
end
87+
88+
def test_accepted_offer_cant_be_expired
89+
product_id = SecureRandom.uuid
90+
order_id = SecureRandom.uuid
91+
92+
set_price(product_id, 33)
93+
add_item(order_id, product_id)
94+
accept_offer(order_id)
95+
96+
exp = assert_raises(Pricing::Offer::InvalidState) do
97+
expire_offer(order_id)
98+
end
99+
assert_equal("Only draft offer can be expired", exp.message)
100+
end
101+
102+
def test_only_draft_offer_can_be_accepted
103+
product_id = SecureRandom.uuid
104+
order_id = SecureRandom.uuid
105+
106+
set_price(product_id, 33)
107+
add_item(order_id, product_id)
108+
accept_offer(order_id)
109+
110+
exp = assert_raises(Pricing::Offer::InvalidState) do
111+
accept_offer(order_id)
112+
end
113+
assert_equal("Only draft offer can be accepted", exp.message)
114+
end
115+
116+
private
117+
118+
def accept_offer(order_id)
119+
run_command(AcceptOffer.new(order_id:))
120+
end
121+
122+
def reject_offer(order_id)
123+
run_command(RejectOffer.new(order_id:))
124+
end
125+
126+
def expire_offer(order_id)
127+
run_command(ExpireOffer.new(order_id:))
128+
end
129+
end
130+
end

0 commit comments

Comments
 (0)