boffinio 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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