From 5faafcbc6f4c88a07aa9fe90f54126f148b3d643 Mon Sep 17 00:00:00 2001 From: marlena-b Date: Mon, 6 Jan 2025 17:24:32 +0100 Subject: [PATCH] Add projection and read models --- ecommerce/ordering/lib/ordering.rb | 1 + .../ordering/lib/ordering/projections.rb | 11 +++ ecommerce/ordering/lib/ordering/refund.rb | 12 +++- ecommerce/ordering/lib/ordering/service.rb | 15 +++- .../ordering/test/add_item_to_refund_test.rb | 21 ++++++ ecommerce/ordering/test/projections_test.rb | 27 +++++++ .../ordering/test/refund_items_list_test.rb | 48 +++++++++++++ .../test/remove_item_from_refund_test.rb | 14 +++- .../app/controllers/refunds_controller.rb | 27 ++++++- .../read_models/refunds/add_item_to_refund.rb | 43 ++++------- .../app/read_models/refunds/configuration.rb | 15 ++++ .../refunds/remove_item_from_refund.rb | 24 +++---- .../app/views/refunds/edit.html.erb | 32 ++++++--- .../test/integration/refunds_test.rb | 41 +++++++++++ .../test/orders/item_added_to_refund_test.rb | 63 ++++------------ .../orders/item_removed_from_refund_test.rb | 72 +++++-------------- rails_application/test/test_helper.rb | 8 +++ 17 files changed, 306 insertions(+), 168 deletions(-) create mode 100644 ecommerce/ordering/lib/ordering/projections.rb create mode 100644 ecommerce/ordering/test/projections_test.rb create mode 100644 ecommerce/ordering/test/refund_items_list_test.rb diff --git a/ecommerce/ordering/lib/ordering.rb b/ecommerce/ordering/lib/ordering.rb index 520e1203..57d25733 100644 --- a/ecommerce/ordering/lib/ordering.rb +++ b/ecommerce/ordering/lib/ordering.rb @@ -22,6 +22,7 @@ require_relative "ordering/service" require_relative "ordering/order" require_relative "ordering/refund" +require_relative "ordering/projections" module Ordering class Configuration diff --git a/ecommerce/ordering/lib/ordering/projections.rb b/ecommerce/ordering/lib/ordering/projections.rb new file mode 100644 index 00000000..aaf674f7 --- /dev/null +++ b/ecommerce/ordering/lib/ordering/projections.rb @@ -0,0 +1,11 @@ +module Ordering + class Projections + def self.product_quantity_available_to_refund(order_id, product_id) + RubyEventStore::Projection + .from_stream("Ordering::Order$#{order_id}") + .init(-> { { available: 0 } }) + .when(ItemAddedToBasket, -> (state, event) { state[:available] += 1 if event.data.fetch(:product_id) == product_id }) + .when(ItemRemovedFromBasket, -> (state, event) { state[:available] -= 1 if event.data.fetch(:product_id) == product_id }) + end + end +end diff --git a/ecommerce/ordering/lib/ordering/refund.rb b/ecommerce/ordering/lib/ordering/refund.rb index 803f378a..063604ec 100644 --- a/ecommerce/ordering/lib/ordering/refund.rb +++ b/ecommerce/ordering/lib/ordering/refund.rb @@ -2,6 +2,7 @@ module Ordering class Refund include AggregateRoot + ExceedsOrderQuantityError = Class.new(StandardError) ProductNotFoundError = Class.new(StandardError) def initialize(id) @@ -13,7 +14,8 @@ def create_draft(order_id) apply DraftRefundCreated.new(data: { refund_id: @id, order_id: order_id }) end - def add_item(product_id) + def add_item(product_id, available_quantity_to_refund) + raise ExceedsOrderQuantityError unless enough_items?(available_quantity_to_refund, product_id) apply ItemAddedToRefund.new(data: { refund_id: @id, order_id: @order_id, product_id: product_id }) end @@ -33,6 +35,12 @@ def remove_item(product_id) on ItemRemovedFromRefund do |event| @refund_items.decrease_quantity(event.data[:product_id]) end + + private + + def enough_items?(available_quantity_to_refund, product_id) + @refund_items.quantity(product_id) < available_quantity_to_refund + end end class ItemsList @@ -48,7 +56,7 @@ def increase_quantity(product_id) def decrease_quantity(product_id) refund_items[product_id] -= 1 - refund_items.delete(product_id) if refund_items.fetch(product_id).equal?(0) + refund_items.delete(product_id) if quantity(product_id).equal?(0) end def quantity(product_id) diff --git a/ecommerce/ordering/lib/ordering/service.rb b/ecommerce/ordering/lib/ordering/service.rb index e35d1cac..0ab35e9b 100644 --- a/ecommerce/ordering/lib/ordering/service.rb +++ b/ecommerce/ordering/lib/ordering/service.rb @@ -88,13 +88,26 @@ def call(command) class OnAddItemToRefund def initialize(event_store) @repository = Infra::AggregateRootRepository.new(event_store) + @event_store = event_store end def call(command) @repository.with_aggregate(Refund, command.aggregate_id) do |refund| - refund.add_item(command.product_id) + refund.add_item( + command.product_id, + available_quantity_to_refund(command.order_id, command.product_id) + ) end end + + private + + def available_quantity_to_refund(order_id, product_id) + Projections + .product_quantity_available_to_refund(order_id, product_id) + .run(@event_store) + .fetch(:available) + end end class OnRemoveItemFromRefund diff --git a/ecommerce/ordering/test/add_item_to_refund_test.rb b/ecommerce/ordering/test/add_item_to_refund_test.rb index 1ebc9d44..51dd8b55 100644 --- a/ecommerce/ordering/test/add_item_to_refund_test.rb +++ b/ecommerce/ordering/test/add_item_to_refund_test.rb @@ -11,6 +11,7 @@ def test_add_item_to_refund stream = "Ordering::Refund$#{aggregate_id}" arrange( + AddItemToBasket.new(order_id: order_id, product_id: product_id), CreateDraftRefund.new( refund_id: aggregate_id, order_id: order_id @@ -37,5 +38,25 @@ def test_add_item_to_refund ) end end + + def test_add_item_raises_exceeds_order_quantity_error + aggregate_id = SecureRandom.uuid + order_id = SecureRandom.uuid + product_id = SecureRandom.uuid + + arrange( + AddItemToBasket.new(order_id: order_id, product_id: product_id), + CreateDraftRefund.new(refund_id: aggregate_id, order_id: order_id), + AddItemToRefund.new( + refund_id: aggregate_id, + order_id: order_id, + product_id: product_id + ) + ) + + assert_raises(Ordering::Refund::ExceedsOrderQuantityError) do + act(AddItemToRefund.new(refund_id: aggregate_id, order_id: order_id, product_id: product_id)) + end + end end end diff --git a/ecommerce/ordering/test/projections_test.rb b/ecommerce/ordering/test/projections_test.rb new file mode 100644 index 00000000..c485de69 --- /dev/null +++ b/ecommerce/ordering/test/projections_test.rb @@ -0,0 +1,27 @@ +require_relative "test_helper" + +module Ordering + class ProjectionsTest < Test + cover "Ordering::Projections" + + def test_product_quantity_available_to_refund + order_id = SecureRandom.uuid + product_id = SecureRandom.uuid + another_product_id = SecureRandom.uuid + stream_name = "Ordering::Order$#{order_id}" + projection = Projections.product_quantity_available_to_refund(order_id, product_id) + + event_store = RubyEventStore::Client.new(repository: RubyEventStore::InMemoryRepository.new) + + event_store.publish(ItemAddedToBasket.new(data: { order_id: order_id, product_id: product_id }), stream_name: stream_name) + event_store.publish(ItemAddedToBasket.new(data: { order_id: order_id, product_id: product_id }), stream_name: stream_name) + event_store.publish(ItemRemovedFromBasket.new(data: { order_id: order_id, product_id: product_id }), stream_name: stream_name) + event_store.publish(ItemAddedToBasket.new(data: { order_id: order_id, product_id: another_product_id }), stream_name: stream_name) + event_store.publish(ItemRemovedFromBasket.new(data: { order_id: order_id, product_id: another_product_id }), stream_name: stream_name) + + available_quantity_to_refund = projection.run(event_store) + + assert_equal({ available: 1 }, available_quantity_to_refund) + end + end +end diff --git a/ecommerce/ordering/test/refund_items_list_test.rb b/ecommerce/ordering/test/refund_items_list_test.rb new file mode 100644 index 00000000..f9592c77 --- /dev/null +++ b/ecommerce/ordering/test/refund_items_list_test.rb @@ -0,0 +1,48 @@ +require_relative "test_helper" + +module Ordering + class RefundItemsListTest < Test + + def test_initialize + list = ItemsList.new + + assert_equal 0, list.refund_items.size + end + + def test_increase_item_quantity + product_one_id = SecureRandom.uuid + product_two_id = SecureRandom.uuid + list = ItemsList.new + + list.increase_quantity(product_one_id) + + assert_equal 1, list.refund_items.size + assert_equal 1, list.quantity(product_one_id) + + list.increase_quantity(product_two_id) + + assert_equal 2, list.refund_items.size + assert_equal 1, list.quantity(product_two_id) + end + + def test_decrease_item_quantity + product_id = SecureRandom.uuid + list = ItemsList.new + + list.increase_quantity(product_id) + list.increase_quantity(product_id) + + assert_equal 1, list.refund_items.size + assert_equal 2, list.quantity(product_id) + + list.decrease_quantity(product_id) + + assert_equal 1, list.refund_items.size + assert_equal 1, list.quantity(product_id) + + list.decrease_quantity(product_id) + + assert_equal 0, list.refund_items.size + end + end +end diff --git a/ecommerce/ordering/test/remove_item_from_refund_test.rb b/ecommerce/ordering/test/remove_item_from_refund_test.rb index f7f7a915..b6e64a9f 100644 --- a/ecommerce/ordering/test/remove_item_from_refund_test.rb +++ b/ecommerce/ordering/test/remove_item_from_refund_test.rb @@ -11,6 +11,7 @@ def test_removing_items_from_refund stream = "Ordering::Refund$#{aggregate_id}" arrange( + AddItemToBasket.new(order_id: order_id, product_id: product_id), CreateDraftRefund.new( refund_id: aggregate_id, order_id: order_id @@ -43,15 +44,26 @@ def test_removing_items_from_refund end end - def test_can_remove_only_added_items + def test_cant_remove_item_with_0_quantity order_id = SecureRandom.uuid aggregate_id = SecureRandom.uuid product_id = SecureRandom.uuid arrange( + AddItemToBasket.new(order_id: order_id, product_id: product_id), CreateDraftRefund.new( refund_id: aggregate_id, order_id: order_id + ), + AddItemToRefund.new( + refund_id: aggregate_id, + order_id: order_id, + product_id: product_id + ), + RemoveItemFromRefund.new( + refund_id: aggregate_id, + order_id: order_id, + product_id: product_id ) ) diff --git a/rails_application/app/controllers/refunds_controller.rb b/rails_application/app/controllers/refunds_controller.rb index 13bb5279..979102b1 100644 --- a/rails_application/app/controllers/refunds_controller.rb +++ b/rails_application/app/controllers/refunds_controller.rb @@ -1,8 +1,8 @@ class RefundsController < ApplicationController def edit @refund = Refunds::Refund.find_by_uid!(params[:id]) - @order = Orders::Order.find_by_uid(@refund.order_uid) - @order_lines = @order.order_lines + @order = Orders::Order.find_by_uid!(@refund.order_uid) + @refund_items = build_refund_items_list(@order.order_lines, @refund.refund_items) end def create @@ -14,10 +14,18 @@ def create def add_item add_item_to_refund + redirect_to edit_order_refund_path(params[:id], order_id: params[:order_id]) + rescue Ordering::Refund::ExceedsOrderQuantityError + flash[:alert] = "You cannot add more of this product to the refund than is in the original order." + redirect_to edit_order_refund_path(params[:id], order_id: params[:order_id]) end def remove_item remove_item_from_refund + redirect_to edit_order_refund_path(params[:id], order_id: params[:order_id]) + rescue Ordering::Refund::ProductNotFoundError + flash[:alert] = "This product is not added to the refund." + redirect_to edit_order_refund_path(params[:id], order_id: params[:order_id]) end private @@ -45,4 +53,19 @@ def remove_item_from_refund_cmd def remove_item_from_refund command_bus.(remove_item_from_refund_cmd) end + + def build_refund_items_list(order_lines, refund_items) + order_lines.map { |order_line| build_refund_item(order_line, refund_items) } + end + + def build_refund_item(order_line, refund_items) + refund_item = refund_items.find { |item| item.product_uid == order_line.product_id } || initialize_refund_item(order_line) + + refund_item.order_line = order_line + refund_item + end + + def initialize_refund_item(order_line) + Refunds::RefundItem.new(product_uid: order_line.product_id, quantity: 0, price: order_line.price) + end end diff --git a/rails_application/app/read_models/refunds/add_item_to_refund.rb b/rails_application/app/read_models/refunds/add_item_to_refund.rb index eba55f4f..c33c19e6 100644 --- a/rails_application/app/read_models/refunds/add_item_to_refund.rb +++ b/rails_application/app/read_models/refunds/add_item_to_refund.rb @@ -1,40 +1,21 @@ module Refunds class AddItemToRefund def call(event) - refund_id = event.data.fetch(:refund_id) - Refund.find_or_create_by!(uid: refund_id) - product_id = event.data.fetch(:product_id) - item = - find(refund_id, product_id) || - create(refund_id, product_id) - item.quantity += 1 - item.save! - end - - private + refund = Refund.find_by!(uid: event.data.fetch(:refund_id)) + product = Orders::Product.find_by!(uid: event.data.fetch(:product_id)) - def event_store - Rails.configuration.event_store - end + item = refund.refund_items.find_or_create_by(product_uid: product.uid) do |item| + item.price = product.price + item.quantity = 0 + end - def find(refund_id, product_id) - Refund - .find_by_uid(refund_id) - .refund_items - .where(product_uid: product_id) - .first - end + refund.total_value += item.price + item.quantity += 1 - def create(refund_id, product_id) - product = Orders::Product.find_by_uid(product_id) - Refund - .find_by(uid: refund_id) - .refund_items - .create( - product_uid: product_id, - price: product.price, - quantity: 0 - ) + ActiveRecord::Base.transaction do + refund.save! + item.save! + end end end end diff --git a/rails_application/app/read_models/refunds/configuration.rb b/rails_application/app/read_models/refunds/configuration.rb index 1d4744c5..763fd760 100644 --- a/rails_application/app/read_models/refunds/configuration.rb +++ b/rails_application/app/read_models/refunds/configuration.rb @@ -10,6 +10,21 @@ class Refund < ApplicationRecord class RefundItem < ApplicationRecord self.table_name = "refund_items" + + attr_accessor :order_line + delegate :product_name, to: :order_line + + def max_quantity? + quantity == order_quantity + end + + def order_quantity + order_line.quantity + end + + def value + quantity * price + end end class Configuration diff --git a/rails_application/app/read_models/refunds/remove_item_from_refund.rb b/rails_application/app/read_models/refunds/remove_item_from_refund.rb index 488f64b2..ce1e775c 100644 --- a/rails_application/app/read_models/refunds/remove_item_from_refund.rb +++ b/rails_application/app/read_models/refunds/remove_item_from_refund.rb @@ -1,24 +1,16 @@ module Refunds class RemoveItemFromRefund def call(event) - refund_id = event.data.fetch(:refund_id) - product_id = event.data.fetch(:product_id) - item = find(refund_id, product_id) - item.quantity -= 1 - item.quantity > 0 ? item.save! : item.destroy! - end + refund = Refund.find_by!(uid: event.data.fetch(:refund_id)) + item = refund.refund_items.find_by!(product_uid: event.data.fetch(:product_id)) - private - def find(order_uid, product_id) - Refund - .find_by_uid(order_uid) - .refund_items - .where(product_uid: product_id) - .first - end + refund.total_value -= item.price + item.quantity -= 1 - def event_store - Rails.configuration.event_store + ActiveRecord::Base.transaction do + refund.save! + item.quantity > 0 ? item.save! : item.destroy! + end end end end diff --git a/rails_application/app/views/refunds/edit.html.erb b/rails_application/app/views/refunds/edit.html.erb index 6356afdf..57747b08 100644 --- a/rails_application/app/views/refunds/edit.html.erb +++ b/rails_application/app/views/refunds/edit.html.erb @@ -4,7 +4,7 @@ <% content_for(:actions) do %> <%= secondary_action_button do %> - <%= link_to 'Back', orders_path %> + <%= link_to 'Back', order_path(@order.uid) %> <% end %> <%= primary_form_action_button do %> @@ -18,26 +18,36 @@ Product Quantity Price - Value + Value + + - <% @order_lines.each do |order_line| %> - - <%= order_line.product_name %> - 0 / <%= order_line.quantity %> - <%= number_to_currency(order_line.price) %> - <%= number_to_currency(order_line.value) %> - <%= button_to "Add", add_item_order_refund_path(order_id: order_line.order_uid, id: @refund.uid, product_id: order_line.product_id), class: "hover:underline text-blue-500" %> - <%= button_to "Remove", remove_item_order_refund_path(order_id: order_line.order_uid, id: @refund.uid, product_id: order_line.product_id), class: "hover:underline text-blue-500" %> + <% @refund_items.each do |refund_item| %> + + <%= refund_item.product_name %> + <%= refund_item.quantity %> / <%= refund_item.order_quantity %> + <%= number_to_currency(refund_item.price) %> + <%= number_to_currency(refund_item.value) %> + + <% unless refund_item.max_quantity? %> + <%= button_to "Add", add_item_order_refund_path(order_id: @order.uid, id: @refund.uid, product_id: refund_item.product_uid), class: "hover:underline text-blue-500" %> + <% end %> + + + <% unless refund_item.quantity.zero? %> + <%= button_to "Remove", remove_item_order_refund_path(order_id: @order.uid, id: @refund.uid, product_id: refund_item.product_uid), class: "hover:underline text-blue-500" %> + <% end %> + <% end %> Total - + <%= number_to_currency(@refund.total_value) %> diff --git a/rails_application/test/integration/refunds_test.rb b/rails_application/test/integration/refunds_test.rb index f75a584f..b46ff133 100644 --- a/rails_application/test/integration/refunds_test.rb +++ b/rails_application/test/integration/refunds_test.rb @@ -29,6 +29,47 @@ def test_happy_path assert_order_line_row(fearless_id, "Fearless Refactoring", 2) end + def test_renders_error_when_exceeds_available_quantity_to_refund + shopify_id = register_customer("Shopify") + order_id = SecureRandom.uuid + async_remote_id = register_product("Async Remote", 39, 10) + + add_product_to_basket(order_id, async_remote_id) + submit_order(shopify_id, order_id) + pay_order(order_id) + + post "/orders/#{order_id}/refunds" + follow_redirect! + + refund = Refunds::Refund.last + + add_item_to_refund(order_id, refund.uid, async_remote_id) + add_item_to_refund(order_id, refund.uid, async_remote_id) + follow_redirect! + + assert_select("#alert", "You cannot add more of this product to the refund than is in the original order.") + end + + def test_renders_error_when_trying_to_remove_not_added_product + shopify_id = register_customer("Shopify") + order_id = SecureRandom.uuid + async_remote_id = register_product("Async Remote", 39, 10) + + add_product_to_basket(order_id, async_remote_id) + submit_order(shopify_id, order_id) + pay_order(order_id) + + post "/orders/#{order_id}/refunds" + follow_redirect! + + refund = Refunds::Refund.last + + remove_item_from_refund(order_id, refund.uid, async_remote_id) + follow_redirect! + + assert_select("#alert", "This product is not added to the refund.") + end + private def assert_order_line_row(product_id, product_name, quantity) diff --git a/rails_application/test/orders/item_added_to_refund_test.rb b/rails_application/test/orders/item_added_to_refund_test.rb index 97e48f47..b7e667aa 100644 --- a/rails_application/test/orders/item_added_to_refund_test.rb +++ b/rails_application/test/orders/item_added_to_refund_test.rb @@ -4,34 +4,20 @@ module Refunds class ItemAddedToRefundTest < InMemoryTestCase cover "Orders*" - def test_add_new_item_to_refund - customer_id = SecureRandom.uuid + def test_add_item_to_refund + refund_id = SecureRandom.uuid product_id = SecureRandom.uuid - another_product_id = SecureRandom.uuid order_id = SecureRandom.uuid - refund_id = SecureRandom.uuid - register_customer(customer_id) prepare_product(product_id, 50) - prepare_product(another_product_id, 30) - run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: product_id)) - run_command(Ordering::AddItemToBasket.new(order_id: order_id, product_id: another_product_id)) - assign_customer_to_order(customer_id, order_id) - submit_order(order_id, customer_id) - confirm_order(order_id) create_draft_refund(refund_id, order_id) - add_item_to_refund(refund_id, order_id, product_id) - add_item_to_refund(refund_id, order_id, product_id) - add_item_to_refund(refund_id, order_id, another_product_id) - assert_equal(Refunds::RefundItem.count, 2) + AddItemToRefund.new.call(item_added_to_refund(refund_id, order_id, product_id)) + + assert_equal(Refunds::RefundItem.count, 1) refund_item = Refunds::RefundItem.find_by(refund_uid: refund_id, product_uid: product_id) - assert_equal(refund_item.product_uid, product_id) - assert_equal(refund_item.quantity, 2) - assert_equal(refund_item.price, 50) - second_refund_item = Refunds::RefundItem.find_by(refund_uid: refund_id, product_uid: another_product_id) - assert_equal(second_refund_item.product_uid, another_product_id) - assert_equal(second_refund_item.quantity, 1) - assert_equal(second_refund_item.price, 30) + assert_equal(product_id, refund_item.product_uid) + assert_equal(1, refund_item.quantity) + assert_equal(50, refund_item.price) assert_equal(Refunds::Refund.count, 1) refund = Refunds::Refund.find_by(uid: refund_id) @@ -40,10 +26,6 @@ def test_add_new_item_to_refund private - def item_added_to_basket(order_id, product_id) - event_store.publish(Pricing::PriceItemAdded.new(data: { product_id: product_id, order_id: order_id })) - end - def prepare_product(product_id, price) run_command( ProductCatalog::RegisterProduct.new( @@ -59,33 +41,14 @@ def prepare_product(product_id, price) run_command(Pricing::SetPrice.new(product_id: product_id, price: price)) end - def register_customer(customer_id) - run_command(Crm::RegisterCustomer.new(customer_id: customer_id, name: "Arkency")) - end - - def assign_customer_to_order(customer_id, order_id) - run_command(Crm::AssignCustomerToOrder.new(customer_id: customer_id, order_id: order_id)) - end - - def submit_order(order_id, customer_id) - order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER - run_command(Ordering::SubmitOrder.new(order_id: order_id, order_number: order_number, customer_id: customer_id)) - end - - def confirm_order(order_id) - run_command(Fulfillment::ConfirmOrder.new(order_id: order_id)) - end - def create_draft_refund(refund_id, order_id) - run_command(Ordering::CreateDraftRefund.new(refund_id: refund_id, order_id: order_id)) - end - - def add_item_to_refund(refund_id, order_id, product_id) - run_command(Ordering::AddItemToRefund.new(refund_id: refund_id, order_id: order_id, product_id: product_id)) + run_command( + Ordering::CreateDraftRefund.new(refund_id: refund_id, order_id: order_id) + ) end - def event_store - Rails.configuration.event_store + def item_added_to_refund(refund_id, order_id, product_id) + Ordering::ItemAddedToRefund.new(data: { refund_id: refund_id, order_id: order_id, product_id: product_id }) end end end diff --git a/rails_application/test/orders/item_removed_from_refund_test.rb b/rails_application/test/orders/item_removed_from_refund_test.rb index b4ff80f1..c64efebc 100644 --- a/rails_application/test/orders/item_removed_from_refund_test.rb +++ b/rails_application/test/orders/item_removed_from_refund_test.rb @@ -4,32 +4,24 @@ module Refunds class ItemRemovedFromRefundTest < InMemoryTestCase cover "Orders*" - def test_removing_items_from_refund - customer_id = SecureRandom.uuid + def test_remove_item_from_refund + refund_id = SecureRandom.uuid product_id = SecureRandom.uuid another_product_id = SecureRandom.uuid order_id = SecureRandom.uuid - refund_id = SecureRandom.uuid - register_customer(customer_id) + create_draft_refund(refund_id, order_id) prepare_product(product_id, 50) prepare_product(another_product_id, 30) - add_item_to_basket(order_id, product_id) - add_item_to_basket(order_id, another_product_id) - assign_customer_to_order(customer_id, order_id) - submit_order(order_id, customer_id) - confirm_order(order_id) - create_draft_refund(refund_id, order_id) - add_item_to_refund(refund_id, order_id, product_id) - add_item_to_refund(refund_id, order_id, product_id) - add_item_to_refund(refund_id, order_id, another_product_id) - remove_item_from_refund(refund_id, order_id, product_id) - remove_item_from_refund(refund_id, order_id, another_product_id) + AddItemToRefund.new.call(item_added_to_refund(refund_id, order_id, product_id)) + AddItemToRefund.new.call(item_added_to_refund(refund_id, order_id, another_product_id)) + + RemoveItemFromRefund.new.call(item_removed_from_refund(refund_id, order_id, product_id)) assert_equal(Refunds::RefundItem.count, 1) - refund_item = Refunds::RefundItem.find_by(refund_uid: refund_id, product_uid: product_id) - assert_equal(refund_item.product_uid, product_id) - assert_equal(refund_item.quantity, 1) - assert_equal(refund_item.price, 50) + refund_item = Refunds::RefundItem.find_by(refund_uid: refund_id, product_uid: another_product_id) + assert_equal(another_product_id, refund_item.product_uid) + assert_equal(1, refund_item.quantity) + assert_equal(30, refund_item.price) assert_equal(Refunds::Refund.count, 1) refund = Refunds::Refund.find_by(uid: refund_id) @@ -38,8 +30,9 @@ def test_removing_items_from_refund private - def item_added_to_basket(order_id, product_id) - event_store.publish(Pricing::PriceItemAdded.new(data: { product_id: product_id, order_id: order_id })) + def create_draft_refund(refund_id, order_id) + draft_refund_created = Ordering::DraftRefundCreated.new(data: { refund_id: refund_id, order_id: order_id }) + CreateDraftRefund.new.call(draft_refund_created) end def prepare_product(product_id, price) @@ -57,41 +50,12 @@ def prepare_product(product_id, price) run_command(Pricing::SetPrice.new(product_id: product_id, price: price)) end - def register_customer(customer_id) - run_command(Crm::RegisterCustomer.new(customer_id: customer_id, name: "Arkency")) - end - - def assign_customer_to_order(customer_id, order_id) - run_command(Crm::AssignCustomerToOrder.new(customer_id: customer_id, order_id: order_id)) - 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 submit_order(order_id, customer_id) - order_number = Ordering::FakeNumberGenerator::FAKE_NUMBER - run_command(Ordering::SubmitOrder.new(order_id: order_id, order_number: order_number, customer_id: customer_id)) - end - - def confirm_order(order_id) - run_command(Fulfillment::ConfirmOrder.new(order_id: order_id)) - end - - def create_draft_refund(refund_id, order_id) - run_command(Ordering::CreateDraftRefund.new(refund_id: refund_id, order_id: order_id)) - end - - def add_item_to_refund(refund_id, order_id, product_id) - run_command(Ordering::AddItemToRefund.new(refund_id: refund_id, order_id: order_id, product_id: product_id)) - end - - def remove_item_from_refund(refund_id, order_id, product_id) - run_command(Ordering::RemoveItemFromRefund.new(refund_id: refund_id, order_id: order_id, product_id: product_id)) + def item_added_to_refund(refund_id, order_id, product_id) + Ordering::ItemAddedToRefund.new(data: { refund_id: refund_id, order_id: order_id, product_id: product_id }) end - def event_store - Rails.configuration.event_store + def item_removed_from_refund(refund_id, order_id, product_id) + Ordering::ItemRemovedFromRefund.new(data: { refund_id: refund_id, order_id: order_id, product_id: product_id }) end end end diff --git a/rails_application/test/test_helper.rb b/rails_application/test/test_helper.rb index 1b30559f..7b981a52 100644 --- a/rails_application/test/test_helper.rb +++ b/rails_application/test/test_helper.rb @@ -127,6 +127,14 @@ def add_product_to_basket(order_id, product_id) post "/orders/#{order_id}/add_item?product_id=#{product_id}" end + def add_item_to_refund(order_id, refund_id, product_id) + post "/orders/#{order_id}/refunds/#{refund_id}/add_item?product_id=#{product_id}" + end + + def remove_item_from_refund(order_id, refund_id, product_id) + post "/orders/#{order_id}/refunds/#{refund_id}/remove_item?product_id=#{product_id}" + end + def run_command(command) Rails.configuration.command_bus.call(command) end