Skip to content

Commit

Permalink
Emit product.out_of_stock. (#11527)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastian-palma committed Nov 25, 2021
1 parent 2b1af49 commit a135500
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 24 deletions.
9 changes: 9 additions & 0 deletions api/app/models/spree/api/webhooks/stock_movement_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module StockMovementDecorator
def self.prepended(base)
base.around_save :queue_webhooks_requests_for_variant_out_of_stock!
base.around_save :queue_webhooks_requests_for_variant_back_in_stock!
base.around_save :queue_webhooks_requests_for_product_out_of_stock!
base.around_save :queue_webhooks_requests_for_product_back_in_stock!
end

Expand Down Expand Up @@ -35,6 +36,14 @@ def queue_webhooks_requests_for_product_back_in_stock!
product.queue_webhooks_requests!('product.back_in_stock')
end
end

def queue_webhooks_requests_for_product_out_of_stock!
product_was_in_stock = product.any_variant_in_stock_or_backorderable?
yield
if product_was_in_stock && !product.any_variant_in_stock_or_backorderable?
product.queue_webhooks_requests!('product.out_of_stock')
end
end
end
end
end
Expand Down
138 changes: 114 additions & 24 deletions api/spec/models/spree/api/webhooks/stock_movement_decorator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,152 @@
let(:stock_item) { create(:stock_item) }
let(:stock_location) { variant.stock_locations.first }

describe 'emitting product.back_in_stock' do
describe 'emitting product events' do
let!(:store) { create(:store) }
let!(:product) { create(:product, stores: [store]) }
let!(:variant) { create(:variant, product: product) }
let!(:variant2) { create(:variant, product: product) }
let(:body) { Spree::Api::V2::Platform::ProductSerializer.new(product).serializable_hash }
let(:params) { 'product.back_in_stock' }

before { Spree::StockItem.update_all(backorderable: false) }
describe 'emitting product.out_of_stock' do
let(:event_name) { 'product.out_of_stock' }

before { Spree::StockItem.update_all(backorderable: false) }

context 'when all product variants are out of stock' do
context 'when one of the variants is back in stock' do
context 'when all product variants are in stock' do
before do
product.variants.each do |variant|
variant.stock_items.each do |stock_item|
stock_item.set_count_on_hand(1)
end
end
end

context 'when one of the variants goes out of stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = -1
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.save
end
product.reload
end

it { expect { subject }.not_to emit_webhook_event(event_name) }
end

context 'when all the variants go out of stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = -1
stock_movement.stock_item = stock_location.set_up_stock_item(product.variants[1])
stock_movement.save
end
product.reload
end

before do
# Set one of the two product variants as out of stock
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = -1
stock_movement.stock_item = stock_location.set_up_stock_item(product.variants[0])
stock_movement.save
end
end

it { expect { subject }.to emit_webhook_event(event_name) }
end
end

context 'when only one product variant is in stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 1
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.quantity = -1
stock_movement.stock_item = stock_location.set_up_stock_item(product.variants[0])
stock_movement.save
end
product.reload
end

it { expect { subject }.to emit_webhook_event(params) }
before { product.variants[0].stock_items[0].set_count_on_hand(1) }

it { expect { subject }.to emit_webhook_event(event_name) }
end

context 'when none of the variants is back in stock' do
context 'when no product variant is in stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 0
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.stock_item = stock_location.set_up_stock_item(product.variants[0])
stock_movement.save
end
product.reload
end

it { expect { subject }.not_to emit_webhook_event(params) }
before do
product.variants.each do |variant|
variant.stock_items.each do |stock_item|
stock_item.set_count_on_hand(0)
end
end
end

it { expect { subject }.not_to emit_webhook_event(event_name) }
end
end

context 'when other variant is already in stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 100
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.save
describe 'emitting product.back_in_stock' do
let(:params) { 'product.back_in_stock' }

before { Spree::StockItem.update_all(backorderable: false) }

context 'when all product variants are out of stock' do
context 'when one of the variants is back in stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 1
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.save
end
product.reload
end

it { expect { subject }.to emit_webhook_event(params) }
end
end

before do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 1
stock_movement.stock_item = stock_location.set_up_stock_item(variant2)
stock_movement.save
context 'when none of the variants is back in stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 0
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.save
end
product.reload
end

it { expect { subject }.not_to emit_webhook_event(params) }
end
end

it { expect { subject }.not_to emit_webhook_event(params) }
context 'when other variant is already in stock' do
subject do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 100
stock_movement.stock_item = stock_location.set_up_stock_item(variant)
stock_movement.save
end
end

before do
stock_location.stock_movements.new.tap do |stock_movement|
stock_movement.quantity = 1
stock_movement.stock_item = stock_location.set_up_stock_item(variant2)
stock_movement.save
end
end

it { expect { subject }.not_to emit_webhook_event(params) }
end
end
end

Expand Down

0 comments on commit a135500

Please sign in to comment.