xeroizer 2.20.0 → 3.0.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 +5 -5
- data/README.md +126 -185
- data/lib/xeroizer/connection.rb +49 -0
- data/lib/xeroizer/exceptions.rb +2 -0
- data/lib/xeroizer/generic_application.rb +8 -3
- data/lib/xeroizer/http.rb +5 -80
- data/lib/xeroizer/http_response.rb +154 -0
- data/lib/xeroizer/models/bank_transaction.rb +1 -0
- data/lib/xeroizer/models/batch_payment.rb +4 -1
- data/lib/xeroizer/models/contact.rb +10 -4
- data/lib/xeroizer/models/credit_note.rb +20 -20
- data/lib/xeroizer/models/history_record.rb +72 -0
- data/lib/xeroizer/models/invoice.rb +5 -1
- data/lib/xeroizer/models/line_item.rb +4 -2
- data/lib/xeroizer/models/manual_journal.rb +2 -1
- data/lib/xeroizer/models/option.rb +1 -1
- data/lib/xeroizer/models/payroll/address.rb +53 -0
- data/lib/xeroizer/models/payroll/bank_account.rb +18 -6
- data/lib/xeroizer/models/payroll/benefit_line.rb +26 -0
- data/lib/xeroizer/models/payroll/benefit_type.rb +45 -0
- data/lib/xeroizer/models/payroll/deduction_line.rb +32 -0
- data/lib/xeroizer/models/payroll/deduction_type.rb +49 -0
- data/lib/xeroizer/models/payroll/earnings_line.rb +39 -0
- data/lib/xeroizer/models/payroll/earnings_type.rb +53 -0
- data/lib/xeroizer/models/payroll/employee.rb +30 -8
- data/lib/xeroizer/models/payroll/leave_application.rb +27 -0
- data/lib/xeroizer/models/payroll/leave_line.rb +30 -0
- data/lib/xeroizer/models/payroll/leave_period.rb +15 -0
- data/lib/xeroizer/models/payroll/pay_items.rb +22 -0
- data/lib/xeroizer/models/payroll/pay_run.rb +33 -0
- data/lib/xeroizer/models/payroll/pay_schedule.rb +40 -0
- data/lib/xeroizer/models/payroll/pay_template.rb +24 -0
- data/lib/xeroizer/models/payroll/payment_method.rb +24 -0
- data/lib/xeroizer/models/payroll/paystub.rb +44 -0
- data/lib/xeroizer/models/payroll/reimbursement_line.rb +21 -0
- data/lib/xeroizer/models/payroll/reimbursement_type.rb +22 -0
- data/lib/xeroizer/models/payroll/salary_and_wage.rb +29 -0
- data/lib/xeroizer/models/payroll/super_line.rb +40 -0
- data/lib/xeroizer/models/payroll/tax_declaration.rb +50 -0
- data/lib/xeroizer/models/payroll/time_off_line.rb +20 -0
- data/lib/xeroizer/models/payroll/time_off_type.rb +32 -0
- data/lib/xeroizer/models/payroll/work_location.rb +25 -0
- data/lib/xeroizer/models/quote.rb +76 -0
- data/lib/xeroizer/models/tax_component.rb +1 -0
- data/lib/xeroizer/oauth.rb +12 -1
- data/lib/xeroizer/oauth2.rb +82 -0
- data/lib/xeroizer/oauth2_application.rb +49 -0
- data/lib/xeroizer/payroll_application.rb +8 -3
- data/lib/xeroizer/record/base_model.rb +1 -1
- data/lib/xeroizer/record/base_model_http_proxy.rb +1 -0
- data/lib/xeroizer/record/payroll_base.rb +4 -0
- data/lib/xeroizer/record/record_association_helper.rb +4 -4
- data/lib/xeroizer/record/validators/associated_validator.rb +1 -0
- data/lib/xeroizer/record/xml_helper.rb +16 -16
- data/lib/xeroizer/response.rb +22 -17
- data/lib/xeroizer/version.rb +1 -1
- data/lib/xeroizer.rb +31 -4
- data/test/acceptance/about_creating_bank_transactions_test.rb +80 -82
- data/test/acceptance/about_creating_prepayment_test.rb +25 -30
- data/test/acceptance/about_fetching_bank_transactions_test.rb +10 -10
- data/test/acceptance/about_online_invoice_test.rb +6 -10
- data/test/acceptance/acceptance_test.rb +28 -26
- data/test/acceptance/bank_transfer_test.rb +12 -17
- data/test/acceptance/bulk_operations_test.rb +18 -16
- data/test/acceptance/connections_test.rb +11 -0
- data/test/stub_responses/bad_request.json +6 -0
- data/test/stub_responses/connections.json +16 -0
- data/test/stub_responses/expired_oauth2_token.json +6 -0
- data/test/stub_responses/generic_response_error.json +6 -0
- data/test/stub_responses/invalid_oauth2_request_token.json +6 -0
- data/test/stub_responses/invalid_tenant_header.json +6 -0
- data/test/stub_responses/object_not_found.json +6 -0
- data/test/test_helper.rb +16 -11
- data/test/unit/generic_application_test.rb +21 -10
- data/test/unit/http_test.rb +281 -9
- data/test/unit/models/address_test.rb +2 -2
- data/test/unit/models/bank_transaction_model_parsing_test.rb +2 -2
- data/test/unit/models/bank_transaction_test.rb +1 -1
- data/test/unit/models/bank_transaction_validation_test.rb +1 -1
- data/test/unit/models/contact_test.rb +2 -2
- data/test/unit/models/credit_note_test.rb +8 -8
- data/test/unit/models/employee_test.rb +4 -4
- data/test/unit/models/invoice_test.rb +12 -12
- data/test/unit/models/journal_line_test.rb +6 -6
- data/test/unit/models/journal_test.rb +4 -4
- data/test/unit/models/line_item_sum_test.rb +1 -1
- data/test/unit/models/line_item_test.rb +19 -2
- data/test/unit/models/manual_journal_test.rb +3 -3
- data/test/unit/models/organisation_test.rb +2 -2
- data/test/unit/models/payment_service_test.rb +2 -2
- data/test/unit/models/phone_test.rb +7 -7
- data/test/unit/models/prepayment_test.rb +4 -4
- data/test/unit/models/repeating_invoice_test.rb +2 -2
- data/test/unit/models/tax_rate_test.rb +2 -2
- data/test/unit/oauth2_test.rb +171 -0
- data/test/unit/oauth_config_test.rb +1 -1
- data/test/unit/record/base_model_test.rb +13 -13
- data/test/unit/record/base_test.rb +5 -4
- data/test/unit/record/block_validator_test.rb +1 -1
- data/test/unit/record/connection_test.rb +60 -0
- data/test/unit/record/model_definition_test.rb +36 -36
- data/test/unit/record/parse_params_test.rb +2 -2
- data/test/unit/record/parse_where_hash_test.rb +13 -13
- data/test/unit/record/record_association_test.rb +14 -14
- data/test/unit/record/validators_test.rb +43 -43
- data/test/unit/record_definition_test.rb +7 -7
- data/test/unit/report_definition_test.rb +7 -7
- data/test/unit/report_test.rb +20 -20
- data/test/unit_test_helper.rb +16 -0
- metadata +106 -23
- data/lib/xeroizer/models/payroll/home_address.rb +0 -24
- data/lib/xeroizer/partner_application.rb +0 -51
- data/lib/xeroizer/private_application.rb +0 -25
- data/lib/xeroizer/public_application.rb +0 -21
- data/test/unit/http_tsl_12_upgrade_test.rb +0 -31
- data/test/unit/oauth_test.rb +0 -118
- data/test/unit/private_application_test.rb +0 -20
@@ -4,23 +4,18 @@ require "acceptance_test"
|
|
4
4
|
class BankTransfer < Test::Unit::TestCase
|
5
5
|
include AcceptanceTest
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
super
|
13
|
-
all_accounts = client.Account.all
|
14
|
-
@from_bank_account = all_accounts.select { |acct| acct.status == "ACTIVE" && acct.type == "BANK" }.first
|
15
|
-
@to_bank_account = all_accounts.select { |acct| acct.status == "ACTIVE" && acct.type == "BANK" }.last
|
16
|
-
end
|
7
|
+
it_works_using_oauth2 do |client, client_type|
|
8
|
+
can "create a bank for #{client_type}" do
|
9
|
+
all_accounts = client.Account.all
|
10
|
+
@from_bank_account = all_accounts.select { |acct| acct.status == "ACTIVE" && acct.type == "BANK" }.first
|
11
|
+
@to_bank_account = all_accounts.select { |acct| acct.status == "ACTIVE" && acct.type == "BANK" }.last
|
17
12
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
13
|
+
new_transfer = client.BankTransfer.build(
|
14
|
+
:amount => 300,
|
15
|
+
:from_bank_account => { :account_id => @from_bank_account.account_id },
|
16
|
+
:to_bank_account => { :account_id => @to_bank_account.account_id }
|
17
|
+
)
|
18
|
+
assert new_transfer.save, "Save failed with the following errors: #{new_transfer.errors.inspect}"
|
19
|
+
end
|
25
20
|
end
|
26
21
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
require "acceptance_test"
|
3
|
+
require "shoulda/matchers"
|
4
|
+
|
5
|
+
include Shoulda::Matchers
|
3
6
|
|
4
7
|
class BulkOperationsTest < Test::Unit::TestCase
|
5
8
|
include AcceptanceTest
|
@@ -8,18 +11,17 @@ class BulkOperationsTest < Test::Unit::TestCase
|
|
8
11
|
"test-person-#{rand 1000000000}"
|
9
12
|
end
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
@client = Xeroizer::PrivateApplication.new(@consumer_key, @consumer_secret, @key_file)
|
14
|
+
setup do
|
15
|
+
@client = AcceptanceTestHelpers.oauth2_client
|
14
16
|
end
|
15
17
|
|
16
|
-
|
18
|
+
should "create multiple invoices at once" do
|
17
19
|
c1, c2 = nil, nil
|
18
20
|
assert_true(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
@client.Contact.batch_save do
|
22
|
+
c1 = @client.Contact.build(name: random_name)
|
23
|
+
c2 = @client.Contact.build(name: random_name)
|
24
|
+
end
|
23
25
|
)
|
24
26
|
[c1, c2].each {|c| assert_false c.new_record? }
|
25
27
|
end
|
@@ -27,11 +29,11 @@ class BulkOperationsTest < Test::Unit::TestCase
|
|
27
29
|
can "create and update new records in bulk" do
|
28
30
|
c1, c2 = nil, nil
|
29
31
|
assert_true(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
@client.Contact.batch_save do
|
33
|
+
c1 = @client.Contact.create(name: random_name)
|
34
|
+
c1.email_address = "foo@bar.com"
|
35
|
+
c2 = @client.Contact.build(name: random_name)
|
36
|
+
end
|
35
37
|
)
|
36
38
|
[c1, c2].each {|c| assert_false c.new_record? }
|
37
39
|
c1.download_complete_record!
|
@@ -40,9 +42,9 @@ class BulkOperationsTest < Test::Unit::TestCase
|
|
40
42
|
|
41
43
|
can "return false from #batch_save if validation fails" do
|
42
44
|
assert_false(
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
@client.Contact.batch_save do
|
46
|
+
@client.Contact.build(email_address: "guy-with-no-name@example.com")
|
47
|
+
end
|
46
48
|
)
|
47
49
|
end
|
48
50
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "acceptance_test"
|
3
|
+
|
4
|
+
class ConnectionsTest < Test::Unit::TestCase
|
5
|
+
include AcceptanceTest
|
6
|
+
|
7
|
+
should "be able to hit Xero to get current connections via OAuth2" do
|
8
|
+
connections = AcceptanceTestHelpers.oauth2_client.current_connections
|
9
|
+
assert_not_nil connections.first.tenant_id
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"id": "9332e669-0a35-4084-8f05-cd1ff31918c2",
|
4
|
+
"tenantId": "7f5fabdd-9565-416a-9b62-d53d852bb2a3",
|
5
|
+
"tenantType": "ORGANISATION",
|
6
|
+
"createdDateUtc": "2019-12-13T18:10:43.3063640",
|
7
|
+
"updatedDateUtc": "2019-12-13T18:10:43.3084790"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"id": "8774aba8-708f-48d1-865e-zedf93a0d5d5",
|
11
|
+
"tenantId": "b4aca7b2-6fab-4ee7-a969-477f9128f636",
|
12
|
+
"tenantType": "ORGANISATION",
|
13
|
+
"createdDateUtc": "2019-12-13T18:06:31.5600280",
|
14
|
+
"updatedDateUtc": "2019-12-13T18:16:38.2095570"
|
15
|
+
}
|
16
|
+
]
|
data/test/test_helper.rb
CHANGED
@@ -4,10 +4,11 @@ require 'test/unit'
|
|
4
4
|
require 'mocha'
|
5
5
|
require 'shoulda'
|
6
6
|
require 'pp'
|
7
|
+
require 'pry'
|
7
8
|
|
8
9
|
require File.dirname(__FILE__) + '/../lib/xeroizer.rb'
|
9
10
|
|
10
|
-
$: << File.join(File.dirname(__FILE__), "acceptance")
|
11
|
+
$: << File.join(File.dirname(__FILE__), "acceptance")
|
11
12
|
|
12
13
|
module TestHelper
|
13
14
|
|
@@ -15,26 +16,31 @@ module TestHelper
|
|
15
16
|
# environment, and you must have set up a customer key for that account.
|
16
17
|
#
|
17
18
|
# You can then run the tests against the test environment using the commands (linux or mac):
|
18
|
-
# export STUB_XERO_CALLS=false
|
19
|
+
# export STUB_XERO_CALLS=false
|
19
20
|
# rake test
|
20
21
|
# (this probably won't work under OAuth?)
|
21
22
|
#
|
22
23
|
|
23
24
|
$VERBOSE=nil
|
24
|
-
|
25
|
+
|
25
26
|
STUB_XERO_CALLS = ENV["STUB_XERO_CALLS"].nil? ? true : (ENV["STUB_XERO_CALLS"] == "true") unless defined? STUB_XERO_CALLS
|
26
|
-
|
27
|
+
|
27
28
|
CONSUMER_KEY = ENV["CONSUMER_KEY"] || "fake_key" unless defined?(CONSUMER_KEY)
|
28
29
|
CONSUMER_SECRET = ENV["CONSUMER_SECRET"] || "fake_secret" unless defined?(CONSUMER_SECRET)
|
29
30
|
PRIVATE_KEY_PATH = ENV["PRIVATE_KEY_PATH"] || "fake_key" unless defined?(PRIVATE_KEY_PATH)
|
30
|
-
|
31
|
+
|
32
|
+
CLIENT_ID = ENV["XERO_CLIENT_ID"] || "fake_client_id" unless defined?(CLIENT_ID)
|
33
|
+
CLIENT_SECRET = ENV["XERO_CLIENT_SECRET"] || "fake_client_secret" unless defined?(CLIENT_SECRET)
|
34
|
+
ACCESS_TOKEN = ENV["XERO_ACCESS_TOKEN"] || "fake_access_token" unless defined?(ACCESS_TOKEN)
|
35
|
+
TENANT_ID = ENV["XERO_TENANT_ID"] || "fake_tenant_id" unless defined?(TENANT_ID)
|
36
|
+
|
31
37
|
# Helper constant for checking regex
|
32
38
|
GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ unless defined?(GUID_REGEX)
|
33
39
|
|
34
40
|
def get_file_as_string(filename)
|
35
41
|
File.read(File.dirname(__FILE__) + "/stub_responses/" + filename)
|
36
42
|
end
|
37
|
-
|
43
|
+
|
38
44
|
def get_record_xml(type, id = nil)
|
39
45
|
if id.nil?
|
40
46
|
get_file_as_string("#{type}.xml")
|
@@ -42,28 +48,27 @@ module TestHelper
|
|
42
48
|
get_file_as_string("records/#{type}-#{id}.xml")
|
43
49
|
end
|
44
50
|
end
|
45
|
-
|
51
|
+
|
46
52
|
def get_report_xml(report_type)
|
47
53
|
get_file_as_string("reports/#{report_type.underscore}.xml")
|
48
54
|
end
|
49
|
-
|
55
|
+
|
50
56
|
def mock_api(model_name)
|
51
57
|
@client.stubs(:http_get).with {|client, url, params| url =~ /#{model_name}$/ }.returns(get_record_xml(model_name.underscore.pluralize.to_s.to_sym))
|
52
58
|
@client.send(model_name.singularize.to_s.to_sym).all.each do | record |
|
53
59
|
@client.stubs(:http_get).with {|client, url, params| url =~ /#{model_name}\/#{record.id}$/ }.returns(get_record_xml(model_name.underscore.singularize.to_s.to_sym, record.id))
|
54
60
|
end
|
55
61
|
end
|
56
|
-
|
62
|
+
|
57
63
|
def mock_report_api(report_type)
|
58
64
|
@client.stubs(:http_get).with { | client, url, params | url =~ /Reports\/#{report_type}$/ }.returns(get_report_xml(report_type))
|
59
65
|
end
|
60
|
-
|
61
66
|
end
|
62
67
|
|
63
68
|
Shoulda::Context::ClassMethods.class_eval do
|
64
69
|
%w{it must can}.each do |m|
|
65
70
|
alias_method m, :should
|
66
71
|
end
|
67
|
-
|
72
|
+
|
68
73
|
alias_method :must_eventually, :should_eventually
|
69
74
|
end
|
@@ -1,26 +1,37 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_test_helper'
|
2
2
|
|
3
3
|
class GenericApplicationTest < Test::Unit::TestCase
|
4
4
|
include TestHelper
|
5
5
|
|
6
|
-
|
6
|
+
setup do
|
7
7
|
@headers = {"User-Agent" => "Xeroizer/2.15.5"}
|
8
8
|
@unitdp = 4
|
9
|
-
@
|
9
|
+
@options = {
|
10
|
+
default_headers: @headers,
|
11
|
+
unitdp: @unitdp
|
12
|
+
}
|
10
13
|
end
|
11
14
|
|
12
|
-
|
15
|
+
it "fails when provided an invalid client" do
|
16
|
+
client = "an invalid client"
|
17
|
+
|
18
|
+
assert_raises Xeroizer::InvalidClientError do
|
19
|
+
Xeroizer::GenericApplication.new(client, {})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "oauth 2" do
|
24
|
+
setup do
|
25
|
+
client = Xeroizer::OAuth2.new(CLIENT_ID, CLIENT_SECRET, @options)
|
26
|
+
@application = Xeroizer::GenericApplication.new(client, @options)
|
27
|
+
end
|
13
28
|
|
14
29
|
should "pass default headers" do
|
15
|
-
assert_equal(@headers, @
|
30
|
+
assert_equal(@headers, @application.default_headers)
|
16
31
|
end
|
17
32
|
|
18
33
|
should "pass unitdp value" do
|
19
|
-
assert_equal(@unitdp, @
|
34
|
+
assert_equal(@unitdp, @application.unitdp)
|
20
35
|
end
|
21
|
-
|
22
36
|
end
|
23
|
-
|
24
37
|
end
|
25
|
-
|
26
|
-
|
data/test/unit/http_test.rb
CHANGED
@@ -1,18 +1,290 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_test_helper'
|
2
2
|
|
3
|
-
class HttpTest <
|
3
|
+
class HttpTest < UnitTestCase
|
4
4
|
include TestHelper
|
5
5
|
|
6
|
-
|
6
|
+
setup do
|
7
|
+
@uri = "https://api.xero.com/path"
|
8
|
+
end
|
9
|
+
|
10
|
+
context "errors" do
|
7
11
|
setup do
|
8
|
-
@
|
9
|
-
|
12
|
+
@application = Xeroizer::OAuth2Application.new(CLIENT_ID, CLIENT_SECRET, tenant_id: TENANT_ID, access_token: ACCESS_TOKEN)
|
13
|
+
end
|
14
|
+
|
15
|
+
context "400" do
|
16
|
+
setup do
|
17
|
+
status_code = 400
|
18
|
+
@body = get_file_as_string("credit_note_not_found_error.xml")
|
19
|
+
stub_request(:get, @uri).to_return(status: status_code, body: @body)
|
20
|
+
end
|
21
|
+
|
22
|
+
should "raise an ApiException" do
|
23
|
+
error = assert_raises(Xeroizer::ApiException) { @application.http_get(@application.client, @uri) }
|
24
|
+
assert_equal ": \n Generated by the following XML: \n #{@body}", error.message
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "401" do
|
29
|
+
setup do
|
30
|
+
@status_code = 401
|
31
|
+
end
|
32
|
+
|
33
|
+
context "token_expired" do
|
34
|
+
setup do
|
35
|
+
body = get_file_as_string("token_expired")
|
36
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
37
|
+
end
|
38
|
+
|
39
|
+
should "raise an OAuth::TokenExpired" do
|
40
|
+
error = assert_raises(Xeroizer::OAuth::TokenExpired) { @application.http_get(@application.client, @uri) }
|
41
|
+
assert_equal "Unexpected token", error.message
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "token_rejected" do
|
46
|
+
setup do
|
47
|
+
body = "oauth_problem_advice=some advice&oauth_problem=token_rejected"
|
48
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
49
|
+
end
|
50
|
+
|
51
|
+
should "raise an OAuth::TokenInvalid" do
|
52
|
+
error = assert_raises(Xeroizer::OAuth::TokenInvalid) { @application.http_get(@application.client, @uri) }
|
53
|
+
assert_equal "some advice", error.message
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "rate limit exceeded" do
|
58
|
+
setup do
|
59
|
+
body = get_file_as_string("rate_limit_exceeded")
|
60
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
61
|
+
end
|
62
|
+
|
63
|
+
should "raise an OAuth::RateLimitExceeded" do
|
64
|
+
error = assert_raises(Xeroizer::OAuth::RateLimitExceeded) { @application.http_get(@application.client, @uri) }
|
65
|
+
assert_equal "please wait before retrying the xero api\n", error.message
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "consumer_key_unknown" do
|
70
|
+
setup do
|
71
|
+
body = "oauth_problem_advice=some more advice&oauth_problem=consumer_key_unknown"
|
72
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
73
|
+
end
|
74
|
+
|
75
|
+
should "raise an OAuth::ConsumerKeyUnknown" do
|
76
|
+
error = assert_raises(Xeroizer::OAuth::ConsumerKeyUnknown) { @application.http_get(@application.client, @uri) }
|
77
|
+
assert_equal "some more advice", error.message
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "nonce_used" do
|
82
|
+
setup do
|
83
|
+
body = get_file_as_string("nonce_used")
|
84
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "raise an OAuth::NonceUsed" do
|
88
|
+
error = assert_raises(Xeroizer::OAuth::NonceUsed) { @application.http_get(@application.client, @uri) }
|
89
|
+
assert_equal "The nonce value \"potatocakes\" has already been used ", error.message
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "organisation offline" do
|
94
|
+
setup do
|
95
|
+
body = "oauth_problem_advice=organisational advice&oauth_problem=organisation offline"
|
96
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
97
|
+
end
|
98
|
+
|
99
|
+
should "raise an OAuth::OrganisationOffline" do
|
100
|
+
error = assert_raises(Xeroizer::OAuth::OrganisationOffline) { @application.http_get(@application.client, @uri) }
|
101
|
+
assert_equal "organisational advice", error.message
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "unknown error" do
|
106
|
+
setup do
|
107
|
+
body = "oauth_problem_advice=unknown advice&oauth_problem=unknown error"
|
108
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
109
|
+
end
|
110
|
+
|
111
|
+
should "raise an OAuth::UnknownError" do
|
112
|
+
error = assert_raises(Xeroizer::OAuth::UnknownError) { @application.http_get(@application.client, @uri) }
|
113
|
+
assert_equal "unknown error:unknown advice", error.message
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "404" do
|
119
|
+
setup do
|
120
|
+
@status_code = 404
|
121
|
+
end
|
122
|
+
|
123
|
+
context "invoices" do
|
124
|
+
setup do
|
125
|
+
@uri = "https://api.xero.com/Invoices"
|
126
|
+
body = get_file_as_string("invoice_not_found_error.xml")
|
127
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
128
|
+
end
|
129
|
+
|
130
|
+
should "raise an InvoiceNotFoundError" do
|
131
|
+
error = assert_raises(Xeroizer::InvoiceNotFoundError) { @application.http_get(@application.client, @uri) }
|
132
|
+
assert_equal "Invoice not found in Xero.", error.message
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "credit notes" do
|
137
|
+
setup do
|
138
|
+
@uri = "https://api.xero.com/CreditNotes"
|
139
|
+
body = get_file_as_string("credit_note_not_found_error.xml")
|
140
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
141
|
+
end
|
142
|
+
|
143
|
+
should "raise an CreditNoteNotFoundError" do
|
144
|
+
error = assert_raises(Xeroizer::CreditNoteNotFoundError) { @application.http_get(@application.client, @uri) }
|
145
|
+
assert_equal "Credit Note not found in Xero.", error.message
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "anything else" do
|
150
|
+
setup do
|
151
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: "body")
|
152
|
+
end
|
153
|
+
|
154
|
+
should "raise an ObjectNotFound" do
|
155
|
+
error = assert_raises(Xeroizer::ObjectNotFound) { @application.http_get(@application.client, @uri) }
|
156
|
+
assert_equal "Couldn't find object for API Endpoint #{@uri}", error.message
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "429" do
|
162
|
+
setup do
|
163
|
+
@status_code = 429
|
164
|
+
end
|
165
|
+
|
166
|
+
context "rate_limit_exceeded" do
|
167
|
+
setup do
|
168
|
+
stub_request(:get, @uri).to_return(
|
169
|
+
status: @status_code,
|
170
|
+
body: "",
|
171
|
+
headers: {
|
172
|
+
"x-daylimit-remaining" => "328",
|
173
|
+
"retry-after" => "42",
|
174
|
+
}
|
175
|
+
)
|
176
|
+
end
|
177
|
+
|
178
|
+
should "raise an OAuth::RateLimitExceeded" do
|
179
|
+
error = assert_raises(Xeroizer::OAuth::RateLimitExceeded){ @application.http_get(@application.client, @uri) }
|
180
|
+
assert_match /rate limit exceeded/i, error.message
|
181
|
+
assert_match /328 requests left for the day/i, error.message
|
182
|
+
assert_match /42 seconds until you can make another request/i, error.message
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "503" do
|
188
|
+
setup do
|
189
|
+
@status_code = 503
|
190
|
+
end
|
191
|
+
|
192
|
+
context "token_expired" do
|
193
|
+
setup do
|
194
|
+
body = get_file_as_string("token_expired")
|
195
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
196
|
+
end
|
197
|
+
|
198
|
+
should "raise an OAuth::TokenExpired" do
|
199
|
+
error = assert_raises(Xeroizer::OAuth::TokenExpired) { @application.http_get(@application.client, @uri) }
|
200
|
+
assert_equal "Unexpected token", error.message
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context "token_rejected" do
|
205
|
+
setup do
|
206
|
+
body = "oauth_problem_advice=some advice&oauth_problem=token_rejected"
|
207
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
208
|
+
end
|
209
|
+
|
210
|
+
should "raise an OAuth::TokenInvalid" do
|
211
|
+
error = assert_raises(Xeroizer::OAuth::TokenInvalid) { @application.http_get(@application.client, @uri) }
|
212
|
+
assert_equal "some advice", error.message
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "rate limit exceeded" do
|
217
|
+
setup do
|
218
|
+
body = get_file_as_string("rate_limit_exceeded")
|
219
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
220
|
+
end
|
221
|
+
|
222
|
+
should "raise an OAuth::RateLimitExceeded" do
|
223
|
+
error = assert_raises(Xeroizer::OAuth::RateLimitExceeded) { @application.http_get(@application.client, @uri) }
|
224
|
+
assert_equal "please wait before retrying the xero api\n", error.message
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
context "consumer_key_unknown" do
|
229
|
+
setup do
|
230
|
+
body = "oauth_problem_advice=some more advice&oauth_problem=consumer_key_unknown"
|
231
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
232
|
+
end
|
233
|
+
|
234
|
+
should "raise an OAuth::ConsumerKeyUnknown" do
|
235
|
+
error = assert_raises(Xeroizer::OAuth::ConsumerKeyUnknown) { @application.http_get(@application.client, @uri) }
|
236
|
+
assert_equal "some more advice", error.message
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context "nonce_used" do
|
241
|
+
setup do
|
242
|
+
body = get_file_as_string("nonce_used")
|
243
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
244
|
+
end
|
245
|
+
|
246
|
+
should "raise an OAuth::NonceUsed" do
|
247
|
+
error = assert_raises(Xeroizer::OAuth::NonceUsed) { @application.http_get(@application.client, @uri) }
|
248
|
+
assert_equal "The nonce value \"potatocakes\" has already been used ", error.message
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "organisation offline" do
|
253
|
+
setup do
|
254
|
+
body = "oauth_problem_advice=organisational advice&oauth_problem=organisation offline"
|
255
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
256
|
+
end
|
257
|
+
|
258
|
+
should "raise an OAuth::OrganisationOffline" do
|
259
|
+
error = assert_raises(Xeroizer::OAuth::OrganisationOffline) { @application.http_get(@application.client, @uri) }
|
260
|
+
assert_equal "organisational advice", error.message
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "unknown error" do
|
265
|
+
setup do
|
266
|
+
body = "oauth_problem_advice=unknown advice&oauth_problem=unknown error"
|
267
|
+
stub_request(:get, @uri).to_return(status: @status_code, body: body)
|
268
|
+
end
|
269
|
+
|
270
|
+
should "raise an OAuth::UnknownError" do
|
271
|
+
error = assert_raises(Xeroizer::OAuth::UnknownError) { @application.http_get(@application.client, @uri) }
|
272
|
+
assert_equal "unknown error:unknown advice", error.message
|
273
|
+
end
|
274
|
+
end
|
10
275
|
end
|
11
276
|
|
12
|
-
|
13
|
-
|
14
|
-
|
277
|
+
context "other status" do
|
278
|
+
setup do
|
279
|
+
body = get_file_as_string("token_expired")
|
280
|
+
stub_request(:get, @uri).to_return(status: 418, body: body)
|
281
|
+
end
|
282
|
+
|
283
|
+
should "raise an BadRespone" do
|
284
|
+
error = assert_raises(Xeroizer::BadResponse) { @application.http_get(@application.client, @uri) }
|
285
|
+
assert_equal "Unknown response code: 418", error.message
|
286
|
+
end
|
287
|
+
|
15
288
|
end
|
16
289
|
end
|
17
290
|
end
|
18
|
-
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_test_helper'
|
2
2
|
|
3
3
|
class AddressTest < Test::Unit::TestCase
|
4
4
|
include TestHelper
|
5
5
|
|
6
6
|
def setup
|
7
|
-
@client = Xeroizer::
|
7
|
+
@client = Xeroizer::OAuth2Application.new(CLIENT_ID, CLIENT_SECRET)
|
8
8
|
@contact = @client.Contact.build
|
9
9
|
end
|
10
10
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'unit_test_helper'
|
2
2
|
|
3
3
|
class BankTransactionModelParsingTest < Test::Unit::TestCase
|
4
4
|
def setup
|
@@ -33,7 +33,7 @@ class BankTransactionModelParsingTest < Test::Unit::TestCase
|
|
33
33
|
assert_equal "Inclusive", the_bank_transaction.line_amount_types
|
34
34
|
|
35
35
|
assert_equal(Time.parse("2008-02-20T12:19:56.657Z"), the_bank_transaction.updated_date_utc)
|
36
|
-
|
36
|
+
|
37
37
|
assert_equal Date.parse("2010-07-30T00:00:00"), the_bank_transaction.fully_paid_on_date
|
38
38
|
assert_equal "d20b6c54-7f5d-4ce6-ab83-55f609719126", the_bank_transaction.bank_transaction_id
|
39
39
|
assert_equal "SPEND", the_bank_transaction.type
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_test_helper'
|
2
2
|
|
3
3
|
class ContactTest < Test::Unit::TestCase
|
4
4
|
include TestHelper
|
5
5
|
|
6
6
|
def setup
|
7
|
-
@client = Xeroizer::
|
7
|
+
@client = Xeroizer::OAuth2Application.new(CLIENT_ID, CLIENT_SECRET)
|
8
8
|
end
|
9
9
|
|
10
10
|
context "contact validators" do
|