summaryrefslogtreecommitdiff
path: root/spec/lib/solidus_subscriptions/processor_spec.rb
blob: 08aa9e33b7e349f25c28c511beafc8b0e84f7f2d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
require 'rails_helper'

RSpec.describe SolidusSubscriptions::Processor, :checkout do
  include ActiveJob::TestHelper
  around { |e| perform_enqueued_jobs { e.run } }

  let!(:user) { create(:user, :subscription_user) }
  let!(:credit_card) {
    card = create(:credit_card, gateway_customer_profile_id: 'BGS-123', user: user)
    wallet_payment_source = user.wallet.add(card)
    user.wallet.default_wallet_payment_source = wallet_payment_source
    user.save
    card
  }

  let!(:actionable_subscriptions) { create_list(:subscription, 2, :actionable, user: user) }
  let!(:pending_cancellation_subscriptions) do
    create_list(:subscription, 2, :pending_cancellation, user: user)
  end

  let!(:expiring_subscriptions) do
    create_list(
      :subscription,
      2,
      :actionable,
      :with_line_item,
      user: user,
      line_item_traits: [{ end_date: Date.current.tomorrow }]
    )
  end

  let!(:future_subscriptions) { create_list(:subscription, 2, :not_actionable) }
  let!(:canceled_subscriptions) { create_list(:subscription, 2, :canceled) }
  let!(:inactive) { create_list(:subscription, 2, :inactive) }

  let!(:successful_installments) { create_list :installment, 2, :success }
  let!(:failed_installments) do
    create_list(
      :installment,
      2,
      :failed,
      subscription_traits: [{ user: user }]
    )
  end

  # all subscriptions and previously failed installments belong to the same user
  let(:expected_orders) { 1 }

  shared_examples 'a subscription order' do
    let(:order_variant_ids) { Spree::Order.last.variant_ids }
    let(:expected_ids) do
      subs = actionable_subscriptions + pending_cancellation_subscriptions + expiring_subscriptions
      subs_ids = subs.flat_map { |s| s.line_items.pluck(:subscribable_id) }
      inst_ids = failed_installments.flat_map { |i| i.subscription.line_items.pluck(:subscribable_id) }

      subs_ids + inst_ids
    end

    it 'creates the correct number of orders' do
      expect { subject }.to change { Spree::Order.complete.count }.by expected_orders
    end

    it 'creates the correct order' do
      subject
      expect(order_variant_ids).to match_array expected_ids
    end

    it 'advances the subsription actionable dates' do
      subscription = actionable_subscriptions.first

      current_date = subscription.actionable_date
      expected_date = subscription.next_actionable_date

      expect { subject }.
        to change { subscription.reload.actionable_date }.
        from(current_date).to(expected_date)
    end

    it 'cancels subscriptions pending cancellation' do
      subs = pending_cancellation_subscriptions.first
      expect { subject }.
        to change { subs.reload.state }.
        from('pending_cancellation').to('canceled')
    end

    it 'resets the subscription successive skip count' do
      subs = pending_cancellation_subscriptions.first
      expect { subject }.
        to change { subs.reload.state }.
        from('pending_cancellation').to('canceled')
    end

    it 'deactivates expired subscriptions' do
      sub = expiring_subscriptions.first

      expect { subject }.
        to change { sub.reload.state }.
        from('active').to('inactive')
    end

    context 'the subscriptions have different shipping addresses' do
      let!(:sub_to_different_address) do
        create(:subscription, :actionable, :with_address, user: user)
      end

      it 'creates an order for each shipping address' do
        expect { subject }.to change { Spree::Order.complete.count }.by 2
      end
    end
  end

  describe '.run' do
    subject { described_class.run }
    it_behaves_like 'a subscription order'
  end

  describe '#build_jobs' do
    subject { described_class.new([user]).build_jobs }
    it_behaves_like 'a subscription order'
  end
end