Skip to content

Commit d22dbf5

Browse files
senemsoyadammathysAlistairNormanstewartbenjaminwil
committed
Don't persist line item on promotion application
This is in service of the in-memory order updater. Co-authored-by: Adam <[email protected]> Co-authored-by: Alistair <[email protected]> Co-authored-by: An <[email protected]> Co-authored-by: Benjamin <[email protected]> Co-authored-by: Chris <[email protected]> Co-authored-by: Harmony <[email protected]> Co-authored-by: Jared <[email protected]> Co-authored-by: Nick <[email protected]> Co-authored-by: Noah <[email protected]> Co-authored-by: Senem <[email protected]> Co-authored-by: Sofia <[email protected]>
1 parent 26f8ed9 commit d22dbf5

File tree

6 files changed

+78
-41
lines changed

6 files changed

+78
-41
lines changed

promotions/app/models/solidus_promotions/benefits/create_discounted_item.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ def perform(order)
1717
end
1818

1919
def remove_from(order)
20-
line_item = find_item(order)
21-
# The enemy
22-
order.line_items.destroy(line_item)
20+
find_item(order)&.mark_for_destruction
2321
end
2422

2523
private
@@ -28,9 +26,8 @@ def find_item(order)
2826
order.line_items.detect { |line_item| line_item.managed_by_order_benefit == self }
2927
end
3028

31-
# The enemy - create_item
3229
def create_item(order)
33-
order.line_items.create!(quantity: determine_item_quantity(order), variant: variant, managed_by_order_benefit: self)
30+
order.line_items.build(quantity: determine_item_quantity(order), variant: variant, managed_by_order_benefit: self)
3431
end
3532

3633
def determine_item_quantity(order)

promotions/app/models/solidus_promotions/order_adjuster/discount_order.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def call
3636

3737
def perform_order_benefits(lane_benefits, lane)
3838
lane_benefits.select { |benefit| benefit.level == :order }.each do |benefit|
39-
# TODO: - the enemy
4039
benefit.perform(order)
4140
end
4241

@@ -48,7 +47,6 @@ def perform_order_benefits(lane_benefits, lane)
4847
end
4948

5049
ineligible_line_items.each do |line_item|
51-
# TODO: - the enemy
5250
line_item.managed_by_order_benefit.remove_from(order)
5351
end
5452
end

promotions/app/models/solidus_promotions/order_adjuster/persist_discounted_order.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def update_adjustments(item, item_discounts)
4848
active_adjustments = item_discounts.map do |item_discount|
4949
update_adjustment(item, item_discount)
5050
end
51-
item.update(promo_total: active_adjustments.sum(&:amount))
51+
item.promo_total = active_adjustments.sum(&:amount)
5252
# Remove any promotion adjustments tied to promotion benefits which no longer match.
5353
unmatched_adjustments = promotion_adjustments - active_adjustments
5454

@@ -71,7 +71,7 @@ def update_adjustment(item, discount_item)
7171
order_id: item.is_a?(Spree::Order) ? item.id : item.order_id,
7272
label: discount_item.label
7373
)
74-
adjustment.update!(amount: discount_item.amount)
74+
adjustment.amount = discount_item.amount
7575
adjustment
7676
end
7777
end

promotions/spec/models/solidus_promotions/benefits/create_discounted_item_spec.rb

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,65 @@
55
RSpec.describe SolidusPromotions::Benefits::CreateDiscountedItem do
66
it { is_expected.to respond_to(:preferred_variant_id) }
77

8+
let!(:benefit) { SolidusPromotions::Benefits::CreateDiscountedItem.new(preferred_variant_id: goodie.id, calculator: hundred_percent, promotion: promotion) }
9+
let(:hundred_percent) { SolidusPromotions::Calculators::Percent.new(preferred_percent: 100) }
10+
let(:promotion) { create(:solidus_promotion) }
11+
let(:goodie) { create(:variant) }
12+
813
describe "#perform" do
9-
let(:order) { create(:order_with_line_items) }
10-
let(:promotion) { create(:solidus_promotion) }
11-
let(:benefit) { SolidusPromotions::Benefits::CreateDiscountedItem.new(preferred_variant_id: goodie.id, calculator: hundred_percent, promotion: promotion) }
12-
let(:hundred_percent) { SolidusPromotions::Calculators::Percent.new(preferred_percent: 100) }
13-
let(:goodie) { create(:variant) }
14+
let!(:order) { create(:order_with_line_items) }
15+
1416
subject { benefit.perform(order) }
1517

1618
it "creates a line item with a hundred percent discount" do
17-
expect { subject }.to change { order.line_items.count }.by(1)
19+
expect { subject }.to change { order.line_items.size }.by(1)
1820
created_item = order.line_items.detect { |line_item| line_item.managed_by_order_benefit == benefit }
1921
expect(created_item.discountable_amount).to be_zero
2022
end
2123

2224
it "never calls the order recalculator" do
2325
expect(order).not_to receive(:recalculate)
2426
end
27+
28+
it "does not persist changes to order" do
29+
expect {
30+
subject
31+
}.not_to make_database_queries(manipulative: true)
32+
end
33+
end
34+
35+
describe "remove_from" do
36+
let!(:order) { create(:order_with_line_items) }
37+
38+
subject { benefit.remove_from(order) }
39+
40+
context "with an item not on the order" do
41+
it "does not modify the order" do
42+
expect {
43+
subject
44+
}.not_to make_database_queries(manipulative: true)
45+
end
46+
end
47+
48+
context "with an item present on the order" do
49+
before do
50+
benefit.perform(order)
51+
order.save!
52+
end
53+
54+
it "marks the the line item for destruction" do
55+
expect { subject }.to change {
56+
order.line_items.select(&:marked_for_destruction?).count
57+
}.by(1)
58+
59+
expect { order.save }.to change(order.line_items, :count).by(-1)
60+
end
61+
62+
it "does not make manipulative database queries" do
63+
expect {
64+
subject
65+
}.not_to make_database_queries(manipulative: true)
66+
end
67+
end
2568
end
2669
end

promotions/spec/models/solidus_promotions/order_adjuster_spec.rb

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,49 @@
55
RSpec.describe SolidusPromotions::OrderAdjuster, type: :model do
66
subject(:order_adjuster) { described_class.new(order, dry_run_promotion: dry_run_promotion) }
77

8+
let!(:order) { line_item.order }
89
let(:dry_run_promotion) { nil }
910
let(:line_item) { create(:line_item) }
10-
let(:order) { line_item.order }
1111
let(:promotion) { create(:solidus_promotion, apply_automatically: true) }
1212
let(:calculator) { SolidusPromotions::Calculators::Percent.new(preferred_percent: 10) }
1313

1414
context "adding order level adjustments" do
1515
let(:variant) { create(:variant, price: 100) }
16-
let(:benefit) do
16+
let!(:benefit) do
1717
SolidusPromotions::Benefits::CreateDiscountedItem.create(promotion: promotion, calculator: calculator, preferences: { variant_id: variant.id })
1818
end
1919
let(:adjustable) { order }
2020

21-
subject do
22-
benefit
23-
order_adjuster.call
24-
end
21+
context "when not doing a dry-run of a promotion" do
22+
subject do
23+
order_adjuster.call
24+
end
2525

26-
it "creates a line item of the given variant with a discount adjustment corresponding to the calculator" do
27-
expect {
28-
subject
29-
}.to change { order.line_items.count }.by(1)
26+
it "builds a line item of the given variant with a discount adjustment corresponding to the calculator", :aggregate_failures do
27+
expect {
28+
subject
29+
}.to change { order.line_items.length }.by(1)
3030

31-
expect(order.line_items.last.variant).to eq(variant)
32-
expect(order.line_items.last.adjustments.promotion.first&.amount).to eq(-10)
31+
expect(order.line_items.last).not_to be_persisted
32+
expect(order.line_items.last.variant).to eq(variant)
33+
expect(order.line_items.last.adjustments.first.amount).to eq(-10)
34+
expect(order.line_items.last.adjustments.first.source).to eq(benefit)
35+
end
3336
end
3437

3538
context 'when on a dry run' do
36-
let(:dry_run_promotion) { create(:solidus_promotion, :with_adjustable_benefit, promotion_benefit_class: SolidusPromotions::Benefits::CreateDiscountedItem) }
39+
let(:dry_run_promotion) { promotion }
3740

3841
subject do
39-
benefit
4042
order_adjuster.call
4143
end
4244

43-
it 'builds the line item but does not save it' do
44-
expect {
45-
subject
46-
}.to change { order.line_items.length }.by(1)
47-
48-
pending "currently on a dry run this just doesn't happen"
49-
expect(order.line_items.last.variant).to eq(variant)
50-
expect(order.line_items.last.adjustments.promotion.first&.amount).to eq(-10)
45+
it "does not create any line items" do
46+
expect { subject }.not_to change(Spree::LineItem, :count)
47+
end
5148

52-
expect(order.reload.line_items.length).to eq(1)
49+
it "does not create any adjustments" do
50+
expect { subject }.not_to change(Spree::Adjustment, :count)
5351
end
5452
end
5553
end
@@ -202,7 +200,7 @@
202200
it "will not create an adjustment on the shipping rate" do
203201
expect do
204202
subject
205-
end.not_to change { order.shipments.first.shipping_rates.first.discounts.count }
203+
end.not_to change { order.shipments.first.shipping_rates.first.discounts.length }
206204
end
207205
end
208206
end
@@ -217,7 +215,7 @@
217215
expect do
218216
promotion
219217
subject.call
220-
end.to change { order.shipments.first.adjustments.count }
218+
end.to change { order.shipments.first.adjustments.length }
221219
end
222220

223221
context "if the promo is eligible but the calculcator returns 0" do
@@ -228,7 +226,7 @@
228226
expect do
229227
promotion
230228
subject.call
231-
end.not_to change { order.shipments.first.adjustments.count }
229+
end.not_to change { order.shipments.first.adjustments.length }
232230
end
233231
end
234232
end

promotions/spec/rails_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
require "spec_helper"
77
require "solidus_legacy_promotions"
8+
require 'db-query-matchers'
89

910
# SOLIDUS DUMMY APP
1011
require "spree/testing_support/dummy_app"

0 commit comments

Comments
 (0)