bill_forward 1.2014.296

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 (84) hide show
  1. data/.gitignore +27 -0
  2. data/.idea/.name +1 -0
  3. data/.idea/compiler.xml +23 -0
  4. data/.idea/copyright/profiles_settings.xml +3 -0
  5. data/.idea/encodings.xml +5 -0
  6. data/.idea/inspectionProfiles/Project_Default.xml +11 -0
  7. data/.idea/inspectionProfiles/profiles_settings.xml +7 -0
  8. data/.idea/misc.xml +23 -0
  9. data/.idea/modules.xml +9 -0
  10. data/.idea/scopes/scope_settings.xml +5 -0
  11. data/.idea/vcs.xml +7 -0
  12. data/.rspec +2 -0
  13. data/Gemfile +9 -0
  14. data/LICENSE.md +22 -0
  15. data/README.md +227 -0
  16. data/Rakefile +73 -0
  17. data/bill_forward.gemspec +29 -0
  18. data/bill_forward.iml +28 -0
  19. data/lib/bill_forward.rb +18 -0
  20. data/lib/bill_forward/billing_entity.rb +263 -0
  21. data/lib/bill_forward/client.rb +355 -0
  22. data/lib/bill_forward/custom_hash.rb +14 -0
  23. data/lib/bill_forward/deny_method.rb +4 -0
  24. data/lib/bill_forward/entities/account.rb +19 -0
  25. data/lib/bill_forward/entities/address.rb +25 -0
  26. data/lib/bill_forward/entities/amendments/amendment.rb +11 -0
  27. data/lib/bill_forward/entities/amendments/invoice_recalculation_amendment.rb +10 -0
  28. data/lib/bill_forward/entities/api_configuration.rb +11 -0
  29. data/lib/bill_forward/entities/authorize_net_token.rb +9 -0
  30. data/lib/bill_forward/entities/credit_note.rb +13 -0
  31. data/lib/bill_forward/entities/invoice.rb +25 -0
  32. data/lib/bill_forward/entities/invoice_parts/invoice_line.rb +37 -0
  33. data/lib/bill_forward/entities/invoice_parts/invoice_payment.rb +29 -0
  34. data/lib/bill_forward/entities/invoice_parts/tax_line.rb +23 -0
  35. data/lib/bill_forward/entities/invoice_parts/taxation_link.rb +5 -0
  36. data/lib/bill_forward/entities/organisation.rb +37 -0
  37. data/lib/bill_forward/entities/payment_method.rb +5 -0
  38. data/lib/bill_forward/entities/payment_method_subscription_link.rb +5 -0
  39. data/lib/bill_forward/entities/pricing_component.rb +21 -0
  40. data/lib/bill_forward/entities/pricing_component_tier.rb +5 -0
  41. data/lib/bill_forward/entities/pricing_component_value.rb +5 -0
  42. data/lib/bill_forward/entities/pricing_component_value_change.rb +5 -0
  43. data/lib/bill_forward/entities/product.rb +5 -0
  44. data/lib/bill_forward/entities/product_rate_plan.rb +19 -0
  45. data/lib/bill_forward/entities/profile.rb +15 -0
  46. data/lib/bill_forward/entities/role.rb +4 -0
  47. data/lib/bill_forward/entities/subscription.rb +53 -0
  48. data/lib/bill_forward/entities/unit_of_measure.rb +5 -0
  49. data/lib/bill_forward/insertable_entity.rb +32 -0
  50. data/lib/bill_forward/mutable_entity.rb +47 -0
  51. data/lib/bill_forward/resource_path.rb +11 -0
  52. data/lib/bill_forward/type_check.rb +21 -0
  53. data/lib/bill_forward/version.rb +4 -0
  54. data/spec/component/account_spec.rb +200 -0
  55. data/spec/component/billing_entity_spec.rb +153 -0
  56. data/spec/component/invoice_spec.rb +155 -0
  57. data/spec/component/subscription_spec.rb +357 -0
  58. data/spec/functional/account_spec.rb +25 -0
  59. data/spec/functional/bad_citizen/account_spec.rb +103 -0
  60. data/spec/functional/bad_citizen/credit_note_spec.rb +41 -0
  61. data/spec/functional/bad_citizen/payment_method_spec.rb +34 -0
  62. data/spec/functional/bad_citizen/product_rate_plan_spec.rb +105 -0
  63. data/spec/functional/bad_citizen/product_spec.rb +22 -0
  64. data/spec/functional/bad_citizen/situational/authorize_net_token_spec.rb +27 -0
  65. data/spec/functional/bad_citizen/situational/invoice_recalculation_amendment_spec.rb +27 -0
  66. data/spec/functional/bad_citizen/situational/invoice_spec.rb +22 -0
  67. data/spec/functional/bad_citizen/situational/malordered_entity_spec.rb +43 -0
  68. data/spec/functional/bad_citizen/situational/organisation_spec.rb +39 -0
  69. data/spec/functional/bad_citizen/situational/payment_method_spec.rb +47 -0
  70. data/spec/functional/bad_citizen/situational/subscription_chargeable_spec.rb +255 -0
  71. data/spec/functional/bad_citizen/subscription_spec.rb +179 -0
  72. data/spec/functional/bad_citizen/subscription_with_credit_spec.rb +240 -0
  73. data/spec/functional/bad_citizen/unit_of_measure_spec.rb +20 -0
  74. data/spec/functional/billing_entity_spec.rb +22 -0
  75. data/spec/functional/client_spec.rb +24 -0
  76. data/spec/functional/organisation_spec.rb +28 -0
  77. data/spec/setup_test_constants.rb +73 -0
  78. data/spec/spec_helper.rb +11 -0
  79. data/spec/syntax/account_spec.rb +24 -0
  80. data/spec/syntax/address_spec.rb +19 -0
  81. data/spec/syntax/api_configuration_spec.rb +13 -0
  82. data/spec/syntax/billing_entity_spec.rb +93 -0
  83. data/spec/syntax/client_spec.rb +8 -0
  84. metadata +287 -0
@@ -0,0 +1,240 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "spec_helper")
2
+
3
+ describe BillForward::Subscription do
4
+ before :all do
5
+ @client = BillForwardTest::TEST_CLIENT
6
+ BillForward::Client.default_client = @client
7
+ end
8
+ context 'upon creating required entities for chargeable Subscription' do
9
+ before :all do
10
+ # get our organisation
11
+ organisations = BillForward::Organisation.get_mine
12
+ first_org = organisations.first
13
+
14
+
15
+ # create an account
16
+ # requires (optionally):
17
+ # - profile
18
+ # - - addresses
19
+ addresses = Array.new()
20
+ addresses.push(
21
+ BillForward::Address.new({
22
+ 'addressLine1' => 'address line 1',
23
+ 'addressLine2' => 'address line 2',
24
+ 'addressLine3' => 'address line 3',
25
+ 'city' => 'London',
26
+ 'province' => 'London',
27
+ 'country' => 'United Kingdom',
28
+ 'postcode' => 'SW1 1AS',
29
+ 'landline' => '02000000000',
30
+ 'primaryAddress' => true
31
+ }))
32
+ profile = BillForward::Profile.new({
33
+ 'email' => 'always@testing.is.moe',
34
+ 'firstName' => 'Test',
35
+ 'addresses' => addresses
36
+ })
37
+ account = BillForward::Account.new({
38
+ 'profile' => profile
39
+ })
40
+ created_account = BillForward::Account.create account
41
+
42
+
43
+ # create for our account: a new payment method, using credit notes
44
+ payment_method = BillForward::PaymentMethod.new({
45
+ 'accountID' => created_account.id,
46
+ 'name' => 'Credit Notes',
47
+ 'description' => 'Pay using credit',
48
+ # engines will link this to an invoice once paid, for the sake of refunds
49
+ 'linkID' => '',
50
+ 'gateway' => 'credit_note',
51
+ 'userEditable' => 0,
52
+ 'priority' => 100,
53
+ 'reusable' => 1
54
+ })
55
+ created_payment_method = BillForward::PaymentMethod::create(payment_method)
56
+
57
+
58
+ # issue $100 credit to our account
59
+ credit_note = BillForward::CreditNote.new({
60
+ "accountID" => created_account.id,
61
+ "nominalValue" => 100,
62
+ "currency" => "USD"
63
+ })
64
+ created_credit_note = BillForward::CreditNote.create(credit_note)
65
+
66
+
67
+ # create a unit of measure
68
+ unit_of_measure = BillForward::UnitOfMeasure.new({
69
+ 'name' => 'Devices',
70
+ 'displayedAs' => 'Devices',
71
+ 'roundingScheme' => 'UP',
72
+ })
73
+ created_uom = BillForward::UnitOfMeasure.create(unit_of_measure)
74
+
75
+
76
+ # create a product
77
+ product = BillForward::Product.new({
78
+ 'productType' => 'non-recurring',
79
+ 'state' => 'prod',
80
+ 'name' => 'Month of Paracetamoxyfrusebendroneomycin',
81
+ 'description' => 'It can cure the common cold and being struck by lightning',
82
+ 'durationPeriod' => 'minutes',
83
+ 'duration' => 1,
84
+ })
85
+ created_product = BillForward::Product::create(product)
86
+
87
+
88
+ # make product rate plan..
89
+ # requires:
90
+ # - product,
91
+ # - pricing components..
92
+ # .. - which require pricing component tiers
93
+
94
+ # create tiers..
95
+ # for a flat pricing component:
96
+ tiers_for_flat_component_1 = Array.new()
97
+ tiers_for_flat_component_1.push(
98
+ BillForward::PricingComponentTier.new({
99
+ 'lowerThreshold' => 1,
100
+ 'upperThreshold' => 1,
101
+ 'pricingType' => 'fixed',
102
+ 'price' => 1,
103
+ }))
104
+
105
+ # for a tiered pricing component:
106
+ tiers_for_tiered_component_1 = Array.new()
107
+ tiers_for_tiered_component_1.push(
108
+ BillForward::PricingComponentTier.new({
109
+ 'lowerThreshold' => 1,
110
+ 'upperThreshold' => 1,
111
+ 'pricingType' => 'fixed',
112
+ 'price' => 10,
113
+ }),
114
+ BillForward::PricingComponentTier.new({
115
+ 'lowerThreshold' => 2,
116
+ 'upperThreshold' => 10,
117
+ 'pricingType' => 'unit',
118
+ 'price' => 5
119
+ }),
120
+ BillForward::PricingComponentTier.new({
121
+ 'lowerThreshold' => 11,
122
+ 'upperThreshold' => 100,
123
+ 'pricingType' => 'unit',
124
+ 'price' => 2
125
+ }))
126
+
127
+
128
+ # create pricing components, based on these tiers
129
+ pricing_components = Array.new()
130
+ pricing_components.push(
131
+ BillForward::PricingComponent.new({
132
+ '@type' => 'flatPricingComponent',
133
+ 'chargeModel' => 'flat',
134
+ 'name' => 'Devices used, fixed',
135
+ 'description' => 'How many devices you use, I guess',
136
+ 'unitOfMeasureID' => created_uom.id,
137
+ 'chargeType' => 'subscription',
138
+ 'upgradeMode' => 'immediate',
139
+ 'downgradeMode' => 'immediate',
140
+ 'defaultQuantity' => 1,
141
+ 'tiers' => tiers_for_flat_component_1
142
+ }),
143
+ BillForward::PricingComponent.new({
144
+ '@type' => 'tieredPricingComponent',
145
+ 'chargeModel' => 'tiered',
146
+ 'name' => 'Devices used, tiered',
147
+ 'description' => 'How many devices you use, but with a tiering system',
148
+ 'unitOfMeasureID' => created_uom.id,
149
+ 'chargeType' => 'usage',
150
+ 'upgradeMode' => 'immediate',
151
+ 'downgradeMode' => 'immediate',
152
+ 'defaultQuantity' => 10,
153
+ 'tiers' => tiers_for_tiered_component_1
154
+ }))
155
+
156
+
157
+ # create product rate plan, using pricing components and product
158
+ prp = BillForward::ProductRatePlan.new({
159
+ 'currency' => 'USD',
160
+ 'name' => 'A sound plan',
161
+ 'pricingComponents' => pricing_components,
162
+ 'productID' => created_product.id,
163
+ })
164
+ created_prp = BillForward::ProductRatePlan.create(prp)
165
+
166
+
167
+ # create references for tests to use
168
+ @created_account = created_account
169
+ @created_prp = created_prp
170
+ @created_payment_method = created_payment_method
171
+ end
172
+ describe '::create' do
173
+ describe 'the subscription' do
174
+ before :all do
175
+ # make subscription..
176
+ # requires:
177
+ # - account [we have this already]
178
+ # - product rate plan [we have this already]
179
+ # - pricing component value instances (for every pricing component on the PRP)
180
+ # - payment method subscription links (for every payment method on the account)
181
+
182
+ # create PaymentMethodSubscriptionLink from payment method and organisation
183
+ payment_method_subscription_links = Array.new
184
+ payment_method_subscription_links.push(
185
+ BillForward::PaymentMethodSubscriptionLink.new({
186
+ 'paymentMethodID' => @created_payment_method.id
187
+ }))
188
+
189
+
190
+ pricing_components = @created_prp.pricingComponents
191
+ # get references to each pricing component we made
192
+ flat_pricing_component_1 = pricing_components[0]
193
+ tiered_pricing_component_1 = pricing_components[1]
194
+
195
+ # create PricingComponentValue instances for every PricingComponent on the PRP
196
+ pricing_component_values = Array.new
197
+ pricing_component_values.push(
198
+ BillForward::PricingComponentValue.new({
199
+ 'pricingComponentID' => flat_pricing_component_1.id,
200
+ 'value' => 1,
201
+ }),
202
+ BillForward::PricingComponentValue.new({
203
+ 'pricingComponentID' => tiered_pricing_component_1.id,
204
+ 'value' => 5,
205
+ }))
206
+
207
+
208
+ # create subscription
209
+ subscription = BillForward::Subscription.new({
210
+ 'type' => 'Subscription',
211
+ 'productRatePlanID' => @created_prp.id,
212
+ 'accountID' => @created_account.id,
213
+ 'name' => 'Memorable Subscription',
214
+ 'description' => 'Memorable Subscription Description',
215
+ 'paymentMethodSubscriptionLinks' => payment_method_subscription_links,
216
+ 'pricingComponentValues' => pricing_component_values
217
+ })
218
+ created_sub = BillForward::Subscription.create(subscription)
219
+
220
+ # create references for tests to use
221
+ @created_sub = created_sub
222
+ end
223
+ subject(:subscription) { @created_sub }
224
+ it 'is created' do
225
+ expect(subscription['@type']).to eq(BillForward::Subscription.resource_path.entity_name)
226
+ end
227
+ it 'can be gotten' do
228
+ gotten_subscription = BillForward::Subscription.get_by_id(subscription.id)
229
+ expect(gotten_subscription['@type']).to eq(BillForward::Subscription.resource_path.entity_name)
230
+ end
231
+ it 'can be activated' do
232
+ expect(subscription['state']).to eq('Provisioned')
233
+ updated_subscription = subscription.activate
234
+
235
+ expect(updated_subscription['state']).to eq('AwaitingPayment')
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
@@ -0,0 +1,20 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "..", "spec_helper")
2
+
3
+ describe BillForward::UnitOfMeasure do
4
+ before :all do
5
+ @client = BillForwardTest::TEST_CLIENT
6
+ BillForward::Client.default_client = @client
7
+ end
8
+ describe '::create' do
9
+ it 'creates a UnitOfMeasure' do
10
+ unit_of_measure = BillForward::UnitOfMeasure.new({
11
+ 'name' => 'Devices',
12
+ 'displayedAs' => 'Devices',
13
+ 'roundingScheme' => 'UP',
14
+ })
15
+ created_uom = BillForward::UnitOfMeasure.create(unit_of_measure)
16
+
17
+ expect(created_uom['@type']).to eq(BillForward::UnitOfMeasure.resource_path.entity_name)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,22 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "spec_helper")
2
+
3
+ describe BillForward::BillingEntity do
4
+ before :all do
5
+ @client = BillForwardTest::TEST_CLIENT
6
+ BillForward::Client.default_client = @client
7
+ end
8
+ describe '::get_all' do
9
+ context 'with query parameters' do
10
+ it "should allow number of records to be specified" do
11
+ # ensure that at least one account exists in addition to our login
12
+ BillForward::Account.create
13
+
14
+ records = BillForward::Account.get_all({
15
+ 'records' => 1
16
+ })
17
+
18
+ expect(records.length).to eq(1)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "spec_helper")
2
+
3
+ describe BillForward::Client do
4
+ describe '#new' do
5
+ before :all do
6
+ @client = BillForwardTest::TEST_CLIENT
7
+ BillForward::Client.default_client = @client
8
+ end
9
+ it "should find empty results upon looking up non-existent ID" do
10
+ account_id = "nonexist"
11
+
12
+ expect{BillForward::Account.get_by_id account_id}.to raise_error(IndexError)
13
+ end
14
+ it "should raise upon bad token" do
15
+ host=@client.host
16
+ token="badtoken"
17
+ dudclient = BillForward::Client.new(
18
+ :host => host,
19
+ :api_token => token
20
+ )
21
+ expect{BillForward::Organisation.get_mine(nil,dudclient)}.to raise_error(BillForward::ApiAuthorizationError)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "spec_helper")
2
+
3
+ describe BillForward::Account do
4
+ before :all do
5
+ @client = BillForwardTest::TEST_CLIENT
6
+ BillForward::Client.default_client = @client
7
+ end
8
+ describe '::get_all' do
9
+ it 'raises permissions error' do
10
+ # 'admin' privilege is insufficient to see other organisations
11
+ expect{BillForward::Organisation::get_all}.to raise_error(BillForward::ApiError, /415/)
12
+ # TODO: consider that API v219 (at least) gives instead:
13
+ # ====
14
+ # 400 API Error.
15
+ # Type: PermissionsError
16
+ # Message: Access is denied
17
+ # ====
18
+ end
19
+ end
20
+ describe '::get_mine' do
21
+ it "should find organisations" do
22
+ organisations = BillForward::Organisation.get_mine
23
+ organisations_first = organisations.first
24
+
25
+ expect(organisations_first['@type']).to eq(BillForward::Organisation.resource_path.entity_name)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,73 @@
1
+ # constants include BillForward credentials, required for running functional tests.
2
+ # this file, ignored from version control, allows users to specify credentials for a test account
3
+ test_constants_file = File.join(File.expand_path(File.dirname(__FILE__)), "test_constants.rb")
4
+ if (File.exist?(test_constants_file))
5
+ puts "using test constants from #{test_constants_file}"
6
+ require test_constants_file
7
+ else
8
+ puts 'using default test constants'
9
+ # The following is a template for what your 'test_constants.rb' should contain.
10
+ # If used in this placeholder state, functional tests will not pass.
11
+ module BillForwardTest
12
+ BILLFORWARD_API_HOST='insert-API-URL-here'
13
+ BILLFORWARD_API_TOKEN="insert-access-token-here OR leave-blank-for-OAUTH"
14
+
15
+ ### alternatively:
16
+ # (these values are used if you leave API token blank)
17
+ # authenticate using OAUTH:
18
+ BILLFORWARD_USERNAME="insert-username"
19
+ BILLFORWARD_PASSWORD="insert-password"
20
+ BILLFORWARD_CLIENT_ID="insert-client-id"
21
+ BILLFORWARD_CLIENT_SECRET="insert-client-secret"
22
+
23
+
24
+ # ---- Enable logging if you want (shows request and response bodies)
25
+ USE_LOGGING=false
26
+
27
+
28
+ # ---- Enable proxy if you want (for example to see requests in Fiddler)
29
+ CLIENT_PROXY_ENABLED=false
30
+ CLIENT_PROXY_URL="http://127.0.0.1:8888"
31
+
32
+
33
+ ## These constants are required only for running situational tests (not in the main run):
34
+ # ---- Required for Authorize.Net gateway tests only
35
+ AUTHORIZE_NET_LOGIN_ID = 'FILL IN WITH AUTHORIZE NET LOGIN ID'
36
+ AUTHORIZE_NET_TRANSACTION_KEY = 'FILL IN WITH AUTHORIZE NET TRANSACTION KEY'
37
+ # ---- Required for Authorize.Net tokenization tests only
38
+ AUTHORIZE_NET_CUSTOMER_PROFILE_ID = 12345678 # FILL IN WITH AUTHORIZE NET CUSTOMER PROFILE ID
39
+ AUTHORIZE_NET_CUSTOMER_PAYMENT_PROFILE_ID = 12345678 # FILL IN WITH AUTHORIZE NET CUSTOMER PAYMENT PROFILE ID
40
+ AUTHORIZE_NET_CARD_LAST_4_DIGITS = 1234
41
+
42
+
43
+ # ---- Required for Invoice tests only
44
+ USUAL_INVOICE_ID = 'FILL IN WITH EXISTING INVOICE ID'
45
+ end
46
+ end
47
+
48
+ # create BillForward client for use in all tests
49
+ # requires working credentials only when running functional tests
50
+ module BillForwardTest
51
+ if (BillForwardTest::BILLFORWARD_API_TOKEN == '')
52
+ # Authenticate using OAuth; username and password
53
+ TEST_CLIENT = BillForward::Client.new(
54
+ :host => BillForwardTest::BILLFORWARD_API_HOST,
55
+ :use_logging => BillForwardTest::USE_LOGGING,
56
+ :username => BillForwardTest::BILLFORWARD_USERNAME,
57
+ :password => BillForwardTest::BILLFORWARD_PASSWORD,
58
+ :client_id => BillForwardTest::BILLFORWARD_CLIENT_ID,
59
+ :client_secret => BillForwardTest::BILLFORWARD_CLIENT_SECRET,
60
+ :use_proxy => BillForwardTest::CLIENT_PROXY_ENABLED,
61
+ :proxy_url => BillForwardTest::CLIENT_PROXY_URL
62
+ )
63
+ else
64
+ # Authenticate instead using access token
65
+ TEST_CLIENT = BillForward::Client.new(
66
+ :host => BillForwardTest::BILLFORWARD_API_HOST,
67
+ :use_logging => BillForwardTest::USE_LOGGING,
68
+ :api_token => BillForwardTest::BILLFORWARD_API_TOKEN,
69
+ :use_proxy => BillForwardTest::CLIENT_PROXY_ENABLED,
70
+ :proxy_url => BillForwardTest::CLIENT_PROXY_URL
71
+ )
72
+ end
73
+ end
@@ -0,0 +1,11 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'bill_forward' # and any other gems you need
5
+
6
+ # this file provides constants for tests to share
7
+ require File.join(File.expand_path(File.dirname(__FILE__)), "setup_test_constants")
8
+
9
+ RSpec.configure do |config|
10
+ # some (optional) config here
11
+ end
@@ -0,0 +1,24 @@
1
+ require File.join(File.expand_path(File.dirname(__FILE__)), "..", "spec_helper")
2
+
3
+ describe BillForward::Account do
4
+ describe '#new' do
5
+ it "provides access to client" do
6
+ host="http://localhost:8080/RestAPI/"
7
+ environment="development"
8
+ token="6f1f7465-fc16-4b9c-9ea0-f8c208a43ca6"
9
+ dudclient = BillForward::Client.new(
10
+ :host => host,
11
+ :environment => environment,
12
+ :api_token => token
13
+ )
14
+ account = BillForward::Account.new(nil, dudclient)
15
+ expect(account._client.host).to eq(host)
16
+ end
17
+ end
18
+ describe '::resource_path' do
19
+ it "points to expected endpoint" do
20
+ resource_path = BillForward::Account.resource_path
21
+ expect(resource_path.path).to eq("accounts")
22
+ end
23
+ end
24
+ end