zuora-ruby 0.3.0 → 0.4.0

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.
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.