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

Prevent empty order submission #384

Merged
merged 1 commit into from
Aug 23, 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
6 changes: 6 additions & 0 deletions ecommerce/ordering/lib/ordering/order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class Order
AlreadySubmitted = Class.new(InvalidState)
NotPlaced = Class.new(InvalidState)
OrderHasExpired = Class.new(InvalidState)
IsEmpty = Class.new(StandardError)

def initialize(id)
@id = id
Expand All @@ -16,6 +17,7 @@ def initialize(id)
def submit(order_number)
raise OrderHasExpired if @state.expired?
raise AlreadySubmitted unless @state.draft?
raise IsEmpty if @basket.empty?
apply OrderSubmitted.new(
data: {
order_id: @id,
Expand Down Expand Up @@ -111,6 +113,10 @@ def order_lines
def quantity(product_id)
order_lines[product_id]
end

def empty?
order_lines.empty?
end
end

class State
Expand Down
8 changes: 5 additions & 3 deletions ecommerce/ordering/test/order_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ def setup
@customer_id = SecureRandom.uuid
end

def test_order_lines_are_empty_after_adding_and_removing
def test_order_is_empty_after_adding_and_removing
order = Order.new(@order_id)
order.add_item(@product_id)
order.remove_item(@product_id)
order.submit(NumberGenerator.new.call)
assert_equal({}, order.unpublished_events.to_a.last.data[:order_lines])

assert_raises(Order::IsEmpty) do
order.submit(NumberGenerator.new.call)
end
end

def test_order_lines_with_the_same_product_twice
Expand Down
8 changes: 8 additions & 0 deletions ecommerce/ordering/test/submit_order_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,13 @@ def test_expired_order_could_not_be_created
act(SubmitOrder.new(order_id: aggregate_id))
end
end

def test_empty_order_cannot_be_submitted
aggregate_id = SecureRandom.uuid

assert_raises(Order::IsEmpty) do
act(SubmitOrder.new(order_id: aggregate_id))
end
end
end
end
11 changes: 7 additions & 4 deletions rails_application/app/controllers/client/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ def new
end

def create
command_bus.(Ordering::SubmitOrder.new(order_id: params[:order_id]))
command_bus.(Crm::AssignCustomerToOrder.new(customer_id: cookies[:client_id], order_id: params[:order_id]))
redirect_to client_order_path(params[:order_id]),
notice: "Your order is being submitted"
ActiveRecord::Base.transaction do
command_bus.(Ordering::SubmitOrder.new(order_id: params[:order_id]))
command_bus.(Crm::AssignCustomerToOrder.new(customer_id: cookies[:client_id], order_id: params[:order_id]))
end
redirect_to client_order_path(params[:order_id]), notice: "Your order is being submitted"
rescue Ordering::Order::IsEmpty
redirect_to edit_client_order_path(params[:order_id]), alert: "You can't submit an empty order"
end

def show
Expand Down
2 changes: 2 additions & 0 deletions rails_application/app/controllers/orders_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ def remove_item
def create
ApplicationRecord.transaction { submit_order(params[:order_id], params[:customer_id]) }
redirect_to order_path(params[:order_id]), notice: "Your order is being submitted"
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."
end
Expand Down
13 changes: 12 additions & 1 deletion rails_application/test/client_orders/order_cancelled_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def test_order_confirmed
customer_id = SecureRandom.uuid
order_id = SecureRandom.uuid
order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER
product_id = SecureRandom.uuid

event_store.publish(Crm::CustomerRegistered.new(
data: {
Expand All @@ -23,6 +24,8 @@ def test_order_confirmed
}
))

create_product(product_id, "Async Remote", 30)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))
run_command(Ordering::SubmitOrder.new(order_id: order_id, order_number: order_number))

event_store.publish(
Expand All @@ -39,5 +42,13 @@ def test_order_confirmed
assert_equal(order_number, orders.first.number)
assert_equal("Cancelled", orders.first.state)
end

private

def create_product(product_id, name, price)
run_command(ProductCatalog::RegisterProduct.new(product_id: product_id))
run_command(ProductCatalog::NameProduct.new(product_id: product_id, name: name))
run_command(Pricing::SetPrice.new(product_id: product_id, price: price))
end
end
end
end
11 changes: 11 additions & 0 deletions rails_application/test/client_orders/order_paid_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ def test_order_confirmed
customer_id = SecureRandom.uuid
order_id = SecureRandom.uuid
order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER
product_id = SecureRandom.uuid

run_command(Crm::RegisterCustomer.new(customer_id: customer_id, name: "John Doe"))
create_product(product_id, "Async Remote", 30)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))

event_store.publish(
Pricing::OrderTotalValueCalculated.new(
Expand Down Expand Up @@ -48,5 +51,13 @@ def test_order_confirmed
assert_equal(order_number, orders.first.number)
assert_equal("Paid", orders.first.state)
end

private

def create_product(product_id, name, price)
run_command(ProductCatalog::RegisterProduct.new(product_id: product_id))
run_command(ProductCatalog::NameProduct.new(product_id: product_id, name: name))
run_command(Pricing::SetPrice.new(product_id: product_id, price: price))
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@ def setup
Client.destroy_all
end

def test_update_orders_cummary
event_store = Rails.configuration.event_store
def test_update_orders_summary
customer_id = SecureRandom.uuid
other_customer_id = SecureRandom.uuid
product_id = SecureRandom.uuid
order_id = SecureRandom.uuid

register_product(product_id)
name_product(product_id, "Async Remote")
set_price_to_product(product_id, 3)
register_customer(other_customer_id)
register_customer(customer_id)
add_item_to_basket(order_id, product_id)
confirm_order(customer_id, order_id, 3)

customer = Client.find_by(uid: customer_id)
assert_equal 3.to_d, customer.paid_orders_summary

order_id = SecureRandom.uuid
add_item_to_basket(order_id, product_id)
add_item_to_basket(order_id, product_id)
confirm_order(customer_id, order_id, 6)

customer = Client.find_by(uid: customer_id)
Expand All @@ -36,6 +41,27 @@ def register_customer(customer_id)
run_command(Crm::RegisterCustomer.new(customer_id: customer_id, name: "John Doe"))
end

def register_product(product_id)
run_command(ProductCatalog::RegisterProduct.new(product_id: product_id))
end

def name_product(product_id, name)
run_command(
ProductCatalog::NameProduct.new(
product_id: product_id,
name: name
)
)
end

def set_price_to_product(product_id, price)
run_command(Pricing::SetPrice.new(product_id: product_id, price: price))
end

def add_item_to_basket(order_id, product_id)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))
end

def confirm_order(customer_id, order_id, total_amount)
order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER
event_store.publish(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ def test_update_orders_summary
customer_id = SecureRandom.uuid
other_customer_id = SecureRandom.uuid
order_id = SecureRandom.uuid
product_id = SecureRandom.uuid

register_customer(other_customer_id)
register_customer(customer_id)
register_product(product_id)
name_product(product_id, "Async Remote")
set_price_to_product(product_id, 3)
add_item_to_basket(order_id, product_id)
confirm_order(customer_id, order_id, 3)

customer = Customer.find(customer_id)
assert_equal 3.to_d, customer.paid_orders_summary

order_id = SecureRandom.uuid
add_item_to_basket(order_id, product_id)
add_item_to_basket(order_id, product_id)
confirm_order(customer_id, order_id, 6)

customer = Customer.find(customer_id)
Expand All @@ -34,6 +41,22 @@ def register_customer(customer_id)
run_command(Crm::RegisterCustomer.new(customer_id: customer_id, name: "John Doe"))
end

def register_product(product_id)
run_command(ProductCatalog::RegisterProduct.new(product_id: product_id))
end

def name_product(product_id, name)
run_command(ProductCatalog::NameProduct.new(product_id: product_id, name: "Async Remote"))
end

def set_price_to_product(product_id, price)
run_command(Pricing::SetPrice.new(product_id: product_id, price: price))
end

def add_item_to_basket(order_id, product_id)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))
end

def confirm_order(customer_id, order_id, total_amount)
order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER
event_store.publish(
Expand Down
14 changes: 14 additions & 0 deletions rails_application/test/integration/client_orders_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ def test_adding_product_which_is_not_available_in_requested_quantity
assert_equal "Product not available in requested quantity!", flash[:alert]
end

def test_empty_order_cannot_be_submitted
customer_id = register_customer("Customer Shop")

login(customer_id)
visit_client_orders

order_id = SecureRandom.uuid
assert_no_changes -> { ClientOrders::Order.count } do
as_client_submit_order_for_customer(order_id)
end

assert_select "#alert", "You can't submit an empty order"
end

private

def submit_order_for_customer(customer_id, order_id)
Expand Down
35 changes: 18 additions & 17 deletions rails_application/test/integration/orders_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,6 @@ def setup
add_available_vat_rate(10)
end

def test_submitting_empty_order
arkency_id = register_customer("Arkency")

get "/"
assert_select "h1", "Orders"
get "/orders/new"
follow_redirect!
assert_select "h1", "Order"
post "/orders",
params: {
"authenticity_token" => "[FILTERED]",
"order_id" => SecureRandom.uuid,
"customer_id" => arkency_id,
"commit" => "Submit order"
}
end

def test_happy_path
shopify_id = register_customer("Shopify")

Expand Down Expand Up @@ -202,6 +185,24 @@ def test_discount_is_applied_for_new_order
assert_select("td", "10.0%")
end

def test_empty_order_cannot_be_submitted
order_id = SecureRandom.uuid
shopify_id = register_customer("Shopify")

assert_no_changes -> { Orders::Order.count } do
post "/orders",
params: {
"authenticity_token" => "[FILTERED]",
"order_id" => order_id,
"customer_id" => shopify_id,
"commit" => "Submit order"
}
end
follow_redirect!

assert_select "#alert", "You can't submit an empty order"
end

private

def assert_remove_buttons_visible(async_remote_id, fearless_id, order_id)
Expand Down
13 changes: 12 additions & 1 deletion rails_application/test/orders/order_cancelled_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def test_cancel_confirmed_order
customer_id = SecureRandom.uuid
order_id = SecureRandom.uuid
order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER
product_id = SecureRandom.uuid

event_store.publish(Crm::CustomerRegistered.new(
data: {
Expand All @@ -23,6 +24,8 @@ def test_cancel_confirmed_order
}
))

create_product(product_id, "Async Remote", 30)
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))
run_command(Ordering::SubmitOrder.new(order_id: order_id, order_number: order_number))

order_cancelled = Fulfillment::OrderCancelled.new(
Expand All @@ -40,5 +43,13 @@ def test_cancel_confirmed_order
assert_equal("Cancelled", orders.first.state)
assert event_store.event_in_stream?(order_cancelled.event_id, "Orders$all")
end

private

def create_product(product_id, name, price)
run_command(ProductCatalog::RegisterProduct.new(product_id: product_id))
run_command(ProductCatalog::NameProduct.new(product_id: product_id, name: name))
run_command(Pricing::SetPrice.new(product_id: product_id, price: price))
end
end
end
end
13 changes: 12 additions & 1 deletion rails_application/test/orders/order_paid_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ def test_order_confirmed
customer_id = SecureRandom.uuid
order_id = SecureRandom.uuid
order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER
product_id = SecureRandom.uuid

create_product(product_id, "Async Remote", 10)
run_command(Crm::RegisterCustomer.new(customer_id: customer_id, name: "John Doe"))
run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id))
run_command(Ordering::SubmitOrder.new(order_id: order_id, order_number: order_number))
run_command(
Crm::AssignCustomerToOrder.new(customer_id: customer_id, order_id: order_id)
Expand All @@ -37,5 +40,13 @@ def test_order_confirmed
assert_equal("Paid", orders.first.state)
assert event_store.event_in_stream?(order_confirmed.event_id, "Orders$all")
end

private

def create_product(product_id, name, price)
run_command(ProductCatalog::RegisterProduct.new(product_id: product_id))
run_command(ProductCatalog::NameProduct.new(product_id: product_id, name: name))
run_command(Pricing::SetPrice.new(product_id: product_id, price: price))
end
end
end
end
Loading