cloud_payments 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +4 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +106 -0
  8. data/Rakefile +7 -0
  9. data/cloud_payments.gemspec +28 -0
  10. data/config.ru +58 -0
  11. data/lib/cloud_payments.rb +34 -0
  12. data/lib/cloud_payments/client.rb +50 -0
  13. data/lib/cloud_payments/client/errors.rb +68 -0
  14. data/lib/cloud_payments/client/gateway_errors.rb +36 -0
  15. data/lib/cloud_payments/client/response.rb +22 -0
  16. data/lib/cloud_payments/client/serializer.rb +9 -0
  17. data/lib/cloud_payments/client/serializer/base.rb +46 -0
  18. data/lib/cloud_payments/client/serializer/multi_json.rb +17 -0
  19. data/lib/cloud_payments/config.rb +44 -0
  20. data/lib/cloud_payments/models.rb +4 -0
  21. data/lib/cloud_payments/models/model.rb +5 -0
  22. data/lib/cloud_payments/models/secure3d.rb +15 -0
  23. data/lib/cloud_payments/models/subscription.rb +49 -0
  24. data/lib/cloud_payments/models/transaction.rb +82 -0
  25. data/lib/cloud_payments/namespaces.rb +23 -0
  26. data/lib/cloud_payments/namespaces/base.rb +50 -0
  27. data/lib/cloud_payments/namespaces/cards.rb +25 -0
  28. data/lib/cloud_payments/namespaces/payments.rb +32 -0
  29. data/lib/cloud_payments/namespaces/subscriptions.rb +24 -0
  30. data/lib/cloud_payments/namespaces/tokens.rb +15 -0
  31. data/lib/cloud_payments/version.rb +3 -0
  32. data/spec/cloud_payments/client/response_spec.rb +35 -0
  33. data/spec/cloud_payments/client/serializer/multi_json_spec.rb +16 -0
  34. data/spec/cloud_payments/client_spec.rb +5 -0
  35. data/spec/cloud_payments/models/secure3d_spec.rb +37 -0
  36. data/spec/cloud_payments/models/subscription_spec.rb +141 -0
  37. data/spec/cloud_payments/models/transaction_spec.rb +254 -0
  38. data/spec/cloud_payments/namespaces/base_spec.rb +75 -0
  39. data/spec/cloud_payments/namespaces/cards_spec.rb +119 -0
  40. data/spec/cloud_payments/namespaces/payments_spec.rb +96 -0
  41. data/spec/cloud_payments/namespaces/subscriptions_spec.rb +82 -0
  42. data/spec/cloud_payments/namespaces/tokens_spec.rb +90 -0
  43. data/spec/cloud_payments/namespaces_spec.rb +45 -0
  44. data/spec/cloud_payments_spec.rb +14 -0
  45. data/spec/fixtures/apis/cards/auth/failed.yml +45 -0
  46. data/spec/fixtures/apis/cards/auth/secure3d.yml +15 -0
  47. data/spec/fixtures/apis/cards/auth/successful.yml +48 -0
  48. data/spec/fixtures/apis/cards/charge/failed.yml +45 -0
  49. data/spec/fixtures/apis/cards/charge/secure3d.yml +15 -0
  50. data/spec/fixtures/apis/cards/charge/successful.yml +48 -0
  51. data/spec/fixtures/apis/payments/confirm/failed.yml +6 -0
  52. data/spec/fixtures/apis/payments/confirm/failed_with_message.yml +6 -0
  53. data/spec/fixtures/apis/payments/confirm/successful.yml +6 -0
  54. data/spec/fixtures/apis/payments/post3ds/failed.yml +45 -0
  55. data/spec/fixtures/apis/payments/post3ds/successful.yml +48 -0
  56. data/spec/fixtures/apis/payments/refund/failed.yml +6 -0
  57. data/spec/fixtures/apis/payments/refund/failed_with_message.yml +6 -0
  58. data/spec/fixtures/apis/payments/refund/successful.yml +6 -0
  59. data/spec/fixtures/apis/payments/void/failed.yml +6 -0
  60. data/spec/fixtures/apis/payments/void/failed_with_message.yml +6 -0
  61. data/spec/fixtures/apis/payments/void/successful.yml +6 -0
  62. data/spec/fixtures/apis/ping/failed.yml +5 -0
  63. data/spec/fixtures/apis/ping/successful.yml +5 -0
  64. data/spec/fixtures/apis/subscriptions/cancel/successful.yml +6 -0
  65. data/spec/fixtures/apis/subscriptions/create/successful.yml +31 -0
  66. data/spec/fixtures/apis/subscriptions/find/successful.yml +31 -0
  67. data/spec/fixtures/apis/subscriptions/update/successful.yml +31 -0
  68. data/spec/fixtures/apis/tokens/auth/failed.yml +45 -0
  69. data/spec/fixtures/apis/tokens/auth/successful.yml +48 -0
  70. data/spec/fixtures/apis/tokens/charge/failed.yml +45 -0
  71. data/spec/fixtures/apis/tokens/charge/successful.yml +48 -0
  72. data/spec/spec_helper.rb +38 -0
  73. data/spec/support/examples.rb +27 -0
  74. data/spec/support/helpers.rb +89 -0
  75. metadata +244 -0
@@ -0,0 +1,15 @@
1
+ module CloudPayments
2
+ module Namespaces
3
+ class Tokens < Base
4
+ def charge(attributes)
5
+ response = request(:charge, attributes)
6
+ Transaction.new(response[:model])
7
+ end
8
+
9
+ def auth(attributes)
10
+ response = request(:auth, attributes)
11
+ Transaction.new(response[:model])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module CloudPayments
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe CloudPayments::Client::Response do
4
+ let(:status){ 200 }
5
+ let(:body){ '{"Model":{"Id":123,"CurrencyCode":"RUB","Amount":120},"Success":true}' }
6
+ let(:headers){ { 'content-type' => 'application/json' } }
7
+
8
+ subject{ CloudPayments::Client::Response.new(status, body, headers) }
9
+
10
+ describe '#body' do
11
+ specify{ expect(subject.body).to eq(model: { id: 123, currency_code: 'RUB', amount: 120 }, success: true) }
12
+
13
+ context 'wnen content type does not match /json/' do
14
+ let(:headers){ { 'content-type' => 'text/plain' } }
15
+ specify{ expect(subject.body).to eq(body) }
16
+ end
17
+ end
18
+
19
+ describe '#origin_body' do
20
+ specify{ expect(subject.origin_body).to eq(body) }
21
+
22
+ context 'wnen content type does not match /json/' do
23
+ let(:headers){ { 'content-type' => 'text/plain' } }
24
+ specify{ expect(subject.origin_body).to eq(body) }
25
+ end
26
+ end
27
+
28
+ describe '#headers' do
29
+ specify{ expect(subject.headers).to eq(headers) }
30
+ end
31
+
32
+ describe '#status' do
33
+ specify{ expect(subject.status).to eq(status) }
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ describe CloudPayments::Client::Serializer::MultiJson do
4
+ let(:encoded_data){ '{"Model":{"Id":123,"CurrencyCode":"RUB","Amount":120},"Success":true}' }
5
+ let(:decoded_data){ { model: { id: 123, currency_code: 'RUB', amount: 120 }, success: true } }
6
+
7
+ subject{ CloudPayments::Client::Serializer::MultiJson.new(CloudPayments.config) }
8
+
9
+ describe '#load' do
10
+ specify{ expect(subject.load(encoded_data)).to eq(decoded_data) }
11
+ end
12
+
13
+ describe '#dump' do
14
+ specify{ expect(subject.dump(decoded_data)).to eq(encoded_data) }
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe CloudPayments::Client do
4
+
5
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe CloudPayments::Secure3D do
4
+ describe 'properties' do
5
+ let(:attributes){ {
6
+ transaction_id: 504,
7
+ pa_req: 'pa_req',
8
+ acs_url: 'acs_url'
9
+ } }
10
+
11
+ subject{ CloudPayments::Secure3D.new(attributes) }
12
+
13
+ specify{ expect(subject.transaction_id).to eq(504) }
14
+ specify{ expect(subject.pa_req).to eq('pa_req') }
15
+ specify{ expect(subject.acs_url).to eq('acs_url') }
16
+
17
+ context 'without any attributes' do
18
+ let(:attributes){ {} }
19
+ specify{ expect{ subject }.to raise_error(/\'transaction_id\' is required/) }
20
+ end
21
+
22
+ context 'without `transaction_id` attribute' do
23
+ let(:attributes){ { pa_req: 'pa_req', acs_url: 'acs_url' } }
24
+ specify{ expect{ subject }.to raise_error(/\'transaction_id\' is required/) }
25
+ end
26
+
27
+ context 'without `pa_req` attribute' do
28
+ let(:attributes){ { transaction_id: 504, acs_url: 'acs_url' } }
29
+ specify{ expect{ subject }.to raise_error(/\'pa_req\' is required/) }
30
+ end
31
+
32
+ context 'without `acs_url` attribute' do
33
+ let(:attributes){ { transaction_id: 504, pa_req: 'pa_req' } }
34
+ specify{ expect{ subject }.to raise_error(/\'acs_url\' is required/) }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ describe CloudPayments::Subscription do
4
+ subject{ CloudPayments::Subscription.new(attributes) }
5
+
6
+ describe 'properties' do
7
+ let(:attributes){ {
8
+ id: 'sc_8cf8a9338fb8ebf7202b08d09c938',
9
+ account_id: 'user@example.com',
10
+ description: 'Monthly subscription',
11
+ email: 'user@example.com',
12
+ amount: 1.02,
13
+ currency_code: 0,
14
+ currency: 'RUB',
15
+ require_confirmation: false,
16
+ start_date_iso: '2014-08-09T11:49:41',
17
+ interval_code: 1,
18
+ interval: 'Month',
19
+ period: 1,
20
+ max_periods: 12,
21
+ status_code: 0,
22
+ status: 'Active',
23
+ successful_transactions_number: 0,
24
+ failed_transactions_number: 0,
25
+ last_transaction_date_iso: '2014-08-09T11:49:41',
26
+ next_transaction_date_iso: '2014-08-09T11:49:41'
27
+ } }
28
+
29
+ specify{ expect(subject.id).to eq('sc_8cf8a9338fb8ebf7202b08d09c938') }
30
+ specify{ expect(subject.account_id).to eq('user@example.com') }
31
+ specify{ expect(subject.description).to eq('Monthly subscription') }
32
+ specify{ expect(subject.email).to eq('user@example.com') }
33
+ specify{ expect(subject.amount).to eq(1.02) }
34
+ specify{ expect(subject.currency_code).to eq(0) }
35
+ specify{ expect(subject.currency).to eq('RUB') }
36
+ specify{ expect(subject.require_confirmation).to be_falsy }
37
+ specify{ expect(subject.started_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
38
+ specify{ expect(subject.interval_code).to eq(1) }
39
+ specify{ expect(subject.interval).to eq('Month') }
40
+ specify{ expect(subject.period).to eq(1) }
41
+ specify{ expect(subject.max_periods).to eq(12) }
42
+ specify{ expect(subject.status_code).to eq(0) }
43
+ specify{ expect(subject.status).to eq('Active') }
44
+ specify{ expect(subject.successful_transactions).to eq(0) }
45
+ specify{ expect(subject.failed_transactions).to eq(0) }
46
+ specify{ expect(subject.last_transaction_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
47
+ specify{ expect(subject.next_transaction_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
48
+
49
+ context 'without any attributes' do
50
+ let(:attributes){ {} }
51
+ specify{ expect{ subject }.to raise_error(/\'id\' is required/) }
52
+ end
53
+
54
+ it_behaves_like :raise_without_attribute, :id
55
+ it_behaves_like :raise_without_attribute, :account_id
56
+ it_behaves_like :raise_without_attribute, :description
57
+ it_behaves_like :raise_without_attribute, :email
58
+ it_behaves_like :raise_without_attribute, :amount
59
+ it_behaves_like :raise_without_attribute, :currency_code
60
+ it_behaves_like :raise_without_attribute, :currency
61
+ it_behaves_like :raise_without_attribute, :require_confirmation
62
+ it_behaves_like :raise_without_attribute, :start_date_iso, :started_at
63
+ it_behaves_like :raise_without_attribute, :interval_code
64
+ it_behaves_like :raise_without_attribute, :interval
65
+ it_behaves_like :raise_without_attribute, :period
66
+ it_behaves_like :raise_without_attribute, :status_code
67
+ it_behaves_like :raise_without_attribute, :status
68
+ it_behaves_like :raise_without_attribute, :successful_transactions_number, :successful_transactions
69
+ it_behaves_like :raise_without_attribute, :failed_transactions_number, :failed_transactions
70
+
71
+ it_behaves_like :not_raise_without_attribute, :max_periods
72
+ it_behaves_like :not_raise_without_attribute, :last_transaction_date_iso, :last_transaction_at
73
+ it_behaves_like :not_raise_without_attribute, :next_transaction_date_iso, :next_transaction_at
74
+ end
75
+
76
+ describe 'status' do
77
+ let(:attributes){ {
78
+ id: 'sc_8cf8a9338fb8ebf7202b08d09c938',
79
+ account_id: 'user@example.com',
80
+ description: 'Monthly subscription',
81
+ email: 'user@example.com',
82
+ amount: 1.02,
83
+ currency_code: 0,
84
+ currency: 'RUB',
85
+ require_confirmation: false,
86
+ start_date_iso: '2014-08-09T11:49:41',
87
+ interval_code: 1,
88
+ interval: 'Month',
89
+ period: 1,
90
+ status_code: 0,
91
+ status: status,
92
+ successful_transactions_number: 0,
93
+ failed_transactions_number: 0
94
+ } }
95
+
96
+ context 'when status == Active' do
97
+ let(:status){ 'Active' }
98
+ specify{ expect(subject).to be_active }
99
+ specify{ expect(subject).not_to be_past_due }
100
+ specify{ expect(subject).not_to be_cancelled }
101
+ specify{ expect(subject).not_to be_rejected }
102
+ specify{ expect(subject).not_to be_expired }
103
+ end
104
+
105
+ context 'when status == PastDue' do
106
+ let(:status){ 'PastDue' }
107
+ specify{ expect(subject).not_to be_active }
108
+ specify{ expect(subject).to be_past_due }
109
+ specify{ expect(subject).not_to be_cancelled }
110
+ specify{ expect(subject).not_to be_rejected }
111
+ specify{ expect(subject).not_to be_expired }
112
+ end
113
+
114
+ context 'when status == Cancelled' do
115
+ let(:status){ 'Cancelled' }
116
+ specify{ expect(subject).not_to be_active }
117
+ specify{ expect(subject).not_to be_past_due }
118
+ specify{ expect(subject).to be_cancelled }
119
+ specify{ expect(subject).not_to be_rejected }
120
+ specify{ expect(subject).not_to be_expired }
121
+ end
122
+
123
+ context 'when status == Rejected' do
124
+ let(:status){ 'Rejected' }
125
+ specify{ expect(subject).not_to be_active }
126
+ specify{ expect(subject).not_to be_past_due }
127
+ specify{ expect(subject).not_to be_cancelled }
128
+ specify{ expect(subject).to be_rejected }
129
+ specify{ expect(subject).not_to be_expired }
130
+ end
131
+
132
+ context 'when status == Expired' do
133
+ let(:status){ 'Expired' }
134
+ specify{ expect(subject).not_to be_active }
135
+ specify{ expect(subject).not_to be_past_due }
136
+ specify{ expect(subject).not_to be_cancelled }
137
+ specify{ expect(subject).not_to be_rejected }
138
+ specify{ expect(subject).to be_expired }
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,254 @@
1
+ require 'spec_helper'
2
+
3
+ describe CloudPayments::Transaction do
4
+ subject{ CloudPayments::Transaction.new(attributes) }
5
+
6
+ describe 'properties' do
7
+ let(:attributes){ {
8
+ transaction_id: 504,
9
+ amount: 10.0,
10
+ currency: 'RUB',
11
+ currency_code: 0,
12
+ invoice_id: '1234567',
13
+ account_id: 'user_x',
14
+ subscription_id: 'sc_8cf8a9338fb8ebf7202b08d09c938',
15
+ email: 'user@example.com',
16
+ description: 'Buying goods in example.com',
17
+ json_data: { key: 'value' },
18
+ date_time: '2014-08-09T11:49:41',
19
+ created_date_iso: '2014-08-09T11:49:41',
20
+ auth_date_iso: '2014-08-09T11:49:41',
21
+ confirm_date_iso: '2014-08-09T11:49:41',
22
+ auth_code: '123456',
23
+ test_mode: true,
24
+ ip_address: '195.91.194.13',
25
+ ip_country: 'RU',
26
+ ip_city: 'Ufa',
27
+ ip_region: 'Republic of Bashkortostan',
28
+ ip_district: 'Volga Federal District',
29
+ ip_latitude: 54.7355,
30
+ ip_longitude: 55.991982,
31
+ card_first_six: '411111',
32
+ card_last_four: '1111',
33
+ card_type: 'Visa',
34
+ card_type_code: 0,
35
+ card_exp_date: '10/17',
36
+ issuer_bank_country: 'RU',
37
+ status: 'Completed',
38
+ status_code: 3,
39
+ reason: 'Approved',
40
+ reason_code: 0,
41
+ card_holder_message: 'Payment successful',
42
+ name: 'CARDHOLDER NAME',
43
+ token: 'a4e67841-abb0-42de-a364-d1d8f9f4b3c0'
44
+ } }
45
+
46
+ specify{ expect(subject.id).to eq(504) }
47
+ specify{ expect(subject.amount).to eq(10.0) }
48
+ specify{ expect(subject.currency).to eq('RUB') }
49
+ specify{ expect(subject.currency_code).to eq(0) }
50
+ specify{ expect(subject.invoice_id).to eq('1234567') }
51
+ specify{ expect(subject.account_id).to eq('user_x') }
52
+ specify{ expect(subject.subscription_id).to eq('sc_8cf8a9338fb8ebf7202b08d09c938') }
53
+ specify{ expect(subject.email).to eq('user@example.com') }
54
+ specify{ expect(subject.description).to eq('Buying goods in example.com') }
55
+ specify{ expect(subject.metadata).to eq(key: 'value') }
56
+ specify{ expect(subject.date_time).to eq(DateTime.parse('2014-08-09T11:49:41')) }
57
+ specify{ expect(subject.created_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
58
+ specify{ expect(subject.authorized_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
59
+ specify{ expect(subject.confirmed_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
60
+ specify{ expect(subject.auth_code).to eq('123456') }
61
+ specify{ expect(subject.test_mode).to be_truthy }
62
+ specify{ expect(subject.ip_address).to eq('195.91.194.13') }
63
+ specify{ expect(subject.ip_country).to eq('RU') }
64
+ specify{ expect(subject.ip_city).to eq('Ufa') }
65
+ specify{ expect(subject.ip_region).to eq('Republic of Bashkortostan') }
66
+ specify{ expect(subject.ip_district).to eq('Volga Federal District') }
67
+ specify{ expect(subject.ip_lat).to eq(54.7355) }
68
+ specify{ expect(subject.ip_lng).to eq(55.991982) }
69
+ specify{ expect(subject.card_first_six).to eq('411111') }
70
+ specify{ expect(subject.card_last_four).to eq('1111') }
71
+ specify{ expect(subject.card_type).to eq('Visa') }
72
+ specify{ expect(subject.card_type_code).to eq(0) }
73
+ specify{ expect(subject.card_exp_date).to eq('10/17') }
74
+ specify{ expect(subject.issuer_bank_country).to eq('RU') }
75
+ specify{ expect(subject.reason).to eq('Approved') }
76
+ specify{ expect(subject.reason_code).to eq(0) }
77
+ specify{ expect(subject.card_holder_message).to eq('Payment successful') }
78
+ specify{ expect(subject.name).to eq('CARDHOLDER NAME') }
79
+ specify{ expect(subject.token).to eq('a4e67841-abb0-42de-a364-d1d8f9f4b3c0') }
80
+
81
+ context 'without any attributes' do
82
+ let(:attributes){ {} }
83
+ specify{ expect{ subject }.to raise_error(/\'id\' is required/) }
84
+ end
85
+
86
+ it_behaves_like :raise_without_attribute, :transaction_id, :id
87
+ it_behaves_like :raise_without_attribute, :amount
88
+ it_behaves_like :raise_without_attribute, :currency
89
+ it_behaves_like :raise_without_attribute, :test_mode
90
+ it_behaves_like :raise_without_attribute, :card_first_six
91
+ it_behaves_like :raise_without_attribute, :card_last_four
92
+ it_behaves_like :raise_without_attribute, :card_type
93
+
94
+ it_behaves_like :not_raise_without_attribute, :currency_code
95
+ it_behaves_like :not_raise_without_attribute, :invoice_id
96
+ it_behaves_like :not_raise_without_attribute, :account_id
97
+ it_behaves_like :not_raise_without_attribute, :email
98
+ it_behaves_like :not_raise_without_attribute, :description
99
+ it_behaves_like :not_raise_without_attribute, :date_time
100
+ it_behaves_like :not_raise_without_attribute, :created_date_iso, :created_at
101
+ it_behaves_like :not_raise_without_attribute, :auth_date_iso, :authorized_at
102
+ it_behaves_like :not_raise_without_attribute, :confirm_date_iso, :confirmed_at
103
+ it_behaves_like :not_raise_without_attribute, :auth_code
104
+ it_behaves_like :not_raise_without_attribute, :ip_address
105
+ it_behaves_like :not_raise_without_attribute, :ip_country
106
+ it_behaves_like :not_raise_without_attribute, :ip_city
107
+ it_behaves_like :not_raise_without_attribute, :ip_region
108
+ it_behaves_like :not_raise_without_attribute, :ip_district
109
+ it_behaves_like :not_raise_without_attribute, :ip_latitude, :ip_lat
110
+ it_behaves_like :not_raise_without_attribute, :ip_longitude, :ip_lng
111
+ it_behaves_like :not_raise_without_attribute, :card_type_code
112
+ it_behaves_like :not_raise_without_attribute, :card_exp_date
113
+ it_behaves_like :not_raise_without_attribute, :issuer_bank_country
114
+ it_behaves_like :not_raise_without_attribute, :reason
115
+ it_behaves_like :not_raise_without_attribute, :reason_code
116
+ it_behaves_like :not_raise_without_attribute, :card_holder_message
117
+ it_behaves_like :not_raise_without_attribute, :name
118
+ it_behaves_like :not_raise_without_attribute, :token
119
+
120
+ context 'without `metadata` attribute' do
121
+ subject do
122
+ attrs = attributes.dup
123
+ attrs.delete(:json_data)
124
+ described_class.new(attrs)
125
+ end
126
+
127
+ specify{ expect{ subject }.not_to raise_error }
128
+ specify{ expect(subject.metadata).to eq({}) }
129
+ end
130
+ end
131
+
132
+ describe 'status' do
133
+ let(:attributes){ {
134
+ transaction_id: 504,
135
+ amount: 10.0,
136
+ currency: 'RUB',
137
+ test_mode: true,
138
+ card_first_six: '411111',
139
+ card_last_four: '1111',
140
+ card_type: 'Visa',
141
+ card_exp_date: '10/17',
142
+ status: status
143
+ } }
144
+
145
+ context 'when status == AwaitingAuthentication' do
146
+ let(:status){ 'AwaitingAuthentication' }
147
+ specify{ expect(subject).to be_awaiting_authentication }
148
+ specify{ expect(subject).not_to be_completed }
149
+ specify{ expect(subject).not_to be_authorized }
150
+ specify{ expect(subject).not_to be_cancelled }
151
+ specify{ expect(subject).not_to be_declined }
152
+ end
153
+
154
+ context 'when status == Completed' do
155
+ let(:status){ 'Completed' }
156
+ specify{ expect(subject).not_to be_awaiting_authentication }
157
+ specify{ expect(subject).to be_completed }
158
+ specify{ expect(subject).not_to be_authorized }
159
+ specify{ expect(subject).not_to be_cancelled }
160
+ specify{ expect(subject).not_to be_declined }
161
+ end
162
+
163
+ context 'when status == Authorized' do
164
+ let(:status){ 'Authorized' }
165
+ specify{ expect(subject).not_to be_awaiting_authentication }
166
+ specify{ expect(subject).not_to be_completed }
167
+ specify{ expect(subject).to be_authorized }
168
+ specify{ expect(subject).not_to be_cancelled }
169
+ specify{ expect(subject).not_to be_declined }
170
+ end
171
+
172
+ context 'when status == Cancelled' do
173
+ let(:status){ 'Cancelled' }
174
+ specify{ expect(subject).not_to be_awaiting_authentication }
175
+ specify{ expect(subject).not_to be_completed }
176
+ specify{ expect(subject).not_to be_authorized }
177
+ specify{ expect(subject).to be_cancelled }
178
+ specify{ expect(subject).not_to be_declined }
179
+ end
180
+
181
+ context 'when status == Declined' do
182
+ let(:status){ 'Declined' }
183
+ specify{ expect(subject).not_to be_awaiting_authentication }
184
+ specify{ expect(subject).not_to be_completed }
185
+ specify{ expect(subject).not_to be_authorized }
186
+ specify{ expect(subject).not_to be_cancelled }
187
+ specify{ expect(subject).to be_declined }
188
+ end
189
+ end
190
+
191
+ context do
192
+ let(:attributes){ {} }
193
+ let(:default_attributes){ {
194
+ transaction_id: 504,
195
+ amount: 10.0,
196
+ currency: 'RUB',
197
+ test_mode: true,
198
+ card_first_six: '411111',
199
+ card_last_four: '1111',
200
+ card_type: 'Visa',
201
+ card_exp_date: '10/17',
202
+ status: 'Completed'
203
+ } }
204
+
205
+ subject{ CloudPayments::Transaction.new(default_attributes.merge(attributes)) }
206
+
207
+ describe '#subscription' do
208
+ before{ stub_api_request('subscriptions/find/successful').perform }
209
+
210
+ context 'with subscription_id' do
211
+ let(:attributes){ { subscription_id: 'sc_8cf8a9338fb' } }
212
+
213
+ specify{ expect(subject.subscription).to be_instance_of(CloudPayments::Subscription) }
214
+
215
+ context do
216
+ let(:sub){ subject.subscription }
217
+
218
+ specify{ expect(sub.id).to eq('sc_8cf8a9338fb') }
219
+ specify{ expect(sub.account_id).to eq('user@example.com') }
220
+ specify{ expect(sub.description).to eq('Monthly subscription') }
221
+ specify{ expect(sub.started_at).to eq(DateTime.parse('2014-08-09T11:49:41')) }
222
+ specify{ expect(sub).to be_active }
223
+ end
224
+ end
225
+
226
+ context 'without subscription_id' do
227
+ specify{ expect(subject.subscription).to be_nil }
228
+ end
229
+ end
230
+
231
+ describe '#card_number' do
232
+ specify{ expect(subject.card_number).to eq('4111 11XX XXXX 1111') }
233
+ end
234
+
235
+ describe '#ip_location' do
236
+ specify{ expect(subject.ip_location).to be_nil }
237
+
238
+ context do
239
+ let(:attributes){ { ip_latitude: 12.34, ip_longitude: 56.78 } }
240
+ specify{ expect(subject.ip_location).to eq([12.34, 56.78]) }
241
+ end
242
+
243
+ context do
244
+ let(:attributes){ { ip_latitude: 12.34 } }
245
+ specify{ expect(subject.ip_location).to be_nil }
246
+ end
247
+
248
+ context do
249
+ let(:attributes){ { ip_longitude: 12.34 } }
250
+ specify{ expect(subject.ip_location).to be_nil }
251
+ end
252
+ end
253
+ end
254
+ end