active_zuora 1.3.0 → 2.6.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 +7 -0
- data/.gitignore +5 -0
- data/.octopolo.yml +4 -0
- data/.soyuz.yml +13 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.markdown +41 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.md +191 -0
- data/Rakefile +9 -53
- data/TODO.md +2 -0
- data/active_zuora.gemspec +25 -59
- data/lib/active_zuora.rb +44 -12
- data/lib/active_zuora/amend.rb +43 -0
- data/lib/active_zuora/base.rb +84 -0
- data/lib/active_zuora/batch_subscribe.rb +53 -0
- data/lib/active_zuora/belongs_to_associations.rb +56 -0
- data/lib/active_zuora/billing_preview.rb +49 -0
- data/lib/active_zuora/collection_proxy.rb +38 -0
- data/lib/active_zuora/connection.rb +47 -0
- data/lib/active_zuora/fields.rb +129 -0
- data/lib/active_zuora/fields/array_field_decorator.rb +28 -0
- data/lib/active_zuora/fields/boolean_field.rb +12 -0
- data/lib/active_zuora/fields/date_field.rb +18 -0
- data/lib/active_zuora/fields/date_time_field.rb +19 -0
- data/lib/active_zuora/fields/decimal_field.rb +12 -0
- data/lib/active_zuora/fields/field.rb +76 -0
- data/lib/active_zuora/fields/integer_field.rb +11 -0
- data/lib/active_zuora/fields/object_field.rb +31 -0
- data/lib/active_zuora/fields/string_field.rb +11 -0
- data/lib/active_zuora/generate.rb +43 -0
- data/lib/active_zuora/generator.rb +244 -0
- data/lib/active_zuora/has_many_associations.rb +37 -0
- data/lib/active_zuora/has_many_proxy.rb +50 -0
- data/lib/active_zuora/lazy_attr.rb +52 -0
- data/lib/active_zuora/persistence.rb +172 -0
- data/lib/active_zuora/relation.rb +260 -0
- data/lib/active_zuora/scoping.rb +50 -0
- data/lib/active_zuora/subscribe.rb +42 -0
- data/lib/active_zuora/version.rb +3 -0
- data/lib/active_zuora/z_object.rb +21 -0
- data/spec/account_integration_spec.rb +41 -0
- data/spec/base_spec.rb +39 -0
- data/spec/belongs_to_associations_spec.rb +35 -0
- data/spec/collection_proxy_spec.rb +28 -0
- data/spec/connection_spec.rb +66 -0
- data/spec/fields/date_field_spec.rb +35 -0
- data/spec/has_many_integration_spec.rb +53 -0
- data/spec/lazy_attr_spec.rb +22 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/subscribe_integration_spec.rb +344 -0
- data/spec/zobject_integration_spec.rb +104 -0
- data/wsdl/zuora.wsdl +1548 -0
- metadata +141 -53
- data/LICENSE +0 -202
- data/README.rdoc +0 -15
- data/VERSION +0 -1
- data/custom_fields.yml +0 -17
- data/lib/zuora/ZUORA.rb +0 -1398
- data/lib/zuora/ZUORADriver.rb +0 -128
- data/lib/zuora/ZUORAMappingRegistry.rb +0 -1488
- data/lib/zuora/ZuoraServiceClient.rb +0 -124
- data/lib/zuora/account.rb +0 -4
- data/lib/zuora/api.rb +0 -18
- data/lib/zuora/contact.rb +0 -4
- data/lib/zuora/rate_plan.rb +0 -4
- data/lib/zuora/rate_plan_data.rb +0 -4
- data/lib/zuora/subscribe_options.rb +0 -4
- data/lib/zuora/subscribe_request.rb +0 -4
- data/lib/zuora/subscribe_with_existing_account_request.rb +0 -4
- data/lib/zuora/subscription.rb +0 -4
- data/lib/zuora/subscription_data.rb +0 -4
- data/lib/zuora/zobject.rb +0 -52
- data/lib/zuora_client.rb +0 -181
- data/lib/zuora_interface.rb +0 -199
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
module Scoping
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Delegate to :scoped
|
10
|
+
delegate :find, :all, :find_each, :to => :scoped
|
11
|
+
delegate :select, :where, :and, :or, :order, :to => :scoped
|
12
|
+
delegate :first, :last, :each, :map, :any?, :empty?, :blank?, :present?, :size, :count, :to => :scoped
|
13
|
+
|
14
|
+
# Keep track of a current scope.
|
15
|
+
attr_accessor :current_scope
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
def scoped
|
23
|
+
current_scope || relation
|
24
|
+
end
|
25
|
+
|
26
|
+
def unscoped
|
27
|
+
block_given? ? relation.scoped { yield } : relation
|
28
|
+
end
|
29
|
+
|
30
|
+
def exclude_from_queries(*field_names)
|
31
|
+
(@excluded_from_queries ||= []).concat field_names.map(&:to_sym)
|
32
|
+
end
|
33
|
+
|
34
|
+
def relation
|
35
|
+
query_field_names = field_names - (@excluded_from_queries ||= [])
|
36
|
+
Relation.new(self, query_field_names)
|
37
|
+
end
|
38
|
+
|
39
|
+
def scope(name, body)
|
40
|
+
# Body can be a Relation or a lambda that returns a relation.
|
41
|
+
define_singleton_method(name) do |*args|
|
42
|
+
body.respond_to?(:call) ? body.call(*args) : scoped.merge(body)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
module Subscribe
|
3
|
+
|
4
|
+
# This is meant to be included onto a SubscribeRequest class.
|
5
|
+
# Returns true/false on success.
|
6
|
+
# Result hash is stored in #result.
|
7
|
+
# If success, the subscription id and account id will be set in those objects.
|
8
|
+
# If failure, errors will be present on object.
|
9
|
+
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
include Base
|
14
|
+
attr_accessor :result
|
15
|
+
end
|
16
|
+
|
17
|
+
def subscribe
|
18
|
+
self.result = self.class.connection.request(:subscribe) do |soap|
|
19
|
+
soap.body do |xml|
|
20
|
+
build_xml(xml, soap,
|
21
|
+
:namespace => soap.namespace,
|
22
|
+
:element_name => :subscribes,
|
23
|
+
:force_type => true)
|
24
|
+
end
|
25
|
+
end[:subscribe_response][:result]
|
26
|
+
if result[:success]
|
27
|
+
account.id = result[:account_id]
|
28
|
+
subscription_data.subscription.id = result[:subscription_id]
|
29
|
+
clear_changed_attributes
|
30
|
+
true
|
31
|
+
else
|
32
|
+
add_zuora_errors(result[:errors])
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def subscribe!
|
38
|
+
raise "Could not subscribe: #{errors.full_messages.join ', '}" unless subscribe
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActiveZuora
|
2
|
+
module ZObject
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include Base
|
8
|
+
include Scoping
|
9
|
+
include HasManyAssociations
|
10
|
+
include Persistence
|
11
|
+
field :id, :string
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(another_zobject)
|
15
|
+
another_zobject.is_a?(ZObject) &&
|
16
|
+
zuora_object_name == another_zobject.zuora_object_name &&
|
17
|
+
id == another_zobject.id
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Create Account' do
|
4
|
+
|
5
|
+
integration_test do
|
6
|
+
|
7
|
+
let(:account) do
|
8
|
+
Z::Account.new name: 'Joe Customer',
|
9
|
+
currency: Tenant.currency,
|
10
|
+
bill_cycle_day: '1'
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:each) do
|
14
|
+
account.delete unless account.new_record?
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'can create an account' do
|
18
|
+
expect(account).to be_a_new_record
|
19
|
+
expect(account).to_not be_valid
|
20
|
+
expect(account.id).to_not be_present
|
21
|
+
expect(account.errors.full_messages).to eq ["Status can't be blank"]
|
22
|
+
|
23
|
+
now 'update account to be valid' do
|
24
|
+
account.status = 'Draft'
|
25
|
+
expect(account).to be_valid
|
26
|
+
expect(account.errors.full_messages).to be_empty
|
27
|
+
end
|
28
|
+
|
29
|
+
now 'save the account' do
|
30
|
+
expect(account.save).to be true
|
31
|
+
expect(account.id).to be_present
|
32
|
+
expect(account.errors.full_messages).to eq []
|
33
|
+
end
|
34
|
+
|
35
|
+
now 'ensure error messages are accessible' do
|
36
|
+
expect(account.update_attributes status: 'Active').to be false
|
37
|
+
expect(account.errors.full_messages).to eq ['Active account must have both sold to and bill to.']
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveZuora::Base do
|
4
|
+
class Comment
|
5
|
+
include ActiveZuora::ZObject
|
6
|
+
field :name, :string
|
7
|
+
field :null_field, :string
|
8
|
+
end
|
9
|
+
|
10
|
+
context "#fields_order" do
|
11
|
+
let(:comment) { Comment.new :id => 'blog1', :null_field => nil, :name => 'test' }
|
12
|
+
let(:field_id) { comment.get_field(:id) }
|
13
|
+
let(:field_null) { comment.get_field(:null_field) }
|
14
|
+
let(:field_name) { comment.get_field(:name) }
|
15
|
+
let(:sorted_fields) { [field_null, field_id, field_name] }
|
16
|
+
|
17
|
+
it 'When the value of a field is null, it should be the first' do
|
18
|
+
fields1 = [field_id, field_null]
|
19
|
+
expect(fields1.sort(&comment.method(:fields_order))).to eq([field_null, field_id])
|
20
|
+
|
21
|
+
fields2 = [field_name, field_null]
|
22
|
+
expect(fields2.sort(&comment.method(:fields_order))).to eq([field_null, field_name])
|
23
|
+
|
24
|
+
fields3 = [field_id, field_name, field_null]
|
25
|
+
expect(fields3.sort(&comment.method(:fields_order))).to eq(sorted_fields)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'When the field name is id, it should be after the nil value fields but before all other fields' do
|
29
|
+
fields1 = [field_name, field_id]
|
30
|
+
expect(fields1.sort(&comment.method(:fields_order))).to eq([field_id, field_name])
|
31
|
+
|
32
|
+
fields2 = [field_null, field_id]
|
33
|
+
expect(fields2.sort(&comment.method(:fields_order))).to eq([field_null, field_id])
|
34
|
+
|
35
|
+
fields3 = [field_name, field_id, field_null]
|
36
|
+
expect(fields3.sort(&comment.method(:fields_order))).to eq(sorted_fields)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "BelongsToAssociations" do
|
4
|
+
|
5
|
+
class Blog
|
6
|
+
include ActiveZuora::ZObject
|
7
|
+
end
|
8
|
+
|
9
|
+
class Comment
|
10
|
+
include ActiveZuora::Base
|
11
|
+
belongs_to :blog
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should define a attribute assignment method method for the object" do
|
15
|
+
blog = Blog.new :id => "blog1"
|
16
|
+
comment = Comment.new :blog => blog
|
17
|
+
expect(comment.blog_loaded?).to be_truthy
|
18
|
+
expect(comment.blog).to eq(blog)
|
19
|
+
expect(comment.blog_id).to eq(blog.id)
|
20
|
+
comment.blog = nil
|
21
|
+
expect(comment.blog_loaded?).to be_truthy
|
22
|
+
expect(comment.blog).to be_nil
|
23
|
+
expect(comment.blog_id).to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should define a attribute assignment method for the object id" do
|
27
|
+
blog = Blog.new :id => "blog1"
|
28
|
+
comment = Comment.new :blog => blog
|
29
|
+
expect(comment.blog_loaded?).to be_truthy
|
30
|
+
comment.blog_id = "blog2"
|
31
|
+
expect(comment.blog_loaded?).to be_falsey
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "ActiveZuora::CollectionProxy" do
|
4
|
+
|
5
|
+
it "should initialize" do
|
6
|
+
cp = Z::CollectionProxy.new
|
7
|
+
expect(cp).to be_empty
|
8
|
+
cp = Z::CollectionProxy.new([Z::SubscribeRequest.new])
|
9
|
+
expect(cp).not_to be_empty
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should respond to enumerable methods" do
|
13
|
+
cp = Z::CollectionProxy.new([Z::SubscribeRequest.new])
|
14
|
+
cp.each do |cp|
|
15
|
+
expect(cp)
|
16
|
+
end
|
17
|
+
cp.inject do |memo,cp|
|
18
|
+
expect(memo)
|
19
|
+
expect(cp)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should respond to the batch_subscribe method" do
|
24
|
+
cp = Z::CollectionProxy.new([Z::SubscribeRequest.new])
|
25
|
+
expect(cp.respond_to?(:batch_subscribe)).to eq(true)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveZuora::Connection do
|
4
|
+
context "custom header" do
|
5
|
+
before do
|
6
|
+
@connection = ActiveZuora::Connection.new
|
7
|
+
@stub_was_called = false
|
8
|
+
end
|
9
|
+
|
10
|
+
it "passes the regular header if not set" do
|
11
|
+
allow(Savon::SOAP::Request).to receive(:new) do |config, http, soap|
|
12
|
+
@stub_was_called = true
|
13
|
+
expect(soap.header).to eq( { "SessionHeader" => {"session" => nil} } )
|
14
|
+
|
15
|
+
double('response').as_null_object
|
16
|
+
end
|
17
|
+
|
18
|
+
@connection.request(:amend) {}
|
19
|
+
|
20
|
+
expect(@stub_was_called).to be_truthy
|
21
|
+
end
|
22
|
+
|
23
|
+
it "merges in a custom header if set" do
|
24
|
+
@connection.custom_header = {'CallOptions' => {'useSingleTransaction' => true}}
|
25
|
+
allow(Savon::SOAP::Request).to receive(:new) do |config, http, soap|
|
26
|
+
@stub_was_called = true
|
27
|
+
expect(soap.header).to eq( { "SessionHeader" => {"session" => nil}, 'CallOptions' => {'useSingleTransaction' => true} } )
|
28
|
+
|
29
|
+
double('response').as_null_object
|
30
|
+
end
|
31
|
+
|
32
|
+
@connection.request(:amend) {}
|
33
|
+
|
34
|
+
expect(@stub_was_called).to be_truthy
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'login' do
|
39
|
+
before do
|
40
|
+
@connection = described_class.new
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when a custom header is set' do
|
44
|
+
it 'uses the custom header' do
|
45
|
+
@connection.custom_header = { 'TestHeader' => 'Foo' }
|
46
|
+
allow(Savon::SOAP::Request).to receive(:new) do |config, http, soap|
|
47
|
+
expect(soap.header).to eq({ 'TestHeader' => 'Foo' })
|
48
|
+
double('response').as_null_object
|
49
|
+
end
|
50
|
+
|
51
|
+
@connection.login
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when a custom header is not set' do
|
56
|
+
it 'does not use the custom header' do
|
57
|
+
allow(Savon::SOAP::Request).to receive(:new) do |config, http, soap|
|
58
|
+
expect(soap.header).to eq({})
|
59
|
+
double('response').as_null_object
|
60
|
+
end
|
61
|
+
|
62
|
+
@connection.login
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveZuora::DateField do
|
4
|
+
subject { described_class.new("date", described_class, {:zuora_name => "date"}) }
|
5
|
+
|
6
|
+
describe "#type_cast" do
|
7
|
+
it "returns nil if provided nil" do
|
8
|
+
expect(subject.type_cast(nil)).to eq(nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns a date when given a datetime object" do
|
12
|
+
datetime = DateTime.now
|
13
|
+
expect(subject.type_cast(datetime)).to be_a(Date)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "returns a date when given a date object" do
|
17
|
+
date = Date.today
|
18
|
+
expect(subject.type_cast(date)).to be_a(Date)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#build_xml" do
|
23
|
+
let(:xml) { double(:xml, :tag! => nil) }
|
24
|
+
let(:soap) { double(:soap, :namespace_by_uri => nil) }
|
25
|
+
let(:options) { {} }
|
26
|
+
|
27
|
+
it "handles a nil value" do
|
28
|
+
expect { subject.build_xml(xml, soap, nil, options) }.to_not raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "handles a date value" do
|
32
|
+
expect { subject.build_xml(xml, soap, Date.today, options) }.to_not raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "HasManyRelations" do
|
4
|
+
|
5
|
+
integration_test do
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@account = Z::Account.create!(
|
9
|
+
:name => "ZObject Integration Test Account",
|
10
|
+
:status => "Draft",
|
11
|
+
:currency => Tenant.currency,
|
12
|
+
:bill_cycle_day => 1)
|
13
|
+
@billy = Z::Contact.create!(
|
14
|
+
:account => @account,
|
15
|
+
:first_name => "Billy",
|
16
|
+
:last_name => "Blanks")
|
17
|
+
@franky = Z::Contact.create!(
|
18
|
+
:account => @account,
|
19
|
+
:first_name => "Franky",
|
20
|
+
:last_name => "Funhouse")
|
21
|
+
end
|
22
|
+
|
23
|
+
after :all do
|
24
|
+
# Delete the account to cleanup in case a test failed.
|
25
|
+
@account.delete if @account
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can specify conditions and order" do
|
29
|
+
Z::Account.instance_eval do
|
30
|
+
has_many :billies, :conditions => { :first_name => "Billy" }, :order => [:first_name, :desc], :class_name => 'Z::Contact'
|
31
|
+
end
|
32
|
+
expect(@account.billies.to_a).to eq([@billy])
|
33
|
+
expect(@account.billies.scope.order_attribute).to eq(:first_name)
|
34
|
+
expect(@account.billies.scope.order_direction).to eq(:desc)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can behave like an array" do
|
38
|
+
expect(@account.contacts.size).to eq(2)
|
39
|
+
expect(@account.contacts.map(&:first_name)).to match_array(%w{Billy Franky})
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can respond to functions on the Relation" do
|
43
|
+
@account.contacts.unload
|
44
|
+
expect(@account.contacts.loaded?).to be_falsey
|
45
|
+
@account.contacts.reload
|
46
|
+
expect(@account.contacts.loaded?).to be_truthy
|
47
|
+
expect(@account.contacts.where(:last_name => "Funhouse").to_a).to eq([@franky])
|
48
|
+
expect(@account.contacts.loaded?).to be_truthy
|
49
|
+
expect(@account.contacts.to_a).to match_array([@billy, @franky])
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'LazyAttr' do
|
4
|
+
class TestInovice
|
5
|
+
include ActiveZuora::LazyAttr
|
6
|
+
lazy_load :test_body
|
7
|
+
end
|
8
|
+
|
9
|
+
subject { TestInovice.new }
|
10
|
+
|
11
|
+
it "should fetch a lazy loaded attribute from the api" do
|
12
|
+
expect(subject).to receive(:fetch_field).with(:test_body){ 'Jesse "The Body"' }
|
13
|
+
subject.test_body
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should should not refetch an attribute after it's been loaded once" do
|
17
|
+
expect(subject).to receive(:fetch_field).with(:test_body).once { 'Jesse "The Body"' }
|
18
|
+
subject.test_body
|
19
|
+
subject.test_body
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|