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.
Files changed (117) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +126 -185
  3. data/lib/xeroizer/connection.rb +49 -0
  4. data/lib/xeroizer/exceptions.rb +2 -0
  5. data/lib/xeroizer/generic_application.rb +8 -3
  6. data/lib/xeroizer/http.rb +5 -80
  7. data/lib/xeroizer/http_response.rb +154 -0
  8. data/lib/xeroizer/models/bank_transaction.rb +1 -0
  9. data/lib/xeroizer/models/batch_payment.rb +4 -1
  10. data/lib/xeroizer/models/contact.rb +10 -4
  11. data/lib/xeroizer/models/credit_note.rb +20 -20
  12. data/lib/xeroizer/models/history_record.rb +72 -0
  13. data/lib/xeroizer/models/invoice.rb +5 -1
  14. data/lib/xeroizer/models/line_item.rb +4 -2
  15. data/lib/xeroizer/models/manual_journal.rb +2 -1
  16. data/lib/xeroizer/models/option.rb +1 -1
  17. data/lib/xeroizer/models/payroll/address.rb +53 -0
  18. data/lib/xeroizer/models/payroll/bank_account.rb +18 -6
  19. data/lib/xeroizer/models/payroll/benefit_line.rb +26 -0
  20. data/lib/xeroizer/models/payroll/benefit_type.rb +45 -0
  21. data/lib/xeroizer/models/payroll/deduction_line.rb +32 -0
  22. data/lib/xeroizer/models/payroll/deduction_type.rb +49 -0
  23. data/lib/xeroizer/models/payroll/earnings_line.rb +39 -0
  24. data/lib/xeroizer/models/payroll/earnings_type.rb +53 -0
  25. data/lib/xeroizer/models/payroll/employee.rb +30 -8
  26. data/lib/xeroizer/models/payroll/leave_application.rb +27 -0
  27. data/lib/xeroizer/models/payroll/leave_line.rb +30 -0
  28. data/lib/xeroizer/models/payroll/leave_period.rb +15 -0
  29. data/lib/xeroizer/models/payroll/pay_items.rb +22 -0
  30. data/lib/xeroizer/models/payroll/pay_run.rb +33 -0
  31. data/lib/xeroizer/models/payroll/pay_schedule.rb +40 -0
  32. data/lib/xeroizer/models/payroll/pay_template.rb +24 -0
  33. data/lib/xeroizer/models/payroll/payment_method.rb +24 -0
  34. data/lib/xeroizer/models/payroll/paystub.rb +44 -0
  35. data/lib/xeroizer/models/payroll/reimbursement_line.rb +21 -0
  36. data/lib/xeroizer/models/payroll/reimbursement_type.rb +22 -0
  37. data/lib/xeroizer/models/payroll/salary_and_wage.rb +29 -0
  38. data/lib/xeroizer/models/payroll/super_line.rb +40 -0
  39. data/lib/xeroizer/models/payroll/tax_declaration.rb +50 -0
  40. data/lib/xeroizer/models/payroll/time_off_line.rb +20 -0
  41. data/lib/xeroizer/models/payroll/time_off_type.rb +32 -0
  42. data/lib/xeroizer/models/payroll/work_location.rb +25 -0
  43. data/lib/xeroizer/models/quote.rb +76 -0
  44. data/lib/xeroizer/models/tax_component.rb +1 -0
  45. data/lib/xeroizer/oauth.rb +12 -1
  46. data/lib/xeroizer/oauth2.rb +82 -0
  47. data/lib/xeroizer/oauth2_application.rb +49 -0
  48. data/lib/xeroizer/payroll_application.rb +8 -3
  49. data/lib/xeroizer/record/base_model.rb +1 -1
  50. data/lib/xeroizer/record/base_model_http_proxy.rb +1 -0
  51. data/lib/xeroizer/record/payroll_base.rb +4 -0
  52. data/lib/xeroizer/record/record_association_helper.rb +4 -4
  53. data/lib/xeroizer/record/validators/associated_validator.rb +1 -0
  54. data/lib/xeroizer/record/xml_helper.rb +16 -16
  55. data/lib/xeroizer/response.rb +22 -17
  56. data/lib/xeroizer/version.rb +1 -1
  57. data/lib/xeroizer.rb +31 -4
  58. data/test/acceptance/about_creating_bank_transactions_test.rb +80 -82
  59. data/test/acceptance/about_creating_prepayment_test.rb +25 -30
  60. data/test/acceptance/about_fetching_bank_transactions_test.rb +10 -10
  61. data/test/acceptance/about_online_invoice_test.rb +6 -10
  62. data/test/acceptance/acceptance_test.rb +28 -26
  63. data/test/acceptance/bank_transfer_test.rb +12 -17
  64. data/test/acceptance/bulk_operations_test.rb +18 -16
  65. data/test/acceptance/connections_test.rb +11 -0
  66. data/test/stub_responses/bad_request.json +6 -0
  67. data/test/stub_responses/connections.json +16 -0
  68. data/test/stub_responses/expired_oauth2_token.json +6 -0
  69. data/test/stub_responses/generic_response_error.json +6 -0
  70. data/test/stub_responses/invalid_oauth2_request_token.json +6 -0
  71. data/test/stub_responses/invalid_tenant_header.json +6 -0
  72. data/test/stub_responses/object_not_found.json +6 -0
  73. data/test/test_helper.rb +16 -11
  74. data/test/unit/generic_application_test.rb +21 -10
  75. data/test/unit/http_test.rb +281 -9
  76. data/test/unit/models/address_test.rb +2 -2
  77. data/test/unit/models/bank_transaction_model_parsing_test.rb +2 -2
  78. data/test/unit/models/bank_transaction_test.rb +1 -1
  79. data/test/unit/models/bank_transaction_validation_test.rb +1 -1
  80. data/test/unit/models/contact_test.rb +2 -2
  81. data/test/unit/models/credit_note_test.rb +8 -8
  82. data/test/unit/models/employee_test.rb +4 -4
  83. data/test/unit/models/invoice_test.rb +12 -12
  84. data/test/unit/models/journal_line_test.rb +6 -6
  85. data/test/unit/models/journal_test.rb +4 -4
  86. data/test/unit/models/line_item_sum_test.rb +1 -1
  87. data/test/unit/models/line_item_test.rb +19 -2
  88. data/test/unit/models/manual_journal_test.rb +3 -3
  89. data/test/unit/models/organisation_test.rb +2 -2
  90. data/test/unit/models/payment_service_test.rb +2 -2
  91. data/test/unit/models/phone_test.rb +7 -7
  92. data/test/unit/models/prepayment_test.rb +4 -4
  93. data/test/unit/models/repeating_invoice_test.rb +2 -2
  94. data/test/unit/models/tax_rate_test.rb +2 -2
  95. data/test/unit/oauth2_test.rb +171 -0
  96. data/test/unit/oauth_config_test.rb +1 -1
  97. data/test/unit/record/base_model_test.rb +13 -13
  98. data/test/unit/record/base_test.rb +5 -4
  99. data/test/unit/record/block_validator_test.rb +1 -1
  100. data/test/unit/record/connection_test.rb +60 -0
  101. data/test/unit/record/model_definition_test.rb +36 -36
  102. data/test/unit/record/parse_params_test.rb +2 -2
  103. data/test/unit/record/parse_where_hash_test.rb +13 -13
  104. data/test/unit/record/record_association_test.rb +14 -14
  105. data/test/unit/record/validators_test.rb +43 -43
  106. data/test/unit/record_definition_test.rb +7 -7
  107. data/test/unit/report_definition_test.rb +7 -7
  108. data/test/unit/report_test.rb +20 -20
  109. data/test/unit_test_helper.rb +16 -0
  110. metadata +106 -23
  111. data/lib/xeroizer/models/payroll/home_address.rb +0 -24
  112. data/lib/xeroizer/partner_application.rb +0 -51
  113. data/lib/xeroizer/private_application.rb +0 -25
  114. data/lib/xeroizer/public_application.rb +0 -21
  115. data/test/unit/http_tsl_12_upgrade_test.rb +0 -31
  116. data/test/unit/oauth_test.rb +0 -118
  117. 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
- let :client do
8
- Xeroizer::PrivateApplication.new(@consumer_key, @consumer_secret, @key_file)
9
- end
10
-
11
- def setup
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
- can "create a bank transfer" do
19
- new_transfer = client.BankTransfer.build(
20
- :amount => 300,
21
- :from_bank_account => { :account_id => @from_bank_account.account_id },
22
- :to_bank_account => { :account_id => @to_bank_account.account_id }
23
- )
24
- assert new_transfer.save, "Save failed with the following errors: #{new_transfer.errors.inspect}"
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
- def setup
12
- super
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
- can "create multiple invoices at once" do
18
+ should "create multiple invoices at once" do
17
19
  c1, c2 = nil, nil
18
20
  assert_true(
19
- @client.Contact.batch_save do
20
- c1 = @client.Contact.build(name: random_name)
21
- c2 = @client.Contact.build(name: random_name)
22
- end
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
- @client.Contact.batch_save do
31
- c1 = @client.Contact.create(name: random_name)
32
- c1.email_address = "foo@bar.com"
33
- c2 = @client.Contact.build(name: random_name)
34
- end
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
- @client.Contact.batch_save do
44
- @client.Contact.build(email_address: "guy-with-no-name@example.com")
45
- end
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,6 @@
1
+ {
2
+ "type": "invalid-request",
3
+ "title": "Invalid Request",
4
+ "status": 400,
5
+ "detail": "For the request field 'StatementLine.ChequeNumber' exceeded the maximum length of 20."
6
+ }
@@ -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
+ ]
@@ -0,0 +1,6 @@
1
+ {
2
+ "Title": "Unauthorized",
3
+ "Status": 401,
4
+ "Detail": "TokenExpired: token expired at 01/23/2020 18:21:16",
5
+ "Instance": "eac0fd6e-8d19-4bae-8121-cb7f7549ec67"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "duplicate-statement",
3
+ "title": "Duplicate Statement Received",
4
+ "status": 409,
5
+ "detail": "The received statement was marked as a duplicate."
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "Title": "Unauthorized",
3
+ "Status": 401,
4
+ "Detail": "AuthenticationUnsuccessful",
5
+ "Instance": "51e9d1af-397c-469f-a703-82a3003aef75"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "title": "Forbidden",
3
+ "status": 403,
4
+ "detail": "AuthenticationUnsuccessful",
5
+ "instance": "c375551e-dcbd-472a-af52-cafd73bfb349"
6
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "statement-not-found",
3
+ "title": "Statement Not Found",
4
+ "status": 404,
5
+ "detail": "The statement was not found."
6
+ }
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 'test_helper'
1
+ require 'unit_test_helper'
2
2
 
3
3
  class GenericApplicationTest < Test::Unit::TestCase
4
4
  include TestHelper
5
5
 
6
- def setup
6
+ setup do
7
7
  @headers = {"User-Agent" => "Xeroizer/2.15.5"}
8
8
  @unitdp = 4
9
- @client = Xeroizer::GenericApplication.new(CONSUMER_KEY, CONSUMER_SECRET, :default_headers => @headers, :unitdp => @unitdp)
9
+ @options = {
10
+ default_headers: @headers,
11
+ unitdp: @unitdp
12
+ }
10
13
  end
11
14
 
12
- context "initialization" do
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, @client.default_headers)
30
+ assert_equal(@headers, @application.default_headers)
16
31
  end
17
32
 
18
33
  should "pass unitdp value" do
19
- assert_equal(@unitdp, @client.unitdp)
34
+ assert_equal(@unitdp, @application.unitdp)
20
35
  end
21
-
22
36
  end
23
-
24
37
  end
25
-
26
-
@@ -1,18 +1,290 @@
1
- require 'test_helper'
1
+ require 'unit_test_helper'
2
2
 
3
- class HttpTest < Test::Unit::TestCase
3
+ class HttpTest < UnitTestCase
4
4
  include TestHelper
5
5
 
6
- context "default_headers" do
6
+ setup do
7
+ @uri = "https://api.xero.com/path"
8
+ end
9
+
10
+ context "errors" do
7
11
  setup do
8
- @headers = { "User-Agent" => "Xeroizer/2.15.5" }
9
- @application = Xeroizer::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET, :default_headers => @headers)
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
- should "recognize default_headers" do
13
- Xeroizer::OAuth.any_instance.expects(:get).with("/test", has_entry(@headers)).returns(stub(:plain_body => "", :code => "200"))
14
- @application.http_get(@application.client, "http://example.com/test")
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 'test_helper'
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::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET)
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 "test_helper"
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,4 +1,4 @@
1
- require "test_helper"
1
+ require 'unit_test_helper'
2
2
 
3
3
  class BankTransactionTest < Test::Unit::TestCase
4
4
  include Xeroizer::Record
@@ -1,4 +1,4 @@
1
- require "test_helper"
1
+ require 'unit_test_helper'
2
2
 
3
3
  class BankTransactionValidationTest < Test::Unit::TestCase
4
4
  include Xeroizer::Record
@@ -1,10 +1,10 @@
1
- require 'test_helper'
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::PublicApplication.new(CONSUMER_KEY, CONSUMER_SECRET)
7
+ @client = Xeroizer::OAuth2Application.new(CLIENT_ID, CLIENT_SECRET)
8
8
  end
9
9
 
10
10
  context "contact validators" do