netsuite 0.8.4 → 0.8.8
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/.github/workflows/main.yml +20 -0
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.tool-versions +1 -0
- data/Gemfile +2 -5
- data/HISTORY.md +26 -0
- data/README.md +72 -29
- data/Rakefile +1 -1
- data/lib/netsuite.rb +13 -19
- data/lib/netsuite/actions/login.rb +10 -2
- data/lib/netsuite/actions/upsert.rb +2 -0
- data/lib/netsuite/configuration.rb +34 -4
- data/lib/netsuite/records/accounting_period.rb +2 -2
- data/lib/netsuite/records/classification.rb +4 -1
- data/lib/netsuite/records/contact.rb +1 -1
- data/lib/netsuite/records/cost_category.rb +28 -0
- data/lib/netsuite/records/credit_memo.rb +1 -1
- data/lib/netsuite/records/custom_field_list.rb +9 -3
- data/lib/netsuite/records/custom_record.rb +1 -1
- data/lib/netsuite/records/customer.rb +2 -1
- data/lib/netsuite/records/customer_credit_cards.rb +36 -0
- data/lib/netsuite/records/customer_credit_cards_list.rb +10 -0
- data/lib/netsuite/records/customer_deposit.rb +5 -5
- data/lib/netsuite/records/customer_payment.rb +6 -2
- data/lib/netsuite/records/customer_payment_credit.rb +17 -0
- data/lib/netsuite/records/customer_payment_credit_list.rb +12 -0
- data/lib/netsuite/records/employee.rb +1 -1
- data/lib/netsuite/records/estimate.rb +42 -0
- data/lib/netsuite/records/estimate_item.rb +40 -0
- data/lib/netsuite/records/estimate_item_list.rb +11 -0
- data/lib/netsuite/records/inventory_item.rb +62 -1
- data/lib/netsuite/records/invoice.rb +94 -1
- data/lib/netsuite/records/item_fulfillment.rb +1 -1
- data/lib/netsuite/records/lot_numbered_inventory_item.rb +116 -0
- data/lib/netsuite/records/matrix_option_list.rb +12 -4
- data/lib/netsuite/records/message.rb +30 -0
- data/lib/netsuite/records/non_inventory_resale_item.rb +1 -0
- data/lib/netsuite/records/non_inventory_sale_item.rb +1 -1
- data/lib/netsuite/records/other_charge_sale_item.rb +2 -2
- data/lib/netsuite/records/partner.rb +7 -5
- data/lib/netsuite/records/serialized_assembly_item.rb +3 -1
- data/lib/netsuite/records/service_resale_item.rb +1 -1
- data/lib/netsuite/records/support_case_type.rb +26 -0
- data/lib/netsuite/records/tax_group.rb +2 -2
- data/lib/netsuite/records/vendor.rb +2 -1
- data/lib/netsuite/records/vendor_currency.rb +26 -0
- data/lib/netsuite/records/vendor_currency_list.rb +9 -0
- data/lib/netsuite/support/fields.rb +16 -0
- data/lib/netsuite/support/records.rb +1 -1
- data/lib/netsuite/support/search_result.rb +36 -6
- data/lib/netsuite/utilities.rb +18 -6
- data/lib/netsuite/version.rb +1 -1
- data/netsuite.gemspec +5 -3
- data/spec/netsuite/actions/search_spec.rb +22 -0
- data/spec/netsuite/configuration_spec.rb +111 -6
- data/spec/netsuite/records/basic_record_spec.rb +9 -1
- data/spec/netsuite/records/classification_spec.rb +10 -1
- data/spec/netsuite/records/cost_category_spec.rb +105 -0
- data/spec/netsuite/records/custom_field_list_spec.rb +46 -6
- data/spec/netsuite/records/custom_record_spec.rb +1 -1
- data/spec/netsuite/records/customer_credit_cards_list_spec.rb +23 -0
- data/spec/netsuite/records/customer_payment_credit_list_spec.rb +26 -0
- data/spec/netsuite/records/customer_payment_spec.rb +1 -6
- data/spec/netsuite/records/customer_spec.rb +22 -1
- data/spec/netsuite/records/employee_spec.rb +2 -2
- data/spec/netsuite/records/estimate_item_list_spec.rb +26 -0
- data/spec/netsuite/records/estimate_item_spec.rb +40 -0
- data/spec/netsuite/records/estimate_spec.rb +216 -0
- data/spec/netsuite/records/inventory_item_spec.rb +65 -0
- data/spec/netsuite/records/invoice_spec.rb +94 -0
- data/spec/netsuite/records/matrix_option_list_spec.rb +15 -5
- data/spec/netsuite/records/message_spec.rb +49 -0
- data/spec/netsuite/records/non_inventory_resale_item_spec.rb +165 -0
- data/spec/netsuite/records/non_inventory_sale_item_spec.rb +1 -1
- data/spec/netsuite/records/partner_spec.rb +143 -0
- data/spec/netsuite/records/service_resale_item_spec.rb +134 -0
- data/spec/netsuite/records/support_case_type_spec.rb +22 -0
- data/spec/netsuite/records/vendor_spec.rb +1 -1
- data/spec/netsuite/support/search_result_spec.rb +24 -0
- data/spec/netsuite/utilities_spec.rb +20 -15
- data/spec/support/fixtures/custom_fields/multi_select.xml +47 -0
- data/spec/support/fixtures/search/saved_search_item.xml +55 -0
- data/spec/support/fixtures/search/saved_search_joined_custom_customer.xml +15 -1
- data/spec/support/search_only_field_matcher.rb +7 -0
- metadata +77 -12
- data/circle.yml +0 -17
data/lib/netsuite/utilities.rb
CHANGED
@@ -78,7 +78,7 @@ module NetSuite
|
|
78
78
|
begin
|
79
79
|
count += 1
|
80
80
|
yield
|
81
|
-
rescue
|
81
|
+
rescue StandardError => e
|
82
82
|
exceptions_to_retry = [
|
83
83
|
Errno::ECONNRESET,
|
84
84
|
Errno::ETIMEDOUT,
|
@@ -115,6 +115,7 @@ module NetSuite
|
|
115
115
|
# https://github.com/stripe/stripe-netsuite/issues/815
|
116
116
|
if !e.message.include?("Only one request may be made against a session at a time") &&
|
117
117
|
!e.message.include?('java.util.ConcurrentModificationException') &&
|
118
|
+
!e.message.include?('java.lang.NullPointerException') &&
|
118
119
|
!e.message.include?('java.lang.IllegalStateException') &&
|
119
120
|
!e.message.include?('java.lang.reflect.InvocationTargetException') &&
|
120
121
|
!e.message.include?('com.netledger.common.exceptions.NLDatabaseOfflineException') &&
|
@@ -172,7 +173,9 @@ module NetSuite
|
|
172
173
|
ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::GiftCertificateItem, ns_item_internal_id, opts)
|
173
174
|
ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::KitItem, ns_item_internal_id, opts)
|
174
175
|
ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::SerializedInventoryItem, ns_item_internal_id, opts)
|
176
|
+
ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::SerializedAssemblyItem, ns_item_internal_id, opts)
|
175
177
|
ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::LotNumberedAssemblyItem, ns_item_internal_id, opts)
|
178
|
+
ns_item ||= NetSuite::Utilities.get_record(NetSuite::Records::LotNumberedInventoryItem, ns_item_internal_id, opts)
|
176
179
|
|
177
180
|
if ns_item.nil?
|
178
181
|
fail NetSuite::RecordNotFound, "item with ID #{ns_item_internal_id} not found"
|
@@ -277,16 +280,25 @@ module NetSuite
|
|
277
280
|
# NetSuite requires that the time be passed to the API with the PDT TZ offset
|
278
281
|
# of the time passed in (i.e. not the current TZ offset of PDT)
|
279
282
|
|
280
|
-
offset = Rational(-7, 24)
|
281
|
-
|
282
283
|
if defined?(TZInfo)
|
283
|
-
|
284
|
-
|
284
|
+
# if no version is defined, less than 2.0
|
285
|
+
# https://github.com/tzinfo/tzinfo/blob/master/CHANGES.md#added
|
286
|
+
if !defined?(TZInfo::VERSION)
|
287
|
+
# https://stackoverflow.com/questions/2927111/ruby-get-time-in-given-timezone
|
288
|
+
offset = TZInfo::Timezone.get("America/Los_Angeles").period_for_utc(time).utc_total_offset_rational
|
289
|
+
time = time.new_offset(offset)
|
290
|
+
else
|
291
|
+
time = TZInfo::Timezone.get("America/Los_Angeles").utc_to_local(time)
|
292
|
+
offset = time.offset
|
293
|
+
end
|
285
294
|
else
|
295
|
+
# if tzinfo is not installed, let's give it our best guess: -7
|
296
|
+
offset = Rational(-7, 24)
|
286
297
|
time = time.new_offset("-07:00")
|
287
298
|
end
|
288
299
|
|
289
|
-
(time + (offset * -1))
|
300
|
+
time = (time + (offset * -1))
|
301
|
+
time.iso8601
|
290
302
|
end
|
291
303
|
|
292
304
|
end
|
data/lib/netsuite/version.rb
CHANGED
data/netsuite.gemspec
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
require File.expand_path('../lib/netsuite/version', __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |gem|
|
5
|
+
gem.licenses = ['MIT']
|
5
6
|
gem.authors = ['Ryan Moran', 'Michael Bianco']
|
6
|
-
gem.email = ['ryan.moran@gmail.com', 'mike@
|
7
|
+
gem.email = ['ryan.moran@gmail.com', 'mike@mikebian.co']
|
7
8
|
gem.description = %q{NetSuite SuiteTalk API Wrapper}
|
8
9
|
gem.summary = %q{NetSuite SuiteTalk API (SOAP) Wrapper}
|
9
10
|
gem.homepage = 'https://github.com/NetSweet/netsuite'
|
@@ -15,7 +16,8 @@ Gem::Specification.new do |gem|
|
|
15
16
|
gem.require_paths = ['lib']
|
16
17
|
gem.version = NetSuite::VERSION
|
17
18
|
|
18
|
-
gem.add_dependency 'savon', '>= 2.3.0'
|
19
|
+
gem.add_dependency 'savon', '>= 2.3.0', '<= 2.11.1'
|
19
20
|
|
20
|
-
gem.add_development_dependency 'rspec', '~> 3.
|
21
|
+
gem.add_development_dependency 'rspec', '~> 3.10.0'
|
22
|
+
gem.add_development_dependency 'rake'
|
21
23
|
end
|
@@ -168,9 +168,31 @@ describe NetSuite::Actions::Search do
|
|
168
168
|
|
169
169
|
expect(search.results.size).to eq(2)
|
170
170
|
expect(search.current_page).to eq(1)
|
171
|
+
expect(search.results.first.internal_id).to eq('123')
|
172
|
+
expect(search.results.first.external_id).to eq('456')
|
171
173
|
expect(search.results.first.alt_name).to eq('A Awesome Name')
|
174
|
+
expect(search.results.first.custom_field_list.custitem_stringfield.value).to eq('sample string value')
|
175
|
+
expect(search.results.first.custom_field_list.custitem_apcategoryforsales.value.internal_id).to eq('4')
|
172
176
|
expect(search.results.last.email).to eq('alessawesome@gmail.com')
|
173
177
|
end
|
178
|
+
|
179
|
+
it "should handle an ID search with basic search only field result columns" do
|
180
|
+
response = File.read('spec/support/fixtures/search/saved_search_item.xml')
|
181
|
+
savon.expects(:search)
|
182
|
+
.with(message: {
|
183
|
+
"searchRecord"=>{
|
184
|
+
"@xsi:type" =>"listAcct:ItemSearchAdvanced",
|
185
|
+
"@savedSearchId" =>42,
|
186
|
+
:content! =>{"listAcct:criteria"=>{}},
|
187
|
+
}
|
188
|
+
}).returns(response)
|
189
|
+
|
190
|
+
search = NetSuite::Records::InventoryItem.search(saved: 42)
|
191
|
+
|
192
|
+
expect(search.results.first.location_quantity_available).to eq('3307.0')
|
193
|
+
expect(search.results.first.location_re_order_point).to eq('2565.0')
|
194
|
+
expect(search.results.first.location_quantity_on_order).to eq('40000.0')
|
195
|
+
end
|
174
196
|
end
|
175
197
|
|
176
198
|
context "advanced search" do
|
@@ -29,10 +29,12 @@ describe NetSuite::Configuration do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
describe '#connection' do
|
32
|
+
EXAMPLE_ENDPOINT = 'https://1023.suitetalk.api.netsuite.com/services/NetSuitePort_2020_2'
|
32
33
|
before(:each) do
|
33
34
|
# reset clears out the password info
|
34
35
|
config.email 'me@example.com'
|
35
36
|
config.password 'me@example.com'
|
37
|
+
config.endpoint EXAMPLE_ENDPOINT
|
36
38
|
config.account 1023
|
37
39
|
config.wsdl "my_wsdl"
|
38
40
|
config.api_version "2012_2"
|
@@ -57,6 +59,19 @@ describe NetSuite::Configuration do
|
|
57
59
|
|
58
60
|
expect(config).to have_received(:cached_wsdl)
|
59
61
|
end
|
62
|
+
|
63
|
+
it 'sets the endpoint on the Savon client' do
|
64
|
+
# this is ugly/brittle, but it's hard to see how else to test this
|
65
|
+
savon_configs = config.connection.globals.instance_eval {@options}
|
66
|
+
expect(savon_configs.fetch(:endpoint)).to eq(EXAMPLE_ENDPOINT)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'handles a nil endpoint' do
|
70
|
+
config.endpoint = nil
|
71
|
+
# this is ugly/brittle, but it's hard to see how else to test this
|
72
|
+
savon_configs = config.connection.globals.instance_eval {@options}
|
73
|
+
expect(savon_configs.fetch(:endpoint)).to eq(nil)
|
74
|
+
end
|
60
75
|
end
|
61
76
|
|
62
77
|
describe '#wsdl' do
|
@@ -166,6 +181,23 @@ describe NetSuite::Configuration do
|
|
166
181
|
end
|
167
182
|
end
|
168
183
|
|
184
|
+
describe '#endpoint' do
|
185
|
+
it 'can be set with endpoint=' do
|
186
|
+
config.endpoint = 42
|
187
|
+
expect(config.endpoint).to eq(42)
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'can be set with just endpoint(value)' do
|
191
|
+
config.endpoint(42)
|
192
|
+
expect(config.endpoint).to eq(42)
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'supports nil endpoints' do
|
196
|
+
config.endpoint = nil
|
197
|
+
expect(config.endpoint).to eq(nil)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
169
201
|
describe '#auth_header' do
|
170
202
|
context 'when doing user authentication' do
|
171
203
|
before do
|
@@ -326,15 +358,11 @@ describe NetSuite::Configuration do
|
|
326
358
|
|
327
359
|
describe "#credentials" do
|
328
360
|
context "when none are defined" do
|
329
|
-
skip "should properly create the auth credentials"
|
330
|
-
|
331
|
-
end
|
361
|
+
skip "should properly create the auth credentials"
|
332
362
|
end
|
333
363
|
|
334
364
|
context "when they are defined" do
|
335
|
-
|
336
|
-
|
337
|
-
end
|
365
|
+
skip "should properly replace the default auth credentials"
|
338
366
|
end
|
339
367
|
end
|
340
368
|
|
@@ -371,4 +399,81 @@ describe NetSuite::Configuration do
|
|
371
399
|
end
|
372
400
|
end
|
373
401
|
|
402
|
+
describe "#log" do
|
403
|
+
it 'allows a file path to be set as the log destination' do
|
404
|
+
file_path = Tempfile.new('tmplog').path
|
405
|
+
config.log = file_path
|
406
|
+
config.logger.info "foo"
|
407
|
+
|
408
|
+
log_contents = open(file_path).read
|
409
|
+
expect(log_contents).to include("foo")
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'allows an IO device to bet set as the log destination' do
|
413
|
+
stream = StringIO.new
|
414
|
+
config.log = stream
|
415
|
+
config.logger.info "foo"
|
416
|
+
|
417
|
+
expect(stream.string).to include("foo")
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
describe '#log_level' do
|
422
|
+
it 'defaults to :debug' do
|
423
|
+
expect(config.log_level).to eq(:debug)
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'can be initially set to any log level' do
|
427
|
+
config.log_level(:info)
|
428
|
+
|
429
|
+
expect(config.log_level).to eq(:info)
|
430
|
+
end
|
431
|
+
|
432
|
+
it 'can override itself' do
|
433
|
+
config.log_level = :info
|
434
|
+
|
435
|
+
expect(config.log_level).to eq(:info)
|
436
|
+
|
437
|
+
config.log_level(:debug)
|
438
|
+
|
439
|
+
expect(config.log_level).to eq(:debug)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
describe '#log_level=' do
|
444
|
+
it 'can set the initial log_level' do
|
445
|
+
config.log_level = :info
|
446
|
+
|
447
|
+
expect(config.log_level).to eq(:info)
|
448
|
+
end
|
449
|
+
|
450
|
+
it 'can override a previously set log level' do
|
451
|
+
config.log_level = :info
|
452
|
+
|
453
|
+
expect(config.log_level).to eq(:info)
|
454
|
+
|
455
|
+
config.log_level = :debug
|
456
|
+
|
457
|
+
expect(config.log_level).to eq(:debug)
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
describe 'timeouts' do
|
462
|
+
it 'has defaults' do
|
463
|
+
expect(config.read_timeout).to eql(60)
|
464
|
+
expect(config.open_timeout).to be_nil
|
465
|
+
end
|
466
|
+
|
467
|
+
it 'sets timeouts' do
|
468
|
+
config.read_timeout = 100
|
469
|
+
config.open_timeout = 60
|
470
|
+
|
471
|
+
expect(config.read_timeout).to eql(100)
|
472
|
+
expect(config.open_timeout).to eql(60)
|
473
|
+
|
474
|
+
# ensure no exception is raised
|
475
|
+
config.connection
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
374
479
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'basic records' do
|
4
|
+
# all records with internal IDs should be added to this list
|
4
5
|
let(:basic_record_list) {
|
5
6
|
[
|
6
7
|
NetSuite::Records::Currency,
|
@@ -25,6 +26,7 @@ describe 'basic records' do
|
|
25
26
|
NetSuite::Records::CustomerDeposit,
|
26
27
|
NetSuite::Records::NonInventoryPurchaseItem,
|
27
28
|
NetSuite::Records::NonInventoryResaleItem,
|
29
|
+
NetSuite::Records::LotNumberedInventoryItem,
|
28
30
|
NetSuite::Records::TaxGroup,
|
29
31
|
NetSuite::Records::Folder,
|
30
32
|
NetSuite::Records::CustomerCategory,
|
@@ -48,6 +50,7 @@ describe 'basic records' do
|
|
48
50
|
NetSuite::Records::SerializedInventoryItem,
|
49
51
|
NetSuite::Records::DepositApplication,
|
50
52
|
NetSuite::Records::InventoryAdjustment,
|
53
|
+
NetSuite::Records::Vendor,
|
51
54
|
NetSuite::Records::VendorReturnAuthorization,
|
52
55
|
NetSuite::Records::AssemblyBuild,
|
53
56
|
NetSuite::Records::AssemblyUnbuild,
|
@@ -60,6 +63,7 @@ describe 'basic records' do
|
|
60
63
|
NetSuite::Records::BinTransfer,
|
61
64
|
NetSuite::Records::SerializedAssemblyItem,
|
62
65
|
NetSuite::Records::CustomerStatus,
|
66
|
+
NetSuite::Records::CustomerPayment,
|
63
67
|
NetSuite::Records::TransactionBodyCustomField,
|
64
68
|
NetSuite::Records::TransactionColumnCustomField,
|
65
69
|
NetSuite::Records::EntityCustomField
|
@@ -107,8 +111,12 @@ describe 'basic records' do
|
|
107
111
|
|
108
112
|
if !sublist_fields.empty?
|
109
113
|
sublist_fields.each do |sublist_field|
|
114
|
+
sublist = record_instance.send(sublist_field)
|
115
|
+
|
110
116
|
# TODO make a sublist entry with some fields valid for that sublist item
|
111
|
-
|
117
|
+
sublist << {}
|
118
|
+
|
119
|
+
expect(sublist.send(sublist.sublist_key).count).to be(1)
|
112
120
|
end
|
113
121
|
end
|
114
122
|
|
@@ -5,12 +5,21 @@ describe NetSuite::Records::Classification do
|
|
5
5
|
|
6
6
|
it 'has all the right fields' do
|
7
7
|
[
|
8
|
-
:name, :include_children, :is_inactive, :class_translation_list
|
8
|
+
:name, :include_children, :is_inactive, :class_translation_list
|
9
9
|
].each do |field|
|
10
10
|
expect(classification).to have_field(field)
|
11
11
|
end
|
12
12
|
|
13
13
|
expect(classification.subsidiary_list.class).to eq(NetSuite::Records::RecordRefList)
|
14
|
+
expect(classification.custom_field_list.class).to eq(NetSuite::Records::CustomFieldList)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has all the right record refs' do
|
18
|
+
[
|
19
|
+
:parent
|
20
|
+
].each do |record_ref|
|
21
|
+
expect(classification).to have_record_ref(record_ref)
|
22
|
+
end
|
14
23
|
end
|
15
24
|
|
16
25
|
describe '.get' do
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NetSuite::Records::CostCategory do
|
4
|
+
let(:cost_category) { described_class.new }
|
5
|
+
|
6
|
+
it 'has all the right fields' do
|
7
|
+
[
|
8
|
+
:is_inactive,
|
9
|
+
:item_cost_type,
|
10
|
+
:name,
|
11
|
+
].each do |field|
|
12
|
+
expect(cost_category).to have_field(field)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'has all the right record refs' do
|
17
|
+
[
|
18
|
+
:account,
|
19
|
+
].each do |record_ref|
|
20
|
+
expect(cost_category).to have_record_ref(record_ref)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '.get' do
|
25
|
+
context 'when the response is successful' do
|
26
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :name => 'CostCategory 1' }) }
|
27
|
+
|
28
|
+
it 'returns a CostCategory instance populated with the data from the response object' do
|
29
|
+
expect(NetSuite::Actions::Get).to receive(:call).with([described_class, {:external_id => 1}], {}).and_return(response)
|
30
|
+
cost_category = described_class.get(:external_id => 1)
|
31
|
+
expect(cost_category).to be_kind_of(described_class)
|
32
|
+
expect(cost_category.name).to eql('CostCategory 1')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the response is unsuccessful' do
|
37
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
38
|
+
|
39
|
+
it 'raises a RecordNotFound exception' do
|
40
|
+
expect(NetSuite::Actions::Get).to receive(:call).with([described_class, {:external_id => 1}], {}).and_return(response)
|
41
|
+
expect {
|
42
|
+
described_class.get(:external_id => 1)
|
43
|
+
}.to raise_error(NetSuite::RecordNotFound,
|
44
|
+
/NetSuite::Records::CostCategory with OPTIONS=(.*) could not be found/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#add' do
|
50
|
+
let(:test_data) { { :name => 'Test CostCategory' } }
|
51
|
+
|
52
|
+
context 'when the response is successful' do
|
53
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
54
|
+
|
55
|
+
it 'returns true' do
|
56
|
+
cost_category = described_class.new(test_data)
|
57
|
+
expect(NetSuite::Actions::Add).to receive(:call).
|
58
|
+
with([cost_category], {}).
|
59
|
+
and_return(response)
|
60
|
+
expect(cost_category.add).to be_truthy
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when the response is unsuccessful' do
|
65
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
66
|
+
|
67
|
+
it 'returns false' do
|
68
|
+
cost_category = described_class.new(test_data)
|
69
|
+
expect(NetSuite::Actions::Add).to receive(:call).
|
70
|
+
with([cost_category], {}).
|
71
|
+
and_return(response)
|
72
|
+
expect(cost_category.add).to be_falsey
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#delete' do
|
78
|
+
let(:test_data) { { :internal_id => '1' } }
|
79
|
+
|
80
|
+
context 'when the response is successful' do
|
81
|
+
let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
|
82
|
+
|
83
|
+
it 'returns true' do
|
84
|
+
cost_category = described_class.new(test_data)
|
85
|
+
expect(NetSuite::Actions::Delete).to receive(:call).
|
86
|
+
with([cost_category], {}).
|
87
|
+
and_return(response)
|
88
|
+
expect(cost_category.delete).to be_truthy
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when the response is unsuccessful' do
|
93
|
+
let(:response) { NetSuite::Response.new(:success => false, :body => {}) }
|
94
|
+
|
95
|
+
it 'returns false' do
|
96
|
+
cost_category = described_class.new(test_data)
|
97
|
+
expect(NetSuite::Actions::Delete).to receive(:call).
|
98
|
+
with([cost_category], {}).
|
99
|
+
and_return(response)
|
100
|
+
expect(cost_category.delete).to be_falsey
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|