summaryrefslogtreecommitdiff
path: root/spec/lib/solidus_subscriptions/processor_spec.rb
blob: b70d501857105c2a705ec2ca5ce5ad6e67aba341 (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
122
123
124
125
126
127
128
129
130
131
132
133
require 'spec_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,
      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_shipping_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

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

      it 'creates an order for each billing 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