boffinio 0.0.1

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 (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +22 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +2 -0
  7. data/boffinio.gemspec +31 -0
  8. data/lib/boffinio/api_operations/create.rb +16 -0
  9. data/lib/boffinio/api_operations/delete.rb +11 -0
  10. data/lib/boffinio/api_operations/list.rb +16 -0
  11. data/lib/boffinio/api_operations/update.rb +57 -0
  12. data/lib/boffinio/api_resource.rb +33 -0
  13. data/lib/boffinio/boffinio_object.rb +190 -0
  14. data/lib/boffinio/customer.rb +36 -0
  15. data/lib/boffinio/errors/api_error.rb +4 -0
  16. data/lib/boffinio/errors/authentication_error.rb +4 -0
  17. data/lib/boffinio/errors/boffinio_error.rb +20 -0
  18. data/lib/boffinio/errors/invalid_request_error.rb +4 -0
  19. data/lib/boffinio/list_object.rb +35 -0
  20. data/lib/boffinio/plan.rb +7 -0
  21. data/lib/boffinio/subscription.rb +10 -0
  22. data/lib/boffinio/util.rb +87 -0
  23. data/lib/boffinio/version.rb +3 -0
  24. data/lib/boffinio.rb +229 -0
  25. data/test/customer/customer_test.rb +149 -0
  26. data/test/fixtures/all_customers.yml +62 -0
  27. data/test/fixtures/cancel_subscription.yml +62 -0
  28. data/test/fixtures/create_customer.yml +66 -0
  29. data/test/fixtures/create_subscription.yml +66 -0
  30. data/test/fixtures/customer_subscriptions.yml +62 -0
  31. data/test/fixtures/one_customer.yml +67 -0
  32. data/test/fixtures/update_customer.yml +64 -0
  33. data/test/fixtures/update_named_subscription.yml +64 -0
  34. data/test/fixtures/update_subscription.yml +66 -0
  35. data/test/subscription/subscription_test.rb +0 -0
  36. data/test/test_helper.rb +13 -0
  37. metadata +210 -0
data/lib/boffinio.rb ADDED
@@ -0,0 +1,229 @@
1
+ require 'cgi'
2
+ require 'set'
3
+ require 'json'
4
+ #Version
5
+ require_relative "boffinio/version"
6
+
7
+ #API Operations
8
+ require_relative 'boffinio/api_operations/list'
9
+ require_relative 'boffinio/api_operations/create'
10
+ require_relative 'boffinio/api_operations/delete'
11
+ require_relative 'boffinio/api_operations/update'
12
+
13
+ #Resources
14
+ require_relative 'boffinio/util'
15
+ require_relative 'boffinio/boffinio_object'
16
+ require_relative 'boffinio/api_resource'
17
+ require_relative "boffinio/list_object"
18
+ require_relative "boffinio/customer"
19
+ require_relative "boffinio/subscription"
20
+ require_relative "boffinio/plan"
21
+
22
+ #Errors
23
+ require_relative 'boffinio/errors/boffinio_error'
24
+ require_relative 'boffinio/errors/api_error'
25
+ require_relative 'boffinio/errors/authentication_error'
26
+ require_relative 'boffinio/errors/invalid_request_error'
27
+
28
+ require 'rest-client'
29
+
30
+ module BoffinIO
31
+
32
+ @api_base = 'https://api.boffin.io'
33
+ @api_version = "v1"
34
+
35
+ class << self
36
+ attr_accessor :api_key, :api_base, :verify_ssl_certs, :api_version
37
+ end
38
+
39
+ def self.api_url(url='')
40
+ @api_base+url
41
+ end
42
+
43
+ def self.request(method, url, api_key, params={}, headers={})
44
+ unless api_key ||= @api_key
45
+ raise AuthenticationError.new('No API key provided. ' +
46
+ 'Set your API key using "BoffinIO.api_key = <API-KEY>". ' +
47
+ 'You can generate API keys from the Boffin web interface. ')
48
+ end
49
+
50
+ if api_key =~ /\s/
51
+ raise AuthenticationError.new('Your API key is invalid, as it contains ' +
52
+ 'whitespace. (HINT: You can double-check your API key from the ' +
53
+ 'Boffin web interface. See https://boffion.io/api for details, or ' +
54
+ 'email support@boffin.io if you have any questions.)')
55
+ end
56
+
57
+ request_opts = { :verify_ssl => false }
58
+
59
+ params = Util.objects_to_ids(params)
60
+ url = api_url(url)
61
+
62
+ case method.to_s.downcase.to_sym
63
+ when :get, :head, :delete
64
+ # Make params into GET parameters
65
+ url += "#{URI.parse(url).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any?
66
+ payload = nil
67
+ else
68
+ payload = uri_encode(params)
69
+ end
70
+ request_opts.update(:headers => request_headers(api_key).update(headers),
71
+ :method => method, :open_timeout => 30,
72
+ :payload => payload, :url => url, :timeout => 80)
73
+
74
+ begin
75
+ response = execute_request(request_opts)
76
+ rescue SocketError => e
77
+ handle_restclient_error(e)
78
+ rescue NoMethodError => e
79
+ # Work around RestClient bug
80
+ if e.message =~ /\WRequestFailed\W/
81
+ e = APIConnectionError.new('Unexpected HTTP response code')
82
+ handle_restclient_error(e)
83
+ else
84
+ raise
85
+ end
86
+ rescue RestClient::ExceptionWithResponse => e
87
+ if rcode = e.http_code and rbody = e.http_body
88
+ handle_api_error(rcode, rbody)
89
+ else
90
+ handle_restclient_error(e)
91
+ end
92
+ rescue RestClient::Exception, Errno::ECONNREFUSED => e
93
+ handle_restclient_error(e)
94
+ end
95
+
96
+ [parse(response), api_key]
97
+ end
98
+
99
+ def self.user_agent
100
+ @uname ||= get_uname
101
+ lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
102
+
103
+ {
104
+ :bindings_version => BoffinIO::VERSION,
105
+ :lang => 'ruby',
106
+ :lang_version => lang_version,
107
+ :platform => RUBY_PLATFORM,
108
+ :publisher => 'boffinio',
109
+ :uname => @uname
110
+ }
111
+
112
+ end
113
+
114
+ def self.get_uname
115
+ `uname -a 2>/dev/null`.strip if RUBY_PLATFORM =~ /linux|darwin/i
116
+ rescue Errno::ENOMEM => ex # couldn't create subprocess
117
+ "uname lookup failed"
118
+ end
119
+
120
+ def self.request_headers(api_key)
121
+ headers = {
122
+ :user_agent => "Boffin/v1 RubyBindings/#{BoffinIO::VERSION}",
123
+ :authorization => "Token token=#{api_key}",
124
+ :content_type => 'application/x-www-form-urlencoded'
125
+ }
126
+
127
+ headers[:boffinio_version] = api_version if api_version
128
+
129
+ begin
130
+ headers.update(:x_boffinio_client_user_agent => JSON.generate(user_agent))
131
+ rescue => e
132
+ headers.update(:x_boffinio_client_raw_user_agent => user_agent.inspect,
133
+ :error => "#{e} (#{e.class})")
134
+ end
135
+ end
136
+
137
+ def self.uri_encode(params)
138
+ Util.flatten_params(params).
139
+ map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
140
+ end
141
+
142
+ def self.execute_request(opts)
143
+ RestClient::Request.execute(opts)
144
+ end
145
+
146
+ def self.parse(response)
147
+ begin
148
+ # Would use :symbolize_names => true, but apparently there is
149
+ # some library out there that makes symbolize_names not work.
150
+ response = JSON.parse(response.body)
151
+ rescue JSON::ParserError
152
+ raise general_api_error(response.code, response.body)
153
+ end
154
+
155
+ Util.symbolize_names(response)
156
+ end
157
+
158
+ def self.handle_api_error(rcode, rbody)
159
+ begin
160
+ error_obj = JSON.parse(rbody)
161
+ error_obj = Util.symbolize_names(error_obj)
162
+ error = error_obj[:error] or raise BoffinIOError.new # escape from parsing
163
+
164
+ rescue JSON::ParserError, BoffinIOError
165
+ raise general_api_error(rcode, rbody)
166
+ end
167
+
168
+ case rcode
169
+ when 400, 404
170
+ raise invalid_request_error error, rcode, rbody, error_obj
171
+ when 401
172
+ raise authentication_error error, rcode, rbody, error_obj
173
+ else
174
+ raise api_error error, rcode, rbody, error_obj
175
+ end
176
+
177
+ end
178
+
179
+ def self.invalid_request_error(error, rcode, rbody, error_obj)
180
+ InvalidRequestError.new(error[:message], error[:param], rcode,
181
+ rbody, error_obj)
182
+ end
183
+
184
+ def self.authentication_error(error, rcode, rbody, error_obj)
185
+ AuthenticationError.new(error[:message], rcode, rbody, error_obj)
186
+ end
187
+
188
+ def self.api_error(error, rcode, rbody, error_obj)
189
+ APIError.new(error[:message], rcode, rbody, error_obj)
190
+ end
191
+
192
+ def self.general_api_error(rcode, rbody)
193
+ BoffinIOError.new("Invalid response object from API: #{rbody.inspect} " +
194
+ "(HTTP response code was #{rcode})", rcode, rbody)
195
+ end
196
+
197
+ def self.handle_restclient_error(e)
198
+ connection_message = "Please check your internet connection and try again. " \
199
+ "If this problem persists, you should check Boffin's service status at " \
200
+ "https://twitter.com/boffinio, or let us know at support@boffin.io."
201
+
202
+ case e
203
+ when RestClient::RequestTimeout
204
+ message = "Could not connect to Boffin (#{@api_base}). #{connection_message}"
205
+
206
+ when RestClient::ServerBrokeConnection
207
+ message = "The connection to the server (#{@api_base}) broke before the " \
208
+ "request completed. #{connection_message}"
209
+
210
+ when RestClient::SSLCertificateNotVerified
211
+ message = "Could not verify Boffin's SSL certificate. " \
212
+ "Please make sure that your network is not intercepting certificates. " \
213
+ "(Try going to https://api.boffin.com/v1 in your browser.) " \
214
+ "If this problem persists, let us know at support@boffin.io."
215
+
216
+ when SocketError
217
+ message = "Unexpected error communicating when trying to connect to Boffin. " \
218
+ "You may be seeing this message because your DNS is not working. " \
219
+ "To check, try running 'host boffin.io' from the command line."
220
+
221
+ else
222
+ message = "Unexpected error communicating with Boffin. " \
223
+ "If this problem persists, let us know at support@boffin.io."
224
+
225
+ end
226
+
227
+ raise BoffinIOError.new(message + "\n\n(Network error: #{e.message})")
228
+ end
229
+ end
@@ -0,0 +1,149 @@
1
+ require './test/test_helper'
2
+
3
+ class BoffinIOCustomerTest < Minitest::Test
4
+ def test_exists
5
+ assert BoffinIO::Customer
6
+ end
7
+
8
+ def test_it_gives_back_a_single_customer
9
+ VCR.use_cassette('one_customer') do
10
+ customer = BoffinIO::Customer.retrieve("1398")
11
+ assert_equal BoffinIO::Customer, customer.class
12
+
13
+ # Check that the fields are accessible by our model
14
+ assert_equal "1398", customer.ref_id
15
+ assert_equal "Tim Williams", customer.description
16
+ end
17
+ end
18
+
19
+ def test_it_gives_back_all_customers
20
+ VCR.use_cassette('all_customers') do
21
+ result = BoffinIO::Customer.all
22
+
23
+ # Make sure we got all the cars
24
+ assert_equal 11, result.count
25
+
26
+ # Make sure that the JSON was parsed
27
+ assert result.kind_of?(BoffinIO::ListObject)
28
+ customers = result.data
29
+ assert customers.first.kind_of?(BoffinIO::Customer)
30
+ end
31
+ end
32
+
33
+ def test_it_creates_one_customer
34
+ VCR.use_cassette('create_customer') do
35
+ customer = BoffinIO::Customer.create(
36
+ ref_id: "test1234",
37
+ description: "Tim Williams",
38
+ email: "tim@example.com"
39
+ )
40
+
41
+ # Make sure we got all the cars
42
+ assert_equal "test1234", customer.ref_id
43
+ assert_equal "Tim Williams", customer.description
44
+ assert_equal "tim@example.com", customer.email
45
+ end
46
+ end
47
+
48
+ def test_it_updates_a_named_customer
49
+ VCR.use_cassette('one_customer') do
50
+ customer = BoffinIO::Customer.retrieve("1398")
51
+ VCR.use_cassette('update_customer', :record => :new_episodes) do
52
+ customer.email="timwilliams@example.com"
53
+ result = customer.save
54
+ assert_equal "timwilliams@example.com",result.email
55
+ end
56
+ end
57
+ end
58
+
59
+ def test_it_creates_one_subscription
60
+ VCR.use_cassette('one_customer') do
61
+ customer = BoffinIO::Customer.retrieve("1398")
62
+ VCR.use_cassette('create_subscription') do
63
+ metadata = {:provider => "heroku"}
64
+ subscription = customer.create_subscription(
65
+ plan: "foo",
66
+ metadata: metadata,
67
+ start: Time.new(2014,1,1)
68
+ )
69
+ assert_equal BoffinIO::Subscription, subscription.class
70
+ plan = subscription.plan
71
+ assert_equal BoffinIO::Plan, plan.class
72
+ assert_equal "foo", plan.slug
73
+ assert_equal "heroku",subscription.metadata[:provider]
74
+ end
75
+ end
76
+ end
77
+
78
+ def test_it_creates_one_subscription
79
+ VCR.use_cassette('one_customer') do
80
+ customer = BoffinIO::Customer.retrieve("1398")
81
+ VCR.use_cassette('create_subscription') do
82
+ metadata = {:provider => "heroku"}
83
+ subscription = customer.create_subscription(
84
+ plan: "foo",
85
+ metadata: metadata,
86
+ start: Time.new(2014,1,1)
87
+ )
88
+ assert_equal BoffinIO::Subscription, subscription.class
89
+ plan = subscription.plan
90
+ assert_equal BoffinIO::Plan, plan.class
91
+ assert_equal "foo", plan.slug
92
+ assert_equal "heroku",subscription.metadata[:provider]
93
+ end
94
+ end
95
+ end
96
+
97
+ def test_it_deletes_subscriptions
98
+ VCR.use_cassette('one_customer') do
99
+ customer = BoffinIO::Customer.retrieve("1398")
100
+ VCR.use_cassette('cancel_subscription') do
101
+ subscription = customer.cancel_subscription
102
+ assert_equal BoffinIO::Subscription, subscription.class
103
+ refute_nil subscription.canceled_at
104
+ end
105
+ end
106
+ end
107
+
108
+ def test_it_updates_subscriptions
109
+ VCR.use_cassette('one_customer') do
110
+ customer = BoffinIO::Customer.retrieve("1398")
111
+ VCR.use_cassette('update_subscription') do
112
+ metadata = {:provider => "heroku"}
113
+ subscription = customer.update_subscription(:plan => "test", :metadata => metadata)
114
+ assert_equal BoffinIO::Subscription, subscription.class
115
+ plan = subscription.plan
116
+ assert_equal BoffinIO::Plan, plan.class
117
+ assert_equal "test", plan.slug
118
+ assert_equal "heroku",subscription.metadata[:provider]
119
+ end
120
+ end
121
+ end
122
+
123
+ def test_it_lists_subscriptions
124
+ VCR.use_cassette('one_customer') do
125
+ customer = BoffinIO::Customer.retrieve("1398")
126
+ VCR.use_cassette('customer_subscriptions', :record => :new_episodes) do
127
+ subscriptions = customer.subscriptions.all
128
+ sub1 = subscriptions.first
129
+ assert_equal BoffinIO::Subscription, sub1.class
130
+ end
131
+ end
132
+ end
133
+
134
+ def test_it_updates_a_named_subscription
135
+ VCR.use_cassette('one_customer') do
136
+ customer = BoffinIO::Customer.retrieve("1398")
137
+ VCR.use_cassette('customer_subscriptions', :record => :new_episodes) do
138
+ subscriptions = customer.subscriptions.all
139
+ sub1 = subscriptions.first
140
+ sub1.metadata = {:country => "gb"}
141
+ VCR.use_cassette('update_named_subscription', :record => :new_episodes) do
142
+ result = sub1.save
143
+ assert_equal "gb",result.metadata[:country]
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ end
@@ -0,0 +1,62 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: http://api.boffin-dev.io:3000/v1/customers
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - "*/*; q=0.5, application/xml"
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Boffin/v1 RubyBindings/0.0.1
16
+ Authorization:
17
+ - Token token=141d246d5e0774eaab3482259516dae9
18
+ Content-Type:
19
+ - application/x-www-form-urlencoded
20
+ Stripe-Version:
21
+ - v1
22
+ X-Stripe-Client-User-Agent:
23
+ - '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
24
+ tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
25
+ x86_64 x86_64 GNU/Linux"}'
26
+ response:
27
+ status:
28
+ code: 200
29
+ message: 'OK '
30
+ headers:
31
+ X-Frame-Options:
32
+ - SAMEORIGIN
33
+ X-Xss-Protection:
34
+ - 1; mode=block
35
+ X-Content-Type-Options:
36
+ - nosniff
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Etag:
40
+ - '"a81d3321ce01aa68b3fbb332e3622605"'
41
+ Cache-Control:
42
+ - max-age=0, private, must-revalidate
43
+ X-Request-Id:
44
+ - 49c89e41-ecd2-4bb6-92f5-aff6f530d2d1
45
+ X-Runtime:
46
+ - '0.298277'
47
+ Server:
48
+ - WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
49
+ Date:
50
+ - Sun, 26 Oct 2014 12:39:08 GMT
51
+ Content-Length:
52
+ - '2069'
53
+ Connection:
54
+ - Keep-Alive
55
+ Set-Cookie:
56
+ - request_method=GET; path=/
57
+ body:
58
+ encoding: UTF-8
59
+ string: '{"object":"list","url":"/v1/customers","count":11,"data":[{"object":"customer","id":"900","ref_id":"900","description":null,"email":"tim@teachmatic.com","subscriptions":{"object":"list","url":"/v1/customers/900/subscriptions","data":[]}},{"object":"customer","id":"901","ref_id":"901","description":null,"email":"user_901@example.com","subscriptions":{"object":"list","url":"/v1/customers/901/subscriptions","data":[]}},{"object":"customer","id":"902","ref_id":"902","description":null,"email":"user_902@example.com","subscriptions":{"object":"list","url":"/v1/customers/902/subscriptions","data":[]}},{"object":"customer","id":"903","ref_id":"903","description":null,"email":"app3830@kensa.heroku.com","subscriptions":{"object":"list","url":"/v1/customers/903/subscriptions","data":[]}},{"object":"customer","id":"904","ref_id":"904","description":null,"email":"app16413261@heroku.com","subscriptions":{"object":"list","url":"/v1/customers/904/subscriptions","data":[]}},{"object":"customer","id":"905","ref_id":"905","description":null,"email":"user_905@example.com","subscriptions":{"object":"list","url":"/v1/customers/905/subscriptions","data":[]}},{"object":"customer","id":"906","ref_id":"906","description":null,"email":"user_906@example.com","subscriptions":{"object":"list","url":"/v1/customers/906/subscriptions","data":[]}},{"object":"customer","id":"907","ref_id":"907","description":null,"email":"app9219248@heroku.com","subscriptions":{"object":"list","url":"/v1/customers/907/subscriptions","data":[]}},{"object":"customer","id":"908","ref_id":"908","description":null,"email":"gojee@herokumanager.com","subscriptions":{"object":"list","url":"/v1/customers/908/subscriptions","data":[]}},{"object":"customer","id":"909","ref_id":"909","description":null,"email":"user_909@example.com","subscriptions":{"object":"list","url":"/v1/customers/909/subscriptions","data":[]}},{"object":"customer","id":"910","ref_id":"910","description":null,"email":"user_910@example.com","subscriptions":{"object":"list","url":"/v1/customers/910/subscriptions","data":[]}}]}'
60
+ http_version:
61
+ recorded_at: Sun, 26 Oct 2014 12:39:08 GMT
62
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,62 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: delete
5
+ uri: http://api.boffin-dev.io:3000/v1/customers/1398/subscriptions
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - "*/*; q=0.5, application/xml"
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Boffin/v1 RubyBindings/0.0.1
16
+ Authorization:
17
+ - Token token=141d246d5e0774eaab3482259516dae9
18
+ Content-Type:
19
+ - application/x-www-form-urlencoded
20
+ Stripe-Version:
21
+ - v1
22
+ X-Stripe-Client-User-Agent:
23
+ - '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
24
+ tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
25
+ x86_64 x86_64 GNU/Linux"}'
26
+ response:
27
+ status:
28
+ code: 200
29
+ message: 'OK '
30
+ headers:
31
+ X-Frame-Options:
32
+ - SAMEORIGIN
33
+ X-Xss-Protection:
34
+ - 1; mode=block
35
+ X-Content-Type-Options:
36
+ - nosniff
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Etag:
40
+ - '"5b689bd2f50df26c7e07c128bf983151"'
41
+ Cache-Control:
42
+ - max-age=0, private, must-revalidate
43
+ X-Request-Id:
44
+ - 5a68351b-454f-4eb1-9431-4a4550cad117
45
+ X-Runtime:
46
+ - '0.094349'
47
+ Server:
48
+ - WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
49
+ Date:
50
+ - Fri, 24 Oct 2014 18:08:56 GMT
51
+ Content-Length:
52
+ - '229'
53
+ Connection:
54
+ - Keep-Alive
55
+ Set-Cookie:
56
+ - request_method=DELETE; path=/
57
+ body:
58
+ encoding: UTF-8
59
+ string: '{"object":"subscription","start":"2014-01-01T00:00:00.000Z","canceled_at":"2014-10-24T18:08:56.000Z","metadata":{"provider":"heroku"},"plan":{"object":"plan","slug":"foo","amount":0,"currency":"usd"},"customer":{"ref_id":"1398"}}'
60
+ http_version:
61
+ recorded_at: Fri, 24 Oct 2014 18:08:56 GMT
62
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,66 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://api.boffin-dev.io:3000/v1/customers
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ref_id=test1234&description=Tim%20Williams&email=tim%40example.com
9
+ headers:
10
+ Accept:
11
+ - "*/*; q=0.5, application/xml"
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Boffin/v1 RubyBindings/0.0.1
16
+ Authorization:
17
+ - Token token=141d246d5e0774eaab3482259516dae9
18
+ Content-Type:
19
+ - application/x-www-form-urlencoded
20
+ Stripe-Version:
21
+ - v1
22
+ X-Stripe-Client-User-Agent:
23
+ - '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
24
+ tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
25
+ x86_64 x86_64 GNU/Linux"}'
26
+ Content-Length:
27
+ - '66'
28
+ response:
29
+ status:
30
+ code: 201
31
+ message: 'Created '
32
+ headers:
33
+ X-Frame-Options:
34
+ - SAMEORIGIN
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ X-Content-Type-Options:
38
+ - nosniff
39
+ Location:
40
+ - http://api.boffin-dev.io:3000/v1/customers/5679
41
+ Content-Type:
42
+ - application/json; charset=utf-8
43
+ Etag:
44
+ - '"6244553f4534538268f711c45950f29e"'
45
+ Cache-Control:
46
+ - max-age=0, private, must-revalidate
47
+ X-Request-Id:
48
+ - 3d93498e-13bf-4b79-ac67-4f43402896d2
49
+ X-Runtime:
50
+ - '0.021902'
51
+ Server:
52
+ - WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
53
+ Date:
54
+ - Fri, 24 Oct 2014 15:51:26 GMT
55
+ Content-Length:
56
+ - '181'
57
+ Connection:
58
+ - Keep-Alive
59
+ Set-Cookie:
60
+ - request_method=POST; path=/
61
+ body:
62
+ encoding: UTF-8
63
+ string: '{"id":5679,"description":"Tim Williams","email":"tim@example.com","ref_id":"test1234","created_at":"2014-10-24T15:51:26.002Z","updated_at":"2014-10-24T15:51:26.002Z","product_id":4}'
64
+ http_version:
65
+ recorded_at: Fri, 24 Oct 2014 15:51:26 GMT
66
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,66 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: http://api.boffin-dev.io:3000/v1/customers/1398/subscriptions
6
+ body:
7
+ encoding: US-ASCII
8
+ string: plan=foo&metadata[provider]=heroku&start=2014-01-01%2000%3A00%3A00%20%2B0000
9
+ headers:
10
+ Accept:
11
+ - "*/*; q=0.5, application/xml"
12
+ Accept-Encoding:
13
+ - gzip, deflate
14
+ User-Agent:
15
+ - Boffin/v1 RubyBindings/0.0.1
16
+ Authorization:
17
+ - Token token=141d246d5e0774eaab3482259516dae9
18
+ Content-Type:
19
+ - application/x-www-form-urlencoded
20
+ Stripe-Version:
21
+ - v1
22
+ X-Stripe-Client-User-Agent:
23
+ - '{"bindings_version":"0.0.1","lang":"ruby","lang_version":"2.0.0 p481 (2014-05-08)","platform":"x86_64-linux","publisher":"boffinio","uname":"Linux
24
+ tim-laptop 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
25
+ x86_64 x86_64 GNU/Linux"}'
26
+ Content-Length:
27
+ - '76'
28
+ response:
29
+ status:
30
+ code: 201
31
+ message: 'Created '
32
+ headers:
33
+ X-Frame-Options:
34
+ - SAMEORIGIN
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ X-Content-Type-Options:
38
+ - nosniff
39
+ Location:
40
+ - http://api.boffin-dev.io:3000/v1/customers/1398/subscriptions/7066
41
+ Content-Type:
42
+ - application/json; charset=utf-8
43
+ Etag:
44
+ - '"4272e7f380bbdbaff2ebc14a016f06f0"'
45
+ Cache-Control:
46
+ - max-age=0, private, must-revalidate
47
+ X-Request-Id:
48
+ - 19030148-df93-442b-b672-13e215ce8bd3
49
+ X-Runtime:
50
+ - '0.363081'
51
+ Server:
52
+ - WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)
53
+ Date:
54
+ - Fri, 24 Oct 2014 18:08:55 GMT
55
+ Content-Length:
56
+ - '207'
57
+ Connection:
58
+ - Keep-Alive
59
+ Set-Cookie:
60
+ - request_method=POST; path=/
61
+ body:
62
+ encoding: UTF-8
63
+ string: '{"object":"subscription","start":"2014-01-01T00:00:00.000Z","canceled_at":null,"metadata":{"provider":"heroku"},"plan":{"object":"plan","slug":"foo","amount":0,"currency":"usd"},"customer":{"ref_id":"1398"}}'
64
+ http_version:
65
+ recorded_at: Fri, 24 Oct 2014 18:08:55 GMT
66
+ recorded_with: VCR 2.9.3