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

[NUT-201] Refactor used_by? method for one_use_per_user rule #10554

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
76 changes: 76 additions & 0 deletions api/spec/controllers/spree/api/v1/orders_controller_spec.rb
Expand Up @@ -708,6 +708,82 @@ def clean_address(address)
end
end

describe '#apply_coupon_code' do
subject(:apply_coupon_code) do
api_put :apply_coupon_code, id: order.number,
order_token: order.token,
coupon_code: coupon_code
end

let(:order) { create(:order_with_line_items, user: current_api_user) }
let(:coupon_code) { 'coupon_code' }

context 'when coupon is not found' do
it 'returns coupon not found response' do
apply_coupon_code

expect(response.status).to eq 422
expect(json_response[:successful]).to eq false
expect(json_response[:status_code]).to eq 'coupon_code_not_found'
expect(json_response[:error]).to eq "The coupon code you entered doesn't exist. Please try again."
expect(json_response[:success]).to be_nil
end

it 'does not apply any promotion to order' do
apply_coupon_code

expect(order.promotions).to be_empty
end
end

context 'when coupon is found' do
let!(:promotion) { create(:promotion_with_one_use_per_user_rule, code: coupon_code) }

context 'when coupon is applied' do
it 'returns coupon applied response' do
apply_coupon_code

expect(response.status).to eq 200
expect(json_response[:successful]).to eq true
expect(json_response[:status_code]).to eq 'coupon_code_applied'
expect(json_response[:success]).to eq 'The coupon code was successfully applied to your order.'
expect(json_response[:error]).to be_nil
end

it 'applies specified promotion to order' do
expect(order.promotions).to be_empty

apply_coupon_code

expect(order.promotions.count).to eq 1
expect(order.promotions.first.code).to eq coupon_code
end
end

context 'when coupon can not be applied' do
let!(:order_with_line_item_promotion) do
create(:order_with_line_items, coupon_code: coupon_code, user: current_api_user).tap do |order|
Spree::PromotionHandler::Coupon.new(order).apply
order.update_column(:completed_at, Time.current)
order.update_column(:state, 'complete')
end
end

context 'when coupon was used by user already' do
it 'returns coupon was used already' do
apply_coupon_code

expect(response.status).to eq 422
expect(json_response[:successful]).to eq false
expect(json_response[:status_code]).to be_nil
expect(json_response[:error]).to eq 'This coupon code can only be used once per user.'
expect(json_response[:success]).to be_nil
end
end
end
end
end

context 'PUT remove_coupon_code' do
let(:order) { create(:order_with_line_items) }

Expand Down
19 changes: 4 additions & 15 deletions core/app/models/spree/promotion.rb
Expand Up @@ -194,21 +194,10 @@ def line_item_actionable?(order, line_item)
end

def used_by?(user, excluded_orders = [])
[
:adjustments,
:line_item_adjustments,
:shipment_adjustments
].any? do |adjustment_type|
user.orders.complete.joins(adjustment_type).where(
spree_adjustments: {
source_type: 'Spree::PromotionAction',
source_id: actions.map(&:id),
eligible: true
}
).where.not(
id: excluded_orders.map(&:id)
).any?
end
user.orders.complete.joins(:promotions).joins(:all_adjustments).
where.not(spree_orders: { id: excluded_orders.map(&:id) }).
where(spree_promotions: { id: id }).
where(spree_adjustments: { source_type: 'Spree::PromotionAction', eligible: true }).any?
end

private
Expand Down
9 changes: 9 additions & 0 deletions core/lib/spree/testing_support/factories/promotion_factory.rb
Expand Up @@ -13,7 +13,16 @@
Spree::Promotion::Actions::CreateItemAdjustments.create!(calculator: calculator, promotion: promotion)
end
end

trait :with_one_use_per_user_rule do
after(:create) do |promotion|
rule = Spree::Promotion::Rules::OneUsePerUser.create!
promotion.rules << rule
end
end

factory :promotion_with_item_adjustment, traits: [:with_line_item_adjustment]
factory :promotion_with_one_use_per_user_rule, traits: [:with_line_item_adjustment, :with_one_use_per_user_rule]

trait :with_order_adjustment do
transient do
Expand Down
2 changes: 1 addition & 1 deletion core/spec/models/spree/promotion_spec.rb
Expand Up @@ -672,7 +672,7 @@
context 'when the order is complete' do
it { is_expected.to be true }

context 'when the promotion was not eligible' do
damianlegawiec marked this conversation as resolved.
Show resolved Hide resolved
context 'when the promotion is not eligible' do
let(:adjustment) { order.adjustments.first }

before do
Expand Down