diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2973725..f600565 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,6 +6,11 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. +# Offense count: 2 +# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. +Metrics/MethodLength: + Max: 11 + # Offense count: 1 # Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates. # AllowedMethods: call diff --git a/app/models/order_updater_decorator.rb b/app/models/order_updater_decorator.rb index ce890dc..9015dcf 100644 --- a/app/models/order_updater_decorator.rb +++ b/app/models/order_updater_decorator.rb @@ -7,19 +7,4 @@ def perform_update_sparta_state_job # rubocop:disable Metrics/AbcSize UpdateSpartaStateJob.perform_later(order.token, 'D', order.number, order.store) if order.payment_state == 'paid' UpdateSpartaStateJob.perform_later(order.token, 'C', order.number, order.store) if order.state == 'canceled' end - - def check_spl_adjustments # rubocop:disable Metrics/MethodLength - if order.public_metadata['spl_card_active'] == true - updated_any_adjustment = false - order.adjustments.each do |adjustment| - if adjustment.source_type != 'SPL' && adjustment.eligible? - adjustment.update(eligible: false) - updated_any_adjustment = true - end - end - updated_any_adjustment - else - false - end - end end diff --git a/app/models/spree/adjustable/adjustments_updater_decorator.rb b/app/models/spree/adjustable/adjustments_updater_decorator.rb index 2be1c17..87bb98e 100644 --- a/app/models/spree/adjustable/adjustments_updater_decorator.rb +++ b/app/models/spree/adjustable/adjustments_updater_decorator.rb @@ -3,28 +3,22 @@ module Spree module Adjustable module AdjustmentsUpdaterDecorator + SPL_SOURCE_TYPE = 'SPL' + private def set_spree_adjustments - adjustable = @adjustable.is_a?(::Spree::Order) ? @adjustable : @adjustable.order - - @adjustable.adjustments.destroy_all if adjustable.public_metadata[:spl_card_active] - end - - def shipment_with_adjustments? - @adjustable.is_a?(::Spree::Shipment) && @adjustable.order.public_metadata.key?(:spl_card_active) - end - - def order_with_adjustments? - @adjustable.is_a?(::Spree::Order) && @adjustable.public_metadata.key?(:spl_card_active) + @adjustable.is_a?(::Spree::Order) ? @adjustable : @adjustable.order end def line_item_with_spl_adjustments? - @adjustable.is_a?(::Spree::LineItem) && @adjustable.adjustments.any? { |adj| adj.source_type == 'SPL' } + @adjustable.is_a?(::Spree::LineItem) && @adjustable.adjustments.any? { |adj| adj.source_type == SPL_SOURCE_TYPE } end def recalculate_spl_adjustments(attributes, totals) - sparta_adjustments = @adjustable.adjustments.select { |adj| adj.source_type == 'SPL' && adj.eligible? } + sparta_adjustments = @adjustable.adjustments.select do |adj| + adj.source_type == SPL_SOURCE_TYPE && adj.eligible? + end total_adjustment_amount = sparta_adjustments.sum(&:amount) assign_spl_totals(attributes, total_adjustment_amount, Time.current) @adjustable.update_columns(totals) diff --git a/app/services/promotion_switcher_service.rb b/app/services/promotion_switcher_service.rb index 7e80b6a..92a9500 100644 --- a/app/services/promotion_switcher_service.rb +++ b/app/services/promotion_switcher_service.rb @@ -9,11 +9,8 @@ def initialize(order, check_only) @order = order end - def call # rubocop:disable Metrics/AbcSize - return unless order.public_metadata.key?(:spl_card_active) - - apply_sparta_discount(order, check_only) if cast_boolean(order.public_metadata[:spl_card_active]) - remove_sparta_discount(order) unless cast_boolean(order.public_metadata[:spl_card_active]) + def call + apply_sparta_discount(order, check_only) rescue StandardError => e Rails.logger.error("[PromotionSwitcher] Failed for Order #{order.id}: #{e.message}") remove_sparta_discount(order) @@ -25,10 +22,11 @@ def call # rubocop:disable Metrics/AbcSize attr_accessor :check_only, :line_items, :order def apply_sparta_discount(order, check_only) - return unless order.line_items.any? && order.public_metadata['spl_no_card'].present? + return unless order.line_items.any? + card_number = prepare_card_number_if_exist(order.public_metadata) spl_response = Spl::SpartaLoyaltyService.new(order.token, - order.public_metadata['spl_no_card'], + card_number, order.line_items, DateTime.current, order.products, @@ -43,7 +41,7 @@ def create_sparta_adjustments(spl_response, order) ApplySpartaDiscountService.new(spl_response, order).call end - def remove_sparta_discount(order) - RemoveSpartaDiscountService.destroy_all_sparta_adjustments(order) + def prepare_card_number_if_exist(metadata) + cast_boolean(metadata[:spl_card_active]) ? metadata['spl_no_card'] : '' end end diff --git a/app/services/spl/login_account_service.rb b/app/services/spl/login_account_service.rb index 3f985d9..998e116 100644 --- a/app/services/spl/login_account_service.rb +++ b/app/services/spl/login_account_service.rb @@ -33,7 +33,7 @@ def send_request(url, body) Spl::SendRequestService.new(url, body).call end - def prepare_login_body # rubocop:disable Metrics/MethodLength + def prepare_login_body { context: { prgCode: @store.private_metadata['spl_prg_code'] diff --git a/app/services/spree/cart/recalculate_decorator.rb b/app/services/spree/cart/recalculate_decorator.rb deleted file mode 100644 index a22ffb6..0000000 --- a/app/services/spree/cart/recalculate_decorator.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Spree - module Cart - module RecalculateDecorator - private - - def spl_cart_active?(order) - return unless order.public_metadata.key?(:spl_card_active) # rubocop:disable Style/ReturnNilInPredicateMethodDefinition - - ActiveModel::Type::Boolean.new.cast(order.public_metadata[:spl_card_active]) - end - end - end -end diff --git a/config/initializers/spree_spl.rb b/config/initializers/spree_spl.rb index 3a91f64..f1f4273 100644 --- a/config/initializers/spree_spl.rb +++ b/config/initializers/spree_spl.rb @@ -21,10 +21,6 @@ Spree::Adjustable::AdjustmentsUpdaterDecorator ) - ::Spree::Cart::Recalculate.prepend( - Spree::Cart::RecalculateDecorator - ) - ::Spree::PromotionHandler::Cart.prepend( CartDecorator ) diff --git a/spec/models/adjustments_updater_decorator_spec.rb b/spec/models/adjustments_updater_decorator_spec.rb index 43dbba0..d789f67 100644 --- a/spec/models/adjustments_updater_decorator_spec.rb +++ b/spec/models/adjustments_updater_decorator_spec.rb @@ -3,225 +3,22 @@ require 'rails_helper' RSpec.describe Spree::Adjustable::AdjustmentsUpdater, type: :model do - let(:store) { Spree::Store.default || create(:store, default: true) } - let(:public_metadata) { {} } + # Use the upstream Spree approach to avoid store/product validation issues + let(:order) { create(:order_with_line_items, line_items_count: 1) } + let(:line_item) { order.line_items.first } - let!(:order) do - create( - :order, - store: store, - public_metadata: public_metadata - ) - end - let(:adjustable) { order } subject(:updater) { described_class.new(adjustable) } - describe '#set_spree_adjustments (private)' do - def run_set_spree_adjustments - updater.send(:set_spree_adjustments) - end - before do - order.adjustments = adjustments - shipment.adjustments << shipment_adjustment - order.save - shipment.save - rescue StandardError - # Ignored - end - - context 'when adjustable is an order with spl_card_active: true (symbol key)' do - let(:public_metadata) { { spl_card_active: true } } - let(:adjustments) { [adjustment1, adjustment2] } - let(:adjustment1) { create(:adjustment, order: order) } - let(:adjustment2) { create(:adjustment, order: order) } - - it 'destroys all adjustments on the order' do - expect { run_set_spree_adjustments } - .to change { order.adjustments.reload.count }.from(2).to(0) - end - end - - context 'when adjustable is an order with spl_card_active: true (string key)' do - let(:public_metadata) { { 'spl_card_active' => true } } - let(:adjustments) { [adjustment1, adjustment2] } - let(:adjustment1) { create(:adjustment, order: order) } - let(:adjustment2) { create(:adjustment, order: order) } - - it 'destroys all adjustments on the order' do - expect { run_set_spree_adjustments } - .to change { order.adjustments.reload.count }.from(2).to(0) - end - end - - context 'when adjustable is an order with spl_card_active: false' do - let(:public_metadata) { { spl_card_active: false } } - let(:adjustments) { [adjustment] } - let!(:adjustment) { create(:adjustment, order: order, adjustable: order) } - - it 'does not destroy adjustments' do - expect { run_set_spree_adjustments } - .not_to change { order.adjustments.reload.count }.from(1) - end - end - - context 'when adjustable is a shipment and order has spl_card_active: true' do - let(:public_metadata) { { spl_card_active: true } } - let(:adjustable) { shipment } - let!(:shipment) { create(:shipment, order: order) } - let(:adjustments) { [order_adjustment] } - let!(:shipment_adjustment) { create(:adjustment, order: order, adjustable: shipment) } - let!(:order_adjustment) { create(:adjustment, order: order, adjustable: order) } - - it 'destroys only the shipment adjustments, not order adjustments' do - expect do - run_set_spree_adjustments - end.to change { shipment.adjustments.reload.count }.from(1).to(0) - - expect do - run_set_spree_adjustments - end.not_to(change { order.adjustments.reload.count }) - end - end - - context 'when adjustable is a line item and order has spl_card_active: true' do - let(:public_metadata) { { spl_card_active: true } } - - let(:adjustable) { line_item } - - let(:line_item) { create(:line_item) } - let(:line_item_adjustment) { create(:adjustment, order: order, adjustable: line_item) } - let(:order_adjustment) { create(:adjustment, order: order, adjustable: order) } - - it 'destroys only the line item adjustments, not order adjustments' do - line_item.adjustments << line_item_adjustment - line_item.save - order.adjustments << order_adjustment - order.line_items << line_item - order.save - - expect { run_set_spree_adjustments } - .to change { line_item.adjustments.reload.count }.from(1).to(0) - end - end - - context 'when order has no spl_card_active key' do - let(:public_metadata) { {} } - - let!(:adjustment) { create(:adjustment, order: order, adjustable: order) } - - it 'does nothing' do - expect { run_set_spree_adjustments } - .not_to change { order.adjustments.reload.count }.from(1) - end - end - end - - describe '#shipment_with_adjustments? (private)' do - def shipment_with_adjustments? - updater.send(:shipment_with_adjustments?) - end - - context 'when adjustable is a shipment and order has spl_card_active key as symbol' do - let(:public_metadata) { { spl_card_active: true } } - let(:adjustable) { shipment } - let!(:shipment) { create(:shipment, order: order) } - - it 'returns true' do - expect(shipment_with_adjustments?).to eq(true) - end - end - - context 'when adjustable is a shipment and order has spl_card_active key as string' do - let(:public_metadata) { { 'spl_card_active' => true } } - let(:adjustable) { shipment } - let!(:shipment) { create(:shipment, order: order) } - - it 'returns true' do - expect(shipment_with_adjustments?).to eq(true) - end - end - - context 'when adjustable is a shipment but order has no key' do - let(:public_metadata) { {} } - let(:adjustable) { shipment } - let!(:shipment) { create(:shipment, order: order) } - - it 'returns false' do - expect(shipment_with_adjustments?).to eq(false) - end - end - - context 'when adjustable is not a shipment' do - let(:public_metadata) { { spl_card_active: true } } - let(:adjustable) { order } - - it 'returns false' do - expect(shipment_with_adjustments?).to eq(false) - end - end - end - - describe '#order_with_adjustments? (private)' do - def order_with_adjustments? - updater.send(:order_with_adjustments?) - end - - context 'when adjustable is an order and it has spl_card_active key as symbol' do - let(:public_metadata) { { spl_card_active: true } } - - it 'returns true' do - expect(order_with_adjustments?).to eq(true) - end - end - - context 'when adjustable is an order and it has spl_card_active key as string' do - let(:public_metadata) { { 'spl_card_active' => true } } - - it 'returns true' do - expect(order_with_adjustments?).to eq(true) - end - end - - context 'when adjustable is an order without that key' do - let(:public_metadata) { {} } - - it 'returns false' do - expect(order_with_adjustments?).to eq(false) - end - end - - context 'when adjustable is not an order' do - let(:public_metadata) { { spl_card_active: true } } - let(:adjustable) { create(:shipment, order: order) } - - it 'returns false' do - expect(order_with_adjustments?).to eq(false) - end - end - end - describe '#line_item_with_spl_adjustments? (private)' do def line_item_with_spl_adjustments? updater.send(:line_item_with_spl_adjustments?) end - before do - line_item.adjustments << line_item_adjustment - line_item.save - order.line_items << line_item - order.save - rescue StandardError - # Ignored - end - - context 'when adjustable is a line item with SPL adjustment' do + context 'when adjustable is a line item with an SPL adjustment' do let(:adjustable) { line_item } - let(:line_item) { create(:line_item) } - let(:line_item_adjustment) do - create(:adjustment, - order: order, - adjustable: line_item, - source_type: 'SPL') + + before do + create(:adjustment, order: order, adjustable: line_item, source_type: 'SPL', eligible: true, amount: -2.to_d) end it 'returns true' do @@ -229,15 +26,11 @@ def line_item_with_spl_adjustments? end end - context 'when adjustable is a line item with non-SPL adjustments only' do + context 'when adjustable is a line item without SPL adjustments' do let(:adjustable) { line_item } - let(:line_item) { create(:line_item) } - let(:line_item_adjustment) do - create(:adjustment, - order: order, - adjustable: line_item, - source_type: 'Promo') + before do + create(:adjustment, order: order, adjustable: line_item, source_type: 'Promo', eligible: true, amount: -2.to_d) end it 'returns false' do @@ -245,14 +38,11 @@ def line_item_with_spl_adjustments? end end - context 'when adjustable is not a line item but has SPL adjustments' do + context 'when adjustable is not a line item' do let(:adjustable) { order } - let!(:spl_adj) do - create(:adjustment, - order: order, - adjustable: order, - source_type: 'SPL') + before do + create(:adjustment, order: order, adjustable: order, source_type: 'SPL', eligible: true, amount: -2.to_d) end it 'returns false' do @@ -262,24 +52,11 @@ def line_item_with_spl_adjustments? end describe '#recalculate_spl_adjustments (private)' do - before do - line_item.adjustments = adjustments - line_item.save - order.line_items << line_item - order.save - rescue StandardError - # Ignored - end - def recalculate_spl_adjustments(attributes, totals) updater.send(:recalculate_spl_adjustments, attributes, totals) end let(:adjustable) { line_item } - let!(:line_item) { create(:line_item) } - let(:adjustments) do - [spl_adj1, spl_adj2, spl_ineligible, other_adj] - end let!(:spl_adj1) do create(:adjustment, @@ -328,8 +105,9 @@ def recalculate_spl_adjustments(attributes, totals) allow(updater).to receive(:assign_spl_totals).and_call_original end - it 'sums only eligible SPL adjustments and passes them to assign_spl_totals' do + it 'sums only eligible SPL adjustments and passes the sum to assign_spl_totals' do recalculate_spl_adjustments(attributes, totals_hash) + expect(updater).to have_received(:assign_spl_totals).with( attributes, expected_total, @@ -343,7 +121,7 @@ def recalculate_spl_adjustments(attributes, totals) expect(line_item).to have_received(:update_columns).with(totals_hash) end - it 'mutates attributes to contain adjustment_total, promo_total and updated_at' do + it 'mutates attributes with adjustment_total, promo_total and updated_at' do recalculate_spl_adjustments(attributes, totals_hash) expect(attributes[:adjustment_total]).to eq(expected_total) @@ -357,6 +135,7 @@ def assign_spl_totals(attributes, total_amount, time) updater.send(:assign_spl_totals, attributes, total_amount, time) end + let(:adjustable) { line_item } let(:attributes) { {} } let(:total_amount) { 42.5.to_d } let(:time) { Time.zone.parse('2024-02-02 10:00:00') } diff --git a/spec/models/order_updater_decorator_spec.rb b/spec/models/order_updater_decorator_spec.rb index 8cca0d2..9c600c4 100644 --- a/spec/models/order_updater_decorator_spec.rb +++ b/spec/models/order_updater_decorator_spec.rb @@ -85,71 +85,4 @@ end end end - - describe '#check_spl_adjustments' do - def run_check - updater.send(:check_spl_adjustments) - end - - context 'when spl_card_active is false' do - let(:public_metadata) { { 'spl_card_active' => false } } - let(:adjustments) { [adjustment] } - - let(:adjustment) do - create(:adjustment, source_type: 'Promo', order:, eligible: true) - end - - it 'returns false and does nothing' do - order.adjustments = adjustments - order.save - expect(run_check).to eq(false) - expect(adjustment.reload.eligible).to eq(true) - end - end - - context 'when spl_card_active is true with eligible non-SPL adjustments' do - let(:public_metadata) { { 'spl_card_active' => true } } - let(:adjustments) { [spl_adj, promo_adj, promo_inelig] } - - let(:spl_adj) { create(:adjustment, order:, source_type: 'SPL', eligible: true) } - let(:promo_adj) { create(:adjustment, order:, source_type: 'Promo', eligible: true) } - let(:promo_inelig) { create(:adjustment, order:, source_type: 'Promo', eligible: false) } - - it 'returns true only if non-SPL eligible adjustments were changed' do - order.adjustments = adjustments - order.save - expect(run_check).to eq(true) - expect(promo_adj.reload.eligible).to eq(false) - expect(spl_adj.reload.eligible).to eq(true) - expect(promo_inelig.reload.eligible).to eq(false) - end - end - - context 'when spl_card_active is true but no eligible non-SPL adjustments' do - let(:public_metadata) { { 'spl_card_active' => true } } - let(:adjustments) { [spl_adj, promo_inelig] } - - let(:spl_adj) { create(:adjustment, order:, source_type: 'SPL', eligible: true) } - let(:promo_inelig) { create(:adjustment, order:, source_type: 'Promo', eligible: false) } - - it 'returns false' do - order.adjustments = adjustments - order.save - expect(run_check).to eq(false) - end - end - - context 'when public_metadata does not contain key' do - let(:public_metadata) { {} } - let(:adjustments) { [promo_adj] } - let(:promo_adj) { create(:adjustment, order:, source_type: 'Promo', eligible: true) } - - it 'returns false and does nothing' do - order.adjustments = adjustments - order.save - expect(run_check).to eq(false) - expect(promo_adj.reload.eligible).to eq(true) - end - end - end end diff --git a/spec/services/promotion_switcher_service_spec.rb b/spec/services/promotion_switcher_service_spec.rb index 1ed4f4a..2314b07 100644 --- a/spec/services/promotion_switcher_service_spec.rb +++ b/spec/services/promotion_switcher_service_spec.rb @@ -3,138 +3,79 @@ require 'rails_helper' RSpec.describe PromotionSwitcherService do - let(:country) { create(:country) } - let(:store) { create(:store, default_country: country) } - let(:order) do - create( - :order, - store:, - public_metadata: public_metadata - ) - end - - let(:check_only) { true } - - let(:service) { described_class.new(order, check_only) } - - let(:variant1) { create(:variant, sku: 'BS49252-BZ020-PSA000-000', price: 6.75) } - let(:variant2) { create(:variant, sku: 'BS49252-BZ020-PSA000-001', price: 7.73) } - - let!(:line_item1) { create(:line_item, order:, variant: variant1, quantity: 1, price: 6.75) } - let!(:line_item2) { create(:line_item, order:, variant: variant2, quantity: 3, price: 7.73) } - - let(:exemple_sparta_response) do - { - 'errorCode' => '0', - 'balanceBurn' => 0.0, - 'balanceEarn' => 0.0, - 'balanceAfter' => 0.12, - 'bookedEarn' => false, - 'processId' => '663c92b05012e0b396ac632b', - 'messages' => [], - 'basket' => [ - { - 'productCode' => 'TESTPRD1', - 'productCode2' => nil, - 'quantity' => 1.0, - 'amountGross' => 6.75, - 'discountGross' => 0.0, - 'discountPercent' => nil, - 'unitPriceGross' => 6.75, - 'discounts' => nil, - 'isAward' => nil, - 'notPromoted' => nil, - 'skipCB' => nil, - 'skipDD' => nil, - 'skipRD' => nil, - 'pos' => 1 - }, - { - 'productCode' => 'TESTPRD4', - 'productCode2' => nil, - 'quantity' => 3.0, - 'amountGross' => 23.2, - 'discountGross' => 0.8, - 'discountPercent' => nil, - 'unitPriceGross' => 7.73, - 'discounts' => [ - { - 'source' => 'LP', - 'amount' => 0.8, - 'percent' => 5.0, - 'code' => '663c926e5012e0b396ac6328', - 'name' => '5% discount for TESTPRD4', - 'order' => 1, - 'quantity' => 2.0, - 'unitPriceGrossDiscounted' => nil - } - ], - 'isAward' => nil, - 'notPromoted' => nil, - 'skipCB' => nil, - 'skipDD' => nil, - 'skipRD' => nil, - 'pos' => 2 - } - ], - 'basketChanged' => true, - 'amountGross' => 29.95, - 'discountGross' => 0.8, - 'coupons' => [], - 'cardType' => { 'code' => 'DV' }, - 'requestId' => '00003_LSHRV' - } - end - describe '#call' do - context 'when spl_card_active is true and card number is present' do - let(:public_metadata) do - { - spl_card_active: 'true', - spl_no_card: '5100179585157' - } - end - - it 'calls Sparta loyalty, gets response and applies Sparta discounts' do - sparta_service_double = instance_double(Spl::SpartaLoyaltyService) - apply_service_double = instance_double(ApplySpartaDiscountService) + let(:country) { create(:country) } + let(:store) { create(:store, default_country: country) } + + let(:public_metadata) do + { + 'spl_card_active' => 'true', + 'spl_no_card' => '5100179585157' + } + end - expect(Spl::SpartaLoyaltyService).to receive(:new) do |token, card_no, line_items, date, products, chk, store_arg| # rubocop:disable Layout/LineLength - expect(token).to eq(order.token) - expect(card_no).to eq('5100179585157') - expect(line_items).to match_array(order.line_items) - expect(date).to be_a(DateTime) - expect(products).to match_array(order.products) - expect(chk).to eq(check_only) - expect(store_arg).to eq(order.store) + let(:order) { create(:order, store: store, public_metadata: public_metadata) } + let(:check_only) { true } + let(:service) { described_class.new(order, check_only) } + + let(:variant1) { create(:variant, sku: 'TESTPRD1', price: 6.75) } + let(:variant2) { create(:variant, sku: 'TESTPRD4', price: 7.73) } + + let!(:line_item1) { create(:line_item, order: order, variant: variant1, quantity: 1, price: 6.75) } + let!(:line_item2) { create(:line_item, order: order, variant: variant2, quantity: 3, price: 7.73) } + + let(:example_sparta_response) do + { + 'errorCode' => '0', + 'basket' => [ + { 'productCode' => 'TESTPRD1', 'quantity' => 1.0, 'amountGross' => 6.75, 'discountGross' => 0.0, 'pos' => 1 }, + { + 'productCode' => 'TESTPRD4', + 'quantity' => 3.0, + 'amountGross' => 23.2, + 'discountGross' => 0.8, + 'discounts' => [ + { 'source' => 'LP', 'amount' => 0.8, 'percent' => 5.0, 'name' => '5% discount for TESTPRD4' } + ], + 'pos' => 2 + } + ], + 'discountGross' => 0.8 + } + end - sparta_service_double - end + it 'calls Sparta loyalty, gets response and applies Sparta discounts' do + sparta_service_double = instance_double(Spl::SpartaLoyaltyService) + apply_service_double = instance_double(ApplySpartaDiscountService) - expect(sparta_service_double).to receive(:call).and_return(exemple_sparta_response) - expect(ApplySpartaDiscountService).to receive(:new).with(exemple_sparta_response, order) - .and_return(apply_service_double) - expect(apply_service_double).to receive(:call) + expect(Spl::SpartaLoyaltyService).to receive(:new).and_return(sparta_service_double) + expect(sparta_service_double).to receive(:call).once.and_return(example_sparta_response) + expect(ApplySpartaDiscountService).to receive(:new) + .with(example_sparta_response, order) + .and_return(apply_service_double) + expect(apply_service_double).to receive(:call).once - service.call - end + service.call end context 'when spl_card_active is true but Sparta returns nil' do let(:public_metadata) do { - spl_card_active: true, - spl_no_card: '5100179585157' + 'spl_card_active' => 'true', + 'spl_no_card' => '5100179585157' } end - it 'does not apply Sparta discounts' do + it 'does not apply Sparta discounts (but still reloads the order)' do sparta_service_double = instance_double(Spl::SpartaLoyaltyService) expect(Spl::SpartaLoyaltyService).to receive(:new).and_return(sparta_service_double) expect(sparta_service_double).to receive(:call).and_return(nil) + expect(ApplySpartaDiscountService).not_to receive(:new) + expect(order).to receive(:reload).and_call_original + service.call end end @@ -142,67 +83,90 @@ context 'when spl_card_active is false' do let(:public_metadata) do { - spl_card_active: 'false', - spl_no_card: '5100179585157' + 'spl_card_active' => 'false', + 'spl_no_card' => '5100179585157' } end - it 'removes Sparta discounts' do - expect(Spl::SpartaLoyaltyService).not_to receive(:new) + it 'calls Sparta with empty card number and does not apply discounts' do + sparta_service_double = instance_double(Spl::SpartaLoyaltyService) + + expect(Spl::SpartaLoyaltyService).to receive(:new) do |_, card_no, *_| + expect(card_no).to eq('') + sparta_service_double + end + + expect(sparta_service_double).to receive(:call).and_return(nil) + expect(ApplySpartaDiscountService).not_to receive(:new) - expect(RemoveSpartaDiscountService).to receive(:destroy_all_sparta_adjustments).with(order) + expect(order).to receive(:reload).and_call_original service.call end end - context 'when spl_card_active key is missing' do + context 'when there are no line items' do let(:public_metadata) do { - spl_no_card: '5100179585157' + 'spl_card_active' => 'true', + 'spl_no_card' => '5100179585157' } end - it 'does nothing' do + before do + order.line_items.destroy_all + end + + it 'does not call Sparta loyalty service or apply discounts' do expect(Spl::SpartaLoyaltyService).not_to receive(:new) expect(ApplySpartaDiscountService).not_to receive(:new) - expect(RemoveSpartaDiscountService).not_to receive(:destroy_all_sparta_adjustments) + + expect(order).to receive(:reload).and_call_original service.call end end - context 'when there are no line items' do + context 'when spl_card_active is true but card number is missing' do let(:public_metadata) do { - spl_card_active: true, - spl_no_card: '5100179585157' + 'spl_card_active' => 'true' } end - before do - order.line_items.destroy_all - end + it 'calls Sparta with nil card number and does not apply discounts' do + sparta_service_double = instance_double(Spl::SpartaLoyaltyService) - it 'does not call Sparta loyalty service' do - expect(Spl::SpartaLoyaltyService).not_to receive(:new) + expect(Spl::SpartaLoyaltyService).to receive(:new) do |_, card_no, *_| + expect(card_no).to be_nil + sparta_service_double + end + + expect(sparta_service_double).to receive(:call).and_return(nil) expect(ApplySpartaDiscountService).not_to receive(:new) + expect(order).to receive(:reload).and_call_original + service.call end end - context 'when card number is missing' do - let(:public_metadata) do - { - spl_card_active: true - } - end + context 'when spl_card_active is missing and card number is missing' do + let(:public_metadata) { {} } - it 'does not call Sparta loyalty service' do - expect(Spl::SpartaLoyaltyService).not_to receive(:new) + it 'calls Sparta with empty card number and does not apply discounts' do + sparta_service_double = instance_double(Spl::SpartaLoyaltyService) + + expect(Spl::SpartaLoyaltyService).to receive(:new) do |_, card_no, *_| + expect(card_no).to eq('') + sparta_service_double + end + + expect(sparta_service_double).to receive(:call).and_return(nil) expect(ApplySpartaDiscountService).not_to receive(:new) + expect(order).to receive(:reload).and_call_original + service.call end end