qbo_rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +23 -0
- data/lib/generators/qbo_rails/install/install_generator.rb +32 -0
- data/lib/generators/qbo_rails/install/templates/config/qbo_rails.rb +17 -0
- data/lib/generators/qbo_rails/install/templates/db/migrate/create_qbo_errors.rb +12 -0
- data/lib/generators/qbo_rails/install/templates/models/qbo_error.rb +3 -0
- data/lib/generators/qbo_rails/install/usage.md +3 -0
- data/lib/qbo_rails.rb +106 -0
- data/lib/qbo_rails/error_handler.rb +4 -0
- data/lib/qbo_rails/version.rb +3 -0
- data/lib/tasks/qbo_rails_tasks.rake +4 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/settings_controller.rb +33 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/account.rb +2 -0
- data/spec/dummy/app/models/customer.rb +2 -0
- data/spec/dummy/app/models/qbo_error.rb +3 -0
- data/spec/dummy/app/services/qbo_rails.rb +15 -0
- data/spec/dummy/app/services/qbo_rails/error_handler.rb +32 -0
- data/spec/dummy/app/views/layouts/application.html.erb +26 -0
- data/spec/dummy/app/views/settings/close_and_redirect.html.erb +14 -0
- data/spec/dummy/app/views/settings/index.html.erb +29 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +8 -0
- data/spec/dummy/bin/rake +8 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +41 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/dotenv.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/qbo_rails.rb +17 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/webmock.rb +2 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20150319132530_create_accounts.rb +12 -0
- data/spec/dummy/db/migrate/20150319132650_create_customers.rb +17 -0
- data/spec/dummy/db/migrate/20150328125013_add_qbo_id_to_customer.rb +5 -0
- data/spec/dummy/db/migrate/20150418134516_create_qbo_errors.rb +12 -0
- data/spec/dummy/db/production.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +50 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +584 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/test.log +6502 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/cache/222/7E0/token +2 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/spec/factories/accounts.rb +8 -0
- data/spec/factories/customers.rb +15 -0
- data/spec/rails_helper.rb +92 -0
- data/spec/requests/qbo_rails_spec.rb +118 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/vcr/qbo_rails/auth/forbidden.yml +119 -0
- data/spec/vcr/qbo_rails/customer/create.yml +75 -0
- data/spec/vcr/qbo_rails/customer/create_and_then_delete.yml +225 -0
- data/spec/vcr/qbo_rails/customer/delete.yml +167 -0
- data/spec/vcr/qbo_rails/customer/error_customer_in_use.yml +257 -0
- data/spec/vcr/qbo_rails/customer/update.yml +138 -0
- metadata +358 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The page you were looking for doesn't exist (404)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/404.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The page you were looking for doesn't exist.</h1>
|
62
|
+
<p>You may have mistyped the address or the page may have moved.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,67 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>The change you wanted was rejected (422)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/422.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>The change you wanted was rejected.</h1>
|
62
|
+
<p>Maybe you tried to change something you didn't have access to.</p>
|
63
|
+
</div>
|
64
|
+
<p>If you are the application owner check the logs for more information.</p>
|
65
|
+
</div>
|
66
|
+
</body>
|
67
|
+
</html>
|
@@ -0,0 +1,66 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>We're sorry, but something went wrong (500)</title>
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
6
|
+
<style>
|
7
|
+
body {
|
8
|
+
background-color: #EFEFEF;
|
9
|
+
color: #2E2F30;
|
10
|
+
text-align: center;
|
11
|
+
font-family: arial, sans-serif;
|
12
|
+
margin: 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
div.dialog {
|
16
|
+
width: 95%;
|
17
|
+
max-width: 33em;
|
18
|
+
margin: 4em auto 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
div.dialog > div {
|
22
|
+
border: 1px solid #CCC;
|
23
|
+
border-right-color: #999;
|
24
|
+
border-left-color: #999;
|
25
|
+
border-bottom-color: #BBB;
|
26
|
+
border-top: #B00100 solid 4px;
|
27
|
+
border-top-left-radius: 9px;
|
28
|
+
border-top-right-radius: 9px;
|
29
|
+
background-color: white;
|
30
|
+
padding: 7px 12% 0;
|
31
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
32
|
+
}
|
33
|
+
|
34
|
+
h1 {
|
35
|
+
font-size: 100%;
|
36
|
+
color: #730E15;
|
37
|
+
line-height: 1.5em;
|
38
|
+
}
|
39
|
+
|
40
|
+
div.dialog > p {
|
41
|
+
margin: 0 0 1em;
|
42
|
+
padding: 1em;
|
43
|
+
background-color: #F7F7F7;
|
44
|
+
border: 1px solid #CCC;
|
45
|
+
border-right-color: #999;
|
46
|
+
border-left-color: #999;
|
47
|
+
border-bottom-color: #999;
|
48
|
+
border-bottom-left-radius: 4px;
|
49
|
+
border-bottom-right-radius: 4px;
|
50
|
+
border-top-color: #DADADA;
|
51
|
+
color: #666;
|
52
|
+
box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
|
53
|
+
}
|
54
|
+
</style>
|
55
|
+
</head>
|
56
|
+
|
57
|
+
<body>
|
58
|
+
<!-- This file lives in public/500.html -->
|
59
|
+
<div class="dialog">
|
60
|
+
<div>
|
61
|
+
<h1>We're sorry, but something went wrong.</h1>
|
62
|
+
</div>
|
63
|
+
<p>If you are the application owner check the logs for more information.</p>
|
64
|
+
</div>
|
65
|
+
</body>
|
66
|
+
</html>
|
File without changes
|
@@ -0,0 +1,2 @@
|
|
1
|
+
o: ActiveSupport::Cache::Entry:@valueo:OAuth::RequestToken :@tokenI"5qyprdsbsHPZNViCb0vqEioyKMfQLD65wB9koW9KLjPysIphH:ET:@secretI"-BLa09K3SI9qESOgWJJCi22mIwboXQoso7MtjtRbW; T:@consumerU:OAuth::Consumer{:keyI"#qyprdhobqczMYO48EHGKyw40TRExem; T:secretI"-dPeYy2UNbMzyaRnNKpFX6bw6PIl6scQU06M07k0I; T:options{:signature_methodI"HMAC-SHA1; T:request_token_pathI" /oauth/v1/get_request_token; T:authorize_pathI"/oauth/authorize; T:access_token_pathI"/oauth/v1/get_access_token; T:
|
2
|
+
proxy0:scheme:header:http_method: post:oauth_versionI"1.0; T: siteI"https://oauth.intuit.com; T:authorize_urlI"/https://appcenter.intuit.com/Connect/Begin; T:@params{:oauth_token_secret@I"oauth_token_secret; T@:oauth_callback_confirmedI" true; TI"oauth_callback_confirmed; T@:oauth_token@I"oauth_token; T@:@created_atf1438085447.409708:@expires_in0
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,8 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :account do
|
3
|
+
company_name 'Nelson Hockey Club'
|
4
|
+
qb_token Rails.application.secrets.qbo_sandbox_access_token
|
5
|
+
qb_secret Rails.application.secrets.qbo_sandbox_access_token_secret
|
6
|
+
qb_company_id Rails.application.secrets.qbo_sandbox_company_id
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Read about factories at https://github.com/thoughtbot/factory_girl
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :customer do
|
5
|
+
firstname "Emer"
|
6
|
+
lastname "Rackowski"
|
7
|
+
email "erack@mail.com"
|
8
|
+
phone "333-444-5555"
|
9
|
+
mobile "666-777-8888"
|
10
|
+
address_1 "1 East Haskins Road"
|
11
|
+
city "Nelson"
|
12
|
+
state "NH"
|
13
|
+
zip "03457-4555"
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
ENV["RAILS_ENV"] ||= 'test'
|
3
|
+
require 'spec_helper'
|
4
|
+
require File.expand_path("../dummy/config/environment", __FILE__)
|
5
|
+
require 'rspec/rails'
|
6
|
+
require 'factory_girl_rails'
|
7
|
+
require 'vcr'
|
8
|
+
|
9
|
+
VCR.configure do |config|
|
10
|
+
config.cassette_library_dir = File.expand_path("../vcr", __FILE__)
|
11
|
+
config.hook_into :webmock
|
12
|
+
s = Rails.application.secrets
|
13
|
+
config.filter_sensitive_data('<ACCESS_TOKEN>') { URI.encode_www_form_component(s.qbo_sandbox_access_token) }
|
14
|
+
config.filter_sensitive_data('<CONSUMER_KEY>') { URI.encode_www_form_component(s.qbo_app_consumer_key) }
|
15
|
+
config.filter_sensitive_data('<COMPANY_ID>') { URI.encode_www_form_component(s.qbo_sandbox_company_id) }
|
16
|
+
|
17
|
+
uri_matcher = VCR.request_matchers[:uri]
|
18
|
+
# Don't check sandbox company id or trailing URL id
|
19
|
+
# This enables multiple different sandboxes to be used
|
20
|
+
# in testing
|
21
|
+
config.register_request_matcher(:for_intuit) do |req_1, req_2|
|
22
|
+
uri1, uri2 = req_1.uri, req_2.uri
|
23
|
+
if uri1 =~ /intuit\.com/ && uri2 =~ /intuit\.com/
|
24
|
+
strip_url_company_id(req_1.uri, req_2.uri)
|
25
|
+
regexp_trail_id = %r(/\d+/?\z)
|
26
|
+
if uri1.match(regexp_trail_id)
|
27
|
+
r1_without_id = uri1.gsub(regexp_trail_id, "")
|
28
|
+
r2_without_id = uri2.gsub(regexp_trail_id, "")
|
29
|
+
uri1.match(regexp_trail_id) && uri2.match(regexp_trail_id) && r1_without_id == r2_without_id
|
30
|
+
else
|
31
|
+
uri_matcher.matches?(req_1, req_2)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
uri_matcher.matches?(req_1, req_2)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def strip_url_company_id(*args)
|
39
|
+
regexp_company_id = %r((company)/\d+/?)
|
40
|
+
args.each do |ref|
|
41
|
+
ref.sub!(regexp_company_id, '')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
config.default_cassette_options = { match_requests_on: [:method, :for_intuit] }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Add additional requires below this line. Rails is not loaded until this point!
|
48
|
+
|
49
|
+
# Requires supporting ruby files with custom matchers and macros, etc, in
|
50
|
+
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
|
51
|
+
# run as spec files by default. This means that files in spec/support that end
|
52
|
+
# in _spec.rb will both be required and run as specs, causing the specs to be
|
53
|
+
# run twice. It is recommended that you do not name files matching this glob to
|
54
|
+
# end with _spec.rb. You can configure this pattern with the --pattern
|
55
|
+
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
|
56
|
+
#
|
57
|
+
# The following line is provided for convenience purposes. It has the downside
|
58
|
+
# of increasing the boot-up time by auto-requiring all files in the support
|
59
|
+
# directory. Alternatively, in the individual `*_spec.rb` files, manually
|
60
|
+
# require only the support files necessary.
|
61
|
+
#
|
62
|
+
# Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
|
63
|
+
|
64
|
+
# Checks for pending migrations before tests are run.
|
65
|
+
# If you are not using ActiveRecord, you can remove this line.
|
66
|
+
ActiveRecord::Migration.maintain_test_schema!
|
67
|
+
|
68
|
+
RSpec.configure do |config|
|
69
|
+
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
70
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
71
|
+
config.include FactoryGirl::Syntax::Methods
|
72
|
+
|
73
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
74
|
+
# examples within a transaction, remove the following line or assign false
|
75
|
+
# instead of true.
|
76
|
+
config.use_transactional_fixtures = true
|
77
|
+
|
78
|
+
# RSpec Rails can automatically mix in different behaviours to your tests
|
79
|
+
# based on their file location, for example enabling you to call `get` and
|
80
|
+
# `post` in specs under `spec/controllers`.
|
81
|
+
#
|
82
|
+
# You can disable this behaviour by removing the line below, and instead
|
83
|
+
# explicitly tag your specs with their type, e.g.:
|
84
|
+
#
|
85
|
+
# RSpec.describe UsersController, :type => :controller do
|
86
|
+
# # ...
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# The different available types are documented in the features, such as in
|
90
|
+
# https://relishapp.com/rspec/rspec-rails/docs
|
91
|
+
config.infer_spec_type_from_file_location!
|
92
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe 'QBO request' do
|
4
|
+
|
5
|
+
describe '.create_or_update' do
|
6
|
+
it 'for a basic create' do
|
7
|
+
account = create(:account)
|
8
|
+
record = create(:customer, firstname: 'Edward')
|
9
|
+
qbo_rails, qb_customer = map_to_qbo(account, record)
|
10
|
+
expect(record.qbo_id).to be_nil
|
11
|
+
VCR.use_cassette("qbo_rails/customer/create", record: :none) do
|
12
|
+
qbo_rails.create_or_update(record, qb_customer)
|
13
|
+
record.reload
|
14
|
+
expect(record.qbo_id).to_not be_nil
|
15
|
+
expect(qbo_rails.result.sync_token).to eq 0
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'for a basic update' do
|
20
|
+
account = create(:account)
|
21
|
+
# Get the qbo_id from spec above
|
22
|
+
record = create(:customer, firstname: 'Edward', qbo_id: 60)
|
23
|
+
qbo_rails, qb_customer = map_to_qbo(account, record)
|
24
|
+
#Quickbooks.log = true
|
25
|
+
VCR.use_cassette("qbo_rails/customer/update", record: :none) do
|
26
|
+
result = qbo_rails.create_or_update(record, qb_customer)
|
27
|
+
expect(result.sync_token).to be > 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '.delete' do
|
34
|
+
# At this time you can't delete (or really make inactive) builtin entities
|
35
|
+
# in the the sandbox. So it returns a 400, bad request
|
36
|
+
it 'a sandbox customer record, Paulsen Medical Supplies, id 18' do
|
37
|
+
account = create(:account)
|
38
|
+
qbo_rails = QboRails.new(account, :customer)
|
39
|
+
#Quickbooks.log = true
|
40
|
+
VCR.use_cassette("qbo_rails/customer/delete", record: :none) do
|
41
|
+
expect{ result = qbo_rails.delete(18) }.to change{ QboError.count }.by(1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'deletes a newly created customer' do
|
46
|
+
account = create(:account)
|
47
|
+
record = create(:customer, firstname: 'Mathis')
|
48
|
+
qbo_rails, qb_customer = map_to_qbo(account, record)
|
49
|
+
#Quickbooks.log = true
|
50
|
+
VCR.use_cassette("qbo_rails/customer/create_and_then_delete", record: :none) do
|
51
|
+
qbo_rails.create_or_update(record, qb_customer)
|
52
|
+
qbo_rails.delete(record.reload)
|
53
|
+
expect(Nokogiri::XML(qbo_rails.result.to_xml.to_s).at('Active').content).to eq 'false'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe QboRails::ErrorHandler do
|
59
|
+
|
60
|
+
# You can see this is error in spec/dummy/app/service/qbo_rails/error_handler.rb
|
61
|
+
it 'initial request is an add request for existing customer that fails. Catch error
|
62
|
+
and resend request as an update' do
|
63
|
+
account = create(:account)
|
64
|
+
record = create(:customer)
|
65
|
+
qbo_rails, qb_customer = map_to_qbo(account, record)
|
66
|
+
expect(record.qbo_id).to be_nil
|
67
|
+
#Quickbooks.log = true
|
68
|
+
VCR.use_cassette("qbo_rails/customer/error_customer_in_use", record: :none) do
|
69
|
+
expect { qbo_rails.create_or_update(record, qb_customer) }.to change{ QboError.count }.by(0)
|
70
|
+
record.reload
|
71
|
+
expect(record.qbo_id).to_not be_nil
|
72
|
+
expect(qbo_rails.result.id).to eq record.qbo_id.to_s
|
73
|
+
expect(qbo_rails.error).to be_nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'does not match a custom error handler and records error' do
|
78
|
+
account = create(:account)
|
79
|
+
record = create(:customer)
|
80
|
+
qbo_rails, qb_customer = map_to_qbo(account, record)
|
81
|
+
qb_customer.display_name = 'Emer:Rack'
|
82
|
+
#Quickbooks.log = true
|
83
|
+
VCR.use_cassette("qbo_rails/customer/error_customer_bad_display_name", record: :none) do
|
84
|
+
expect{ qbo_rails.create_or_update(record, qb_customer) }.to change{ QboError.count }.by(1)
|
85
|
+
expect(qbo_rails.error).to_not be_nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# You can see this is error in spec/dummy/app/service/qbo_rails/error_handler.rb
|
90
|
+
it 'runs a custom error handler and verifies that @only_run_once prevents endless looping' do
|
91
|
+
account = create(:account)
|
92
|
+
account.qb_token = nil
|
93
|
+
account.qb_secret = nil
|
94
|
+
record = create(:customer)
|
95
|
+
qbo_rails, qb_customer = map_to_qbo(account, record)
|
96
|
+
expect(qbo_rails.only_run_once).to be nil
|
97
|
+
#Quickbooks.log = true
|
98
|
+
VCR.use_cassette("qbo_rails/auth/forbidden", record: :none) do
|
99
|
+
qbo_rails.create_or_update(record, qb_customer)
|
100
|
+
expect(qbo_rails.only_run_once).to be true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
def map_to_qbo(account, record)
|
107
|
+
qbo_rails = QboRails.new(account, :customer)
|
108
|
+
qb_customer = qbo_rails.base.qr_model(:customer)
|
109
|
+
qb_customer.display_name = "#{record.firstname} #{record.lastname}"
|
110
|
+
address = qbo_rails.base.qr_model :physical_address
|
111
|
+
address.line1 = record.address_1
|
112
|
+
address.city = record.city
|
113
|
+
address.country_sub_division_code = record.state
|
114
|
+
address.postal_code = record.zip
|
115
|
+
qb_customer.billing_address = address
|
116
|
+
[qbo_rails, qb_customer]
|
117
|
+
end
|
118
|
+
end
|