zuora-ruby 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59ac3797046acdb3f30dbd498d3f5368024d6c8f
4
- data.tar.gz: c747cfe5f6c0e2dfeeb46da7a0279761e201ecba
3
+ metadata.gz: 7f2609823dc2d907d854ef7c950b7a683f5795b2
4
+ data.tar.gz: 06c402c7774279668eb3891085eb3d9c7c72bf87
5
5
  SHA512:
6
- metadata.gz: a2e9865623c907ad008b942f39fb831979f6fe65f8b7d159f4176ae074ea41867e38883d77e891922e1e3e70da7685a3ad617dbe9cbf6aedfefceba8513f2b56
7
- data.tar.gz: ded935331529eecc8ce365652be19e7fadb252c949e919d7e0bca07af74211d7f1cf5cc4264c3dd2d721bfdefcdb1893007ba3b91e25e678298047a70d1797a7
6
+ metadata.gz: 075799410c0f4b511ade42eded914a5d5287592297b77558f0ccd5f1b288893a31d9c160fb3a9952d34536228a656f7ab9c92f985e2e578bd8b945a6ba4e40b0
7
+ data.tar.gz: cd675321a91dfae484fc72447cca0378a74ab6b129b65c6d8e7c329d41cd688a70706d1624cc5b7951206c5417f17ba68f092c81c6b4435aa35f3a9ade545b19
@@ -53,4 +53,8 @@ Metrics/ClassLength:
53
53
  Enabled: false
54
54
 
55
55
  Style/EachWithObject:
56
- Enabled: false
56
+ Enabled: false
57
+
58
+ Metrics/MethodLength:
59
+ Max: 15
60
+ Enabled: true
data/README.md CHANGED
@@ -8,9 +8,7 @@
8
8
  * HTTP client to Zuora SOAP API
9
9
  * Authentication and session storage
10
10
  * SOAP XML request constructors from Ruby data
11
- * Support for custom Zuora fields
12
- * Light validation of SOAP call parameters
13
- * Light wrapper over response, providing a Ruby object interface over Zuora's returned XML response
11
+ * Light validation of top-level forms; field-level validation delegated to Zuora's responses.
14
12
 
15
13
  ## Usage
16
14
 
@@ -19,28 +17,11 @@
19
17
 
20
18
  Create a client
21
19
  ```ruby
22
- client = Zuora::Client.new(<username>, <password>)
20
+ client = Zuora::Client.new(<username>, <password>)
23
21
  ```
24
22
 
25
- Execute a SOAP request. All Zuora calls are supported: `.create()`, `.update()`, `.amend()`, `.generate()`, `.delete()`, `subscribe()`.
26
23
 
27
- ### Quick Reference
28
- See examples below and integration specs for full interfaces.
29
- ```ruby
30
- client.call! :query, "SELECT Id FROM Account"
31
- client.call! :create, type: :Account, objects: [{}, {}]
32
- client.call! :update, type: :Invoice, objects: [{ id: '123' }, { id: '123' }]
33
- client.call! :delete, ids: ['123', '456']
34
- client.call! :amend, amendments: {}, amend_options: {}, :preview_options: {}
35
- client.call! :subscribe,
36
- account: {}
37
- payment_method: {}
38
- bill_to_contact: {}
39
- sold_to_contact: {}
40
- subscribe_options: {}
41
- subscription: {}
42
- rate_plan: {}
43
- ```
24
+ Execute a SOAP request. Currently only `:create` and `:subscribe` are supported
44
25
 
45
26
  #### Create Example
46
27
 
@@ -51,8 +32,11 @@ response = client.call! :create,
51
32
  invoice_date: '2016-03-01',
52
33
  target_date: '2016-03-01'
53
34
  }]
35
+
54
36
  ```
37
+
55
38
  This would generate SOAP XML, make, and return an authenticated SOAP request.
39
+
56
40
  ```xml
57
41
  <?xml version="1.0"?>
58
42
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:api="http://api.zuora.com/" xmlns:obj="http://object.api.zuora.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
@@ -72,10 +56,12 @@ This would generate SOAP XML, make, and return an authenticated SOAP request.
72
56
  </soapenv:Envelope>
73
57
  ```
74
58
 
75
- A response object is returned. You can access the raw response:
59
+ A response object is returned, having status and body
60
+
76
61
  ```ruby
77
- response.raw.body
62
+ response.body
78
63
  ```
64
+
79
65
  ```xml
80
66
  <?xml version="1.0" encoding="UTF-8"?>
81
67
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
@@ -90,15 +76,18 @@ response.raw.body
90
76
  </soapenv:Envelope>
91
77
  ```
92
78
 
93
- The `.to_h` method provides an interface that can be navigated as a hash or object.
79
+ This XML body, in turn, could be parsed with Nokogiri for further work.
94
80
 
95
81
  ```ruby
96
- response.to_h.envelope.body.create_response.result
97
- => { id: '2c92c0f9526913e301526a7863df4647', success: true }
82
+ response_xml = Nokogiri::XML(response.body)
83
+ success = response_xml.xpath(
84
+ '/soapenv/Envelope/soapenv:Body/api:createResponse/api:result/api:Success'
85
+ ).text == 'true'
98
86
  ```
99
87
 
100
- #### .subscribe() example
101
- Subscribe is a very large call that involves a lot of data. See the integration spec `spec/zuora/integration/subscription_spec.rb` for full example
88
+
89
+ #### Subscribe Example
90
+ Subscribe is a very large call that involves a lot of data. See the integration spec `spec/zuora/integration/subscription_spec` for full example
102
91
 
103
92
  ```ruby
104
93
  response = client.call! :subscribe,
@@ -126,14 +115,16 @@ response = client.call! :subscribe,
126
115
  - Adds integration specs for `Subscribe` `create!` and `update!` and `Account` `create!` and `update!`
127
116
 
128
117
  * **[0.3.0 2016-1-28]** Focus on SOAP API, simpify client library feature set
129
- - Redesign API, eliminate previous Model constructs
130
- - Implement SOAP API Client, as it provides fuller functionality than REST
118
+ - Implement SOAP API Client; it provides fuller functionality than REST
131
119
  - Focus on constructing + composing hash-like Ruby objects into XML SOAP requests
132
- - Add support for custom fields
133
- - Remove object-level validations; relies on Zuora's own error responses. Light validations on call constructors.
134
- - Provide object/hash lookup capabilities on Zuora Responses
120
+ - No object-level validations; relies on Zuora's own responses
135
121
  - See integration specs for full interface
136
122
 
123
+ * **[0.4.0 2016-02-10]** Improves interface and feedback loop between developer and Zuora servers.
124
+ - Allow flexible submission of parameters to the API. Let Zuora's API handle validation instead of performing in the client.
125
+ - Adds integration specs to cover base functionality
126
+ - Adds exception raising to match servier-side exceptions such as missing required fields, invalid data, etc.
127
+
137
128
  # Commit rights
138
129
  Anyone who has a patch accepted may request commit rights. Please do so inside the pull request post-merge.
139
130
 
@@ -24,6 +24,7 @@ module Zuora
24
24
  end
25
25
 
26
26
  require_relative 'zuora/version'
27
+ require_relative 'zuora/errors'
27
28
  require_relative 'zuora/utils/envelope'
28
29
  require_relative 'zuora/client'
29
30
  require_relative 'zuora/object'
@@ -3,12 +3,6 @@ require 'faraday_middleware'
3
3
  require 'nokogiri'
4
4
 
5
5
  module Zuora
6
- # Unable to connect. Check username / password
7
- SoapConnectionError = Class.new StandardError
8
-
9
- # Non-success response
10
- SoapErrorResponse = Class.new StandardError
11
-
12
6
  class Client
13
7
  attr_accessor :session_token
14
8
 
@@ -40,7 +34,7 @@ module Zuora
40
34
 
41
35
  handle_auth_response auth_response
42
36
  rescue Object => e
43
- raise SoapConnectionError, e
37
+ raise Zuora::Errors::SoapConnectionError, e
44
38
  end
45
39
 
46
40
  # Fire a request
@@ -55,7 +49,11 @@ module Zuora
55
49
  request.body = body.to_xml
56
50
  end
57
51
 
58
- Zuora::Response.new(raw_response)
52
+ response = Zuora::Response.new(raw_response)
53
+
54
+ response.handle_errors(response.to_h)
55
+
56
+ response
59
57
  end
60
58
 
61
59
  # The primary interface via which users should make SOAP requests.
@@ -73,8 +71,8 @@ module Zuora
73
71
  private
74
72
 
75
73
  # Generate envelope for request
76
- # @param [Symbol] call name - one of the supported calls (see #call)
77
- # @param [Callable] builder_modifier - function taking a builder
74
+ # @param [Symbol] call_name - one of the supported calls (see #call)
75
+ # @param [Callable] xml_builder_modifier - function taking a builder
78
76
  # @return [Nokogiri::XML::Builder]
79
77
  def envelope_for(call_name, xml_builder_modifier)
80
78
  if call_name == :login
@@ -89,13 +87,13 @@ module Zuora
89
87
  # Handle auth response, setting session
90
88
  # @params [Faraday::Response]
91
89
  # @return [Faraday::Response]
92
- # @throw [SoapErrorResponse]
90
+ # @throw [Zuora::Errors::InvalidCredentials]
93
91
  def handle_auth_response(response)
94
92
  if response.raw.status == 200
95
93
  @session_token = extract_session_token response
96
94
  else
97
95
  message = 'Unable to connect with provided credentials'
98
- fail SoapErrorResponse, message
96
+ fail Zuora::Errors::InvalidCredentials, message
99
97
  end
100
98
  response
101
99
  end
@@ -104,9 +102,7 @@ module Zuora
104
102
  # for use in subsequent requests
105
103
  # @param [Faraday::Response] response - response to auth request
106
104
  def extract_session_token(response)
107
- Nokogiri::XML(response.raw.body).xpath(
108
- SESSION_TOKEN_XPATH, Zuora::NAMESPACES
109
- ).text
105
+ response.to_h.envelope.body.login_response.result.session
110
106
  end
111
107
 
112
108
  # Initializes a connection using api_url
@@ -0,0 +1,18 @@
1
+ module Zuora
2
+ module Errors
3
+ class InvalidValue < StandardError
4
+ attr_reader :response
5
+
6
+ def initialize(msg = nil, response = nil)
7
+ @response = response
8
+ super(msg)
9
+ end
10
+ end
11
+
12
+ class InvalidCredentials < StandardError
13
+ end
14
+
15
+ class SoapConnectionError < StandardError
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,7 @@ require 'active_support/core_ext/hash/conversions'
2
2
 
3
3
  module Zuora
4
4
  class Response
5
+ ERROR_STRINGS = ['Missing required value', 'are required fields'].freeze
5
6
  attr_reader :raw
6
7
 
7
8
  # @param [Faraday::Response]
@@ -18,8 +19,32 @@ module Zuora
18
19
  Hashie::Mash.new(symbolize_keys_deep(hash))
19
20
  end
20
21
 
22
+ # @param [Hash] hash
23
+ def handle_errors(hash)
24
+ errors = []
25
+
26
+ hash.each do |key, value|
27
+ if value.is_a?(Hash)
28
+ handle_errors(value)
29
+ elsif value.is_a?(Array)
30
+ value.each { |v| handle_errors(v) }
31
+ elsif error?(key, value)
32
+ errors << value
33
+ end
34
+ end
35
+
36
+ raise_errors(errors) if errors.present?
37
+ end
38
+
21
39
  private
22
40
 
41
+ # @param [String|Symbol] key
42
+ # @param [String] value
43
+ def error?(key, value)
44
+ ERROR_STRINGS.any? { |str| value.to_s.match(str) } ||
45
+ key.to_s.casecmp('message').zero?
46
+ end
47
+
23
48
  # Given a key, convert to symbol, removing XML namespace, if any.
24
49
  # @param [String] key - a key, either "abc" or "abc:def"
25
50
  # @return [Symbol]
@@ -46,5 +71,12 @@ module Zuora
46
71
  [symbolize_key(key), value]
47
72
  end]
48
73
  end
74
+
75
+ # @param [Array] errors
76
+ def raise_errors(errors)
77
+ error_string = errors.join(',')
78
+ error = Zuora::Errors::InvalidValue.new(error_string, to_h)
79
+ fail error
80
+ end
49
81
  end
50
82
  end
@@ -65,7 +65,6 @@ module Zuora
65
65
  # @return [Symbol] - e.g. :SomeKeyName or :SomeKeyName__c
66
66
  def self.to_zuora_key(key)
67
67
  custom_field_matcher = Regexp.new CUSTOM_FIELD_STRING
68
-
69
68
  matches = custom_field_matcher.match(key.to_s)
70
69
  suffix = ''
71
70
 
@@ -1,3 +1,3 @@
1
1
  module Zuora
2
- VERSION = '0.3.0'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  end
@@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'rspec'
47
47
  spec.add_development_dependency 'rspec-its'
48
48
  spec.add_development_dependency 'rspec_junit_formatter', '0.2.2'
49
- spec.add_development_dependency 'rubocop'
49
+ spec.add_development_dependency 'rubocop', '0.36.0'
50
50
  spec.add_development_dependency 'webmock'
51
51
  spec.add_development_dependency 'vcr'
52
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zuora-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Contactually Engineering
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-02-02 00:00:00.000000000 Z
11
+ date: 2016-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -224,16 +224,16 @@ dependencies:
224
224
  name: rubocop
225
225
  requirement: !ruby/object:Gem::Requirement
226
226
  requirements:
227
- - - ">="
227
+ - - '='
228
228
  - !ruby/object:Gem::Version
229
- version: '0'
229
+ version: 0.36.0
230
230
  type: :development
231
231
  prerelease: false
232
232
  version_requirements: !ruby/object:Gem::Requirement
233
233
  requirements:
234
- - - ">="
234
+ - - '='
235
235
  - !ruby/object:Gem::Version
236
- version: '0'
236
+ version: 0.36.0
237
237
  - !ruby/object:Gem::Dependency
238
238
  name: webmock
239
239
  requirement: !ruby/object:Gem::Requirement
@@ -294,6 +294,7 @@ files:
294
294
  - lib/zuora/calls/upsert.rb
295
295
  - lib/zuora/client.rb
296
296
  - lib/zuora/dispatcher.rb
297
+ - lib/zuora/errors.rb
297
298
  - lib/zuora/object.rb
298
299
  - lib/zuora/response.rb
299
300
  - lib/zuora/utils/envelope.rb
@@ -320,7 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
320
321
  version: '0'
321
322
  requirements: []
322
323
  rubyforge_project:
323
- rubygems_version: 2.4.5.1
324
+ rubygems_version: 2.4.8
324
325
  signing_key:
325
326
  specification_version: 4
326
327
  summary: A Ruby wrapper for Zuora API.