Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Result pattern to exceptions #395

Merged
merged 2 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
23 changes: 11 additions & 12 deletions rails_application/app/services/orders/submit_service.rb
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
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)
if unavailable_products.any?
raise OrderHasUnavailableProducts.new(unavailable_products)
end
rescue Ordering::Order::IsEmpty
Result.new(:order_is_empty)
rescue Crm::Customer::NotExists
Result.new(:customer_not_exists)
end

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

This file was deleted.

36 changes: 9 additions & 27 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,12 @@ 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
Orders::SubmitService.new(order_id: order_id, customer_id: customer_id).call

assert_equal result.status, :success
order = Order.find_by!(uid: order_id)

assert_equal "Submitted", order.state
assert_equal "John Doe", order.customer
end

def test_order_submission_with_unavailable_products
Expand All @@ -32,32 +35,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.

Loading