Skip to content

Commit

Permalink
Change Result pattern to exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
marlena-b committed Sep 5, 2024
1 parent 690d65d commit e6c1ab2
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 114 deletions.
4 changes: 2 additions & 2 deletions ecommerce/processes/lib/processes/reservation_process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def call(event)
state = build_state(event)
case event.event_type
when 'Ordering::OrderSubmitted'
order_side_effects(state) { reserve_stock(state) }
update_order_state(state) { reserve_stock(state) }
when 'Fulfillment::OrderCancelled'
release_stock(state)
when 'Fulfillment::OrderConfirmed'
Expand Down Expand Up @@ -38,7 +38,7 @@ def reserve_stock(state)
event_store.publish(event, stream_name: stream_name(state.order_id))
end

def order_side_effects(state)
def update_order_state(state)
event_store
.within { yield }
.subscribe(to: ReservationProcessFailed) { reject_order(state) }
Expand Down
14 changes: 8 additions & 6 deletions rails_application/app/controllers/client/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ def new
end

def create
Orders::SubmitService.new(order_id: params[:order_id], customer_id: cookies[:client_id]).call.then do |result|
result.path(:success) { redirect_to client_order_path(params[:order_id]), notice: "Your order is being submitted" }
result.path(:products_out_of_stock) { |unavailable_products| redirect_to edit_client_order_path(params[:order_id]),
alert: "Order can not be submitted! #{unavailable_products.join(", ")} not available in requested quantity!"}
result.path(:order_is_empty) { redirect_to edit_client_order_path(params[:order_id]), alert: "You can't submit an empty order" }
end
Orders::SubmitService.new(order_id: params[:order_id], customer_id: cookies[:client_id]).call
rescue Orders::OrderHasUnavailableProducts => e
unavailable_products = e.unavailable_products.join(", ")
redirect_to edit_client_order_path(params[:order_id]), alert: "Order can not be submitted! #{unavailable_products} not available in requested quantity!"
rescue Ordering::Order::IsEmpty
redirect_to edit_client_order_path(params[:order_id]), alert: "You can't submit an empty order"
else
redirect_to client_order_path(params[:order_id]), notice: "Your order is being submitted"
end

def show
Expand Down
17 changes: 10 additions & 7 deletions rails_application/app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,16 @@ def remove_item
end

def create
Orders::SubmitService.new(order_id: params[:order_id], customer_id: params[:customer_id]).call.then do |result|
result.path(:success) { redirect_to order_path(params[:order_id]), notice: "Your order is being submitted" }
result.path(:products_out_of_stock) { |unavailable_products| redirect_to edit_order_path(params[:order_id]),
alert: "Order can not be submitted! #{unavailable_products.join(", ")} not available in requested quantity!"}
result.path(:order_is_empty) { redirect_to edit_order_path(params[:order_id]), alert: "You can't submit an empty order" }
result.path(:customer_not_exists) { redirect_to order_path(params[:order_id]), alert: "Order can not be submitted! Customer does not exist." }
end
Orders::SubmitService.new(order_id: params[:order_id], customer_id: params[:customer_id]).call
rescue Orders::OrderHasUnavailableProducts => e
unavailable_products = e.unavailable_products.join(", ")
redirect_to edit_order_path(params[:order_id]), alert: "Order can not be submitted! #{unavailable_products} not available in requested quantity!"
rescue Ordering::Order::IsEmpty
redirect_to edit_order_path(params[:order_id]), alert: "You can't submit an empty order"
rescue Crm::Customer::NotExists
redirect_to order_path(params[:order_id]), alert: "Order can not be submitted! Customer does not exist."
else
redirect_to order_path(params[:order_id]), notice: "Your order is being submitted"
end

def expire
Expand Down
26 changes: 13 additions & 13 deletions rails_application/app/services/orders/submit_service.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
module Orders
class OrderHasUnavailableProducts < StandardError
attr_reader :unavailable_products

def initialize(unavailable_products)
@unavailable_products = unavailable_products
end
end

class SubmitService < ApplicationService
def initialize(order_id:, customer_id:)
@order_id = order_id
@customer_id = customer_id
end

def call
success = true
unavailable_products = nil

unavailable_products = []
event_store
.within { submit_order }
.subscribe(to: Processes::ReservationProcessFailed) do |event|
success = false
unavailable_products = Products::Product.where(id: event.data.fetch(:unavailable_products)).pluck(:name)
end
.call

if success
Result.new(:success)
else
Result.new(:products_out_of_stock, unavailable_products)
end
rescue Ordering::Order::IsEmpty
Result.new(:order_is_empty)
rescue Crm::Customer::NotExists
Result.new(:customer_not_exists)
if unavailable_products.any?
raise OrderHasUnavailableProducts.new(unavailable_products)
end
true
end

private
Expand Down
14 changes: 0 additions & 14 deletions rails_application/app/services/result.rb

This file was deleted.

33 changes: 5 additions & 28 deletions rails_application/test/services/orders/submit_service_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ def test_successful_order_submission
prepare_product(product_id, "Async Remote", 49)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))

result = Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call

assert_equal result.status, :success
assert_equal true, Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call
end

def test_order_submission_with_unavailable_products
Expand All @@ -32,32 +30,11 @@ def test_order_submission_with_unavailable_products
prepare_product(another_product_id, "Fearless Refactoring", 49)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: another_product_id))

result = Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call

assert_equal result.status, :products_out_of_stock
assert_equal result.args, [["Async Remote"]]
end

def test_order_submission_with_empty_order
order_id = SecureRandom.uuid
customer_id = SecureRandom.uuid

result = Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call

assert_equal result.status, :order_is_empty
end

def test_order_submission_with_non_existing_customer
order_id = SecureRandom.uuid
customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid

prepare_product(product_id, "Async Remote", 49)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))

result = Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call
error = assert_raises(Orders::OrderHasUnavailableProducts) do
Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call
end

assert_equal result.status, :customer_not_exists
assert_equal ["Async Remote"], error.unavailable_products
end

private
Expand Down
44 changes: 0 additions & 44 deletions rails_application/test/services/result_test.rb

This file was deleted.

0 comments on commit e6c1ab2

Please sign in to comment.