netsuite 0.5.7 → 0.5.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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NDQwMWNkMzVjNmRhNGMxODE4MTdkODQyMmQ4OWNlYTFjNzNiZDA0Nw==
5
- data.tar.gz: !binary |-
6
- YWMzMjc0NTgwYWQ1MzY2NDExMWI4YmVhYjE0NTNkOGIzZWRmNjJiMA==
2
+ SHA1:
3
+ metadata.gz: 63eeb2f2515c54bab1663a2683ed3f234f978d44
4
+ data.tar.gz: 6aaf5ad5cb70cdfb433a4a9c6c9798f2cf6c29ba
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- OWM2NTA4ZjQ0ZjJlMjRlNWI0NmJjNjhlZjNiYjMwM2QxNTE3NmI5NTRiZjc2
10
- YTJiZWIxM2Q3NmEyMTU4M2YwNDFlYTgzNWU1ZjQ0ZDkzZWNkM2UzZjI1Yzc5
11
- OWY2ZDZlNTMxY2E2ZTZhMjRkMjQ5ZjEzNWY2YWI3MmJjY2VlNmM=
12
- data.tar.gz: !binary |-
13
- MmJlMjIxOWY4MDIyYzI4MTJmMjExYmFhYTU3MmIzZjc1NGYwOGZmZTU3NDdh
14
- YzU0OTM2NjFiZTU4Yzg2NmQ0ZjA4ZjlmZmY4ZWViYmY3NjU5ZTZlY2YzMmE1
15
- NTAyMWNiODM5ZDcyMmMyZjQ5NjY2YTIzYmI0YWU2MWRjOTc1Nzk=
6
+ metadata.gz: 16405b1ce41bc3b287eebfa347316998d66507bfa6b6dfa6c2bb0c7a9d6ef158adef44bd19ec229d235e7fb7abca7013369450c5c038fdc4b17392cc1c671893
7
+ data.tar.gz: 1b214d4f1f23e608920b6556f7440286db57fcf8925d0bf9f3af4dd1bf6b28f5a7839bb19c7fe4767b6c62c22b0dee5c4b0a2da3e2b9fc1b931a4dddc0f7e780
@@ -128,6 +128,7 @@ module NetSuite
128
128
  autoload :Duration, 'netsuite/records/duration'
129
129
  autoload :Employee, 'netsuite/records/employee'
130
130
  autoload :File, 'netsuite/records/file'
131
+ autoload :Folder, 'netsuite/records/folder'
131
132
  autoload :InventoryAssignment, 'netsuite/records/inventory_assignment'
132
133
  autoload :InventoryAssignmentList, 'netsuite/records/inventory_assignment_list'
133
134
  autoload :InventoryDetail, 'netsuite/records/inventory_detail'
@@ -206,6 +207,11 @@ module NetSuite
206
207
  autoload :WorkOrderItemList, 'netsuite/records/work_order_item_list'
207
208
  end
208
209
 
210
+ module Passports
211
+ autoload :User, 'netsuite/passports/user'
212
+ autoload :Token, 'netsuite/passports/token'
213
+ end
214
+
209
215
  def self.configure(&block)
210
216
  NetSuite::Configuration.instance_eval(&block)
211
217
  end
@@ -59,17 +59,19 @@ module NetSuite
59
59
  if wsdl
60
60
  self.wsdl = wsdl
61
61
  else
62
- if sandbox
63
- wsdl_path = "https://webservices.sandbox.netsuite.com/wsdl/v#{api_version}_0/netsuite.wsdl"
64
- else
65
- wsdl_path = File.expand_path("../../../wsdl/#{api_version}.wsdl", __FILE__)
62
+ attributes[:wsdl] ||= begin
63
+ if sandbox
64
+ "https://webservices.sandbox.netsuite.com/wsdl/v#{api_version}_0/netsuite.wsdl"
65
+ else
66
+ wsdl_path = File.expand_path("../../../wsdl/#{api_version}.wsdl", __FILE__)
67
+
68
+ unless File.exists? wsdl_path
69
+ wsdl_path = "https://#{wsdl_domain}/wsdl/v#{api_version}_0/netsuite.wsdl"
70
+ end
66
71
 
67
- unless File.exists? wsdl_path
68
- wsdl_path = "https://#{wsdl_domain}/wsdl/v#{api_version}_0/netsuite.wsdl"
72
+ wsdl_path
69
73
  end
70
74
  end
71
-
72
- attributes[:wsdl] ||= wsdl_path
73
75
  end
74
76
  end
75
77
 
@@ -103,14 +105,30 @@ module NetSuite
103
105
  end
104
106
 
105
107
  def auth_header(credentials={})
106
- {
107
- 'platformMsgs:passport' => {
108
- 'platformCore:email' => credentials[:email] || email,
109
- 'platformCore:password' => credentials[:password] || password,
110
- 'platformCore:account' => credentials[:account] || account.to_s,
111
- 'platformCore:role' => { :@internalId => credentials[:role] || role }
112
- }
113
- }
108
+ if !credentials[:consumer_key].blank? || !consumer_key.blank?
109
+ token_auth(credentials)
110
+ else
111
+ user_auth(credentials)
112
+ end
113
+ end
114
+
115
+ def user_auth(credentials)
116
+ NetSuite::Passports::User.new(
117
+ credentials[:account] || account,
118
+ credentials[:email] || email,
119
+ credentials[:password] || password,
120
+ credentials[:role] || role
121
+ ).passport
122
+ end
123
+
124
+ def token_auth(credentials)
125
+ NetSuite::Passports::Token.new(
126
+ credentials[:account] || account,
127
+ credentials[:consumer_key] || consumer_key,
128
+ credentials[:consumer_secret] || consumer_secret,
129
+ credentials[:token_id] || token_id,
130
+ credentials[:token_secret] || token_secret
131
+ ).passport
114
132
  end
115
133
 
116
134
  def namespaces
@@ -185,6 +203,54 @@ module NetSuite
185
203
  end
186
204
  end
187
205
 
206
+ def consumer_key=(consumer_key)
207
+ attributes[:consumer_key] = consumer_key
208
+ end
209
+
210
+ def consumer_key(consumer_key = nil)
211
+ if consumer_key
212
+ self.consumer_key = consumer_key
213
+ else
214
+ attributes[:consumer_key]
215
+ end
216
+ end
217
+
218
+ def consumer_secret=(consumer_secret)
219
+ attributes[:consumer_secret] = consumer_secret
220
+ end
221
+
222
+ def consumer_secret(consumer_secret = nil)
223
+ if consumer_secret
224
+ self.consumer_secret = consumer_secret
225
+ else
226
+ attributes[:consumer_secret]
227
+ end
228
+ end
229
+
230
+ def token_id=(token_id)
231
+ attributes[:token_id] = token_id
232
+ end
233
+
234
+ def token_id(token_id = nil)
235
+ if token_id
236
+ self.token_id = token_id
237
+ else
238
+ attributes[:token_id]
239
+ end
240
+ end
241
+
242
+ def token_secret=(token_secret)
243
+ attributes[:token_secret] = token_secret
244
+ end
245
+
246
+ def token_secret(token_secret = nil)
247
+ if token_secret
248
+ self.token_secret = token_secret
249
+ else
250
+ attributes[:token_secret]
251
+ end
252
+ end
253
+
188
254
  def read_timeout=(timeout)
189
255
  attributes[:read_timeout] = timeout
190
256
  end
@@ -0,0 +1,55 @@
1
+ module NetSuite
2
+ module Passports
3
+ class Token
4
+ attr_reader :account, :consumer_key, :consumer_secret, :token_id, :token_secret
5
+
6
+ def initialize(account, consumer_key, consumer_secret, token_id, token_secret)
7
+ @account = account.to_s
8
+ @consumer_key = consumer_key
9
+ @consumer_secret = consumer_secret
10
+ @token_id = token_id
11
+ @token_secret = token_secret
12
+ end
13
+
14
+ def passport
15
+ {
16
+ 'platformMsgs:tokenPassport' => {
17
+ 'platformCore:account' => account,
18
+ 'platformCore:consumerKey' => consumer_key,
19
+ 'platformCore:token' => token_id,
20
+ 'platformCore:nonce' => nonce,
21
+ 'platformCore:timestamp' => timestamp,
22
+ 'platformCore:signature' => signature,
23
+ :attributes! => { 'platformCore:signature' => { 'algorithm' => 'HMAC-SHA256' } }
24
+ }
25
+ }
26
+ end
27
+
28
+ private
29
+
30
+ def signature
31
+ Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), signature_key, signature_data))
32
+ end
33
+
34
+ def signature_key
35
+ "#{consumer_secret}&#{token_secret}"
36
+ end
37
+
38
+ def signature_data
39
+ "#{account}&#{consumer_key}&#{token_id}&#{nonce}&#{timestamp}"
40
+ end
41
+
42
+ def nonce
43
+ @nonce ||= Array.new(20) { alphanumerics.sample }.join
44
+ end
45
+
46
+ def alphanumerics
47
+ [*'0'..'9',*'A'..'Z',*'a'..'z']
48
+ end
49
+
50
+ def timestamp
51
+ @timestamp ||= Time.now.to_i
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,25 @@
1
+ module NetSuite
2
+ module Passports
3
+ class User
4
+ attr_reader :account, :email, :password, :role
5
+
6
+ def initialize(account, email, password, role)
7
+ @account = account.to_s
8
+ @email = email
9
+ @password = password
10
+ @role = role
11
+ end
12
+
13
+ def passport
14
+ {
15
+ 'platformMsgs:passport' => {
16
+ 'platformCore:account' => account,
17
+ 'platformCore:email' => email,
18
+ 'platformCore:password' => password,
19
+ 'platformCore:role' => { :@internalId => role }
20
+ }
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -11,7 +11,7 @@ module NetSuite
11
11
 
12
12
  fields :content, :description, :name, :media_type_name, :file_type, :text_file_encoding
13
13
 
14
- record_refs :klass
14
+ record_refs :folder, :klass
15
15
 
16
16
  read_only_fields :url
17
17
 
@@ -0,0 +1,26 @@
1
+ module NetSuite
2
+ module Records
3
+ class Folder
4
+ include Support::Fields
5
+ include Support::RecordRefs
6
+ include Support::Records
7
+ include Support::Actions
8
+ include Namespaces::FileCabinet
9
+
10
+ actions :add
11
+
12
+ fields :name
13
+
14
+ record_refs :parent
15
+
16
+ attr_reader :internal_id
17
+ attr_accessor :external_id
18
+
19
+ def initialize(attributes = {})
20
+ @internal_id = attributes.delete(:internal_id) || attributes.delete(:@internal_id)
21
+ @external_id = attributes.delete(:external_id) || attributes.delete(:@external_id)
22
+ initialize_from_attributes_hash(attributes)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -261,6 +261,12 @@ module NetSuite
261
261
  end
262
262
  end
263
263
 
264
+ def ==(other)
265
+ other.class == self.class && other.to_iso == self.to_iso
266
+ end
267
+
268
+ alias :eql? :==
269
+
264
270
  def to_iso
265
271
  ISO_TO_NETSUITE.key(@id)
266
272
  end
@@ -1,3 +1,3 @@
1
1
  module Netsuite
2
- VERSION = '0.5.7'
2
+ VERSION = '0.5.8'
3
3
  end
@@ -64,21 +64,48 @@ describe NetSuite::Configuration do
64
64
  end
65
65
 
66
66
  describe '#auth_header' do
67
- before do
68
- config.email = 'user@example.com'
69
- config.password = 'myPassword'
70
- config.account = 1234
67
+ context 'when doing user authentication' do
68
+ before do
69
+ config.account = 1234
70
+ config.email = 'user@example.com'
71
+ config.password = 'myPassword'
72
+ end
73
+
74
+ it 'returns a hash representation of the authentication header' do
75
+ expect(config.auth_header).to eql({
76
+ 'platformMsgs:passport' => {
77
+ 'platformCore:account' => '1234',
78
+ 'platformCore:email' => 'user@example.com',
79
+ 'platformCore:password' => 'myPassword',
80
+ 'platformCore:role' => { :@internalId => '3' },
81
+ }
82
+ })
83
+ end
71
84
  end
72
85
 
73
- it 'returns a hash representation of the authentication header' do
74
- expect(config.auth_header).to eql({
75
- 'platformMsgs:passport' => {
76
- 'platformCore:email' => 'user@example.com',
77
- 'platformCore:password' => 'myPassword',
78
- 'platformCore:account' => '1234',
79
- 'platformCore:role' => { :@internalId => '3' },
80
- }
81
- })
86
+ context 'when doing token authentication' do
87
+ before do
88
+ config.account = 1234
89
+ config.consumer_key = 'consumer_key'
90
+ config.consumer_secret = 'consumer_secret'
91
+ config.token_id = 'token_id'
92
+ config.token_secret = 'token_secret'
93
+ end
94
+
95
+ it 'returns tokenPassport object' do
96
+ expect(config.auth_header.has_key?('platformMsgs:tokenPassport')).to be_truthy
97
+ end
98
+
99
+ it 'returns proper elements of tokenPassport' do
100
+ expect(config.auth_header['platformMsgs:tokenPassport']['platformCore:account']).to eql('1234')
101
+ expect(config.auth_header['platformMsgs:tokenPassport']['platformCore:consumerKey']).to eql('consumer_key')
102
+ expect(config.auth_header['platformMsgs:tokenPassport']['platformCore:token']).to eql('token_id')
103
+ expect(config.auth_header['platformMsgs:tokenPassport'][:attributes!]).to eql({ 'platformCore:signature' => { 'algorithm' => 'HMAC-SHA256' } })
104
+
105
+ expect(config.auth_header['platformMsgs:tokenPassport'].has_key?('platformCore:nonce')).to be_truthy
106
+ expect(config.auth_header['platformMsgs:tokenPassport'].has_key?('platformCore:timestamp')).to be_truthy
107
+ expect(config.auth_header['platformMsgs:tokenPassport'].has_key?('platformCore:signature')).to be_truthy
108
+ end
82
109
  end
83
110
  end
84
111
 
@@ -16,7 +16,7 @@ describe NetSuite::Records::Address do
16
16
  :state => 'CA',
17
17
  :zip => '90007'
18
18
  }
19
- end
19
+ end
20
20
  let(:list) { NetSuite::Records::Address.new(attributes) }
21
21
 
22
22
  it 'has all the right fields' do
@@ -26,7 +26,7 @@ describe NetSuite::Records::Address do
26
26
  expect(list).to have_field(field)
27
27
  end
28
28
  end
29
-
29
+
30
30
  it 'has all the right read_only_fields' do
31
31
  [
32
32
  :addr_text
@@ -104,6 +104,13 @@ describe NetSuite::Records::Address do
104
104
  addressbook = NetSuite::Records::Address.new country: "US"
105
105
  expect(addressbook.to_record["platformCommon:country"]).to eql "_unitedStates"
106
106
  end
107
+
108
+ it 'properly evaluates equality against another country of the same ISO code' do
109
+ addressbook = NetSuite::Records::Address.new country: "US"
110
+ addressbook_2 = NetSuite::Records::Address.new country: "US"
111
+
112
+ expect(addressbook.country == addressbook_2.country).to eq(true)
113
+ end
107
114
  end
108
115
 
109
116
  context "when the country code is a YAML reserved word (NO)" do
@@ -22,6 +22,7 @@ describe 'basic records' do
22
22
  NetSuite::Records::NonInventoryPurchaseItem,
23
23
  NetSuite::Records::NonInventoryResaleItem,
24
24
  NetSuite::Records::TaxGroup,
25
+ NetSuite::Records::Folder,
25
26
  ]
26
27
  }
27
28
 
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::File do
4
+ let(:file) { NetSuite::Records::File.new }
5
+
6
+ it 'has all the right record refs' do
7
+ [:folder, :klass].each do |record_ref|
8
+ expect(file).to have_record_ref(record_ref)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe NetSuite::Records::Folder do
4
+ let(:folder) { NetSuite::Records::Folder.new }
5
+
6
+ it 'has all the right fields' do
7
+ [:name].each do |field|
8
+ expect(folder).to have_field(field)
9
+ end
10
+ end
11
+
12
+ it 'has all the right record refs' do
13
+ [:parent].each do |record_ref|
14
+ expect(folder).to have_record_ref(record_ref)
15
+ end
16
+ end
17
+
18
+ describe '#add' do
19
+ let(:test_data) { { :name => 'foo' } }
20
+
21
+ context 'when the response is successful' do
22
+ let(:response) { NetSuite::Response.new(:success => true, :body => { :internal_id => '1' }) }
23
+
24
+ it 'returns true' do
25
+ folder = NetSuite::Records::Folder.new(test_data)
26
+ expect(NetSuite::Actions::Add).to receive(:call).
27
+ with([folder], {}).
28
+ and_return(response)
29
+ expect(folder.add).to be_truthy
30
+ end
31
+ end
32
+ end
33
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: netsuite
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.7
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Moran
@@ -9,34 +9,34 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-02-11 00:00:00.000000000 Z
12
+ date: 2016-04-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: savon
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ! '>='
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: 2.3.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ! '>='
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: 2.3.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rspec
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ~>
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
34
  version: 3.1.0
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ~>
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
41
  version: 3.1.0
42
42
  description: NetSuite SuiteTalk API Wrapper
@@ -47,8 +47,8 @@ executables: []
47
47
  extensions: []
48
48
  extra_rdoc_files: []
49
49
  files:
50
- - .gitignore
51
- - .rspec
50
+ - ".gitignore"
51
+ - ".rspec"
52
52
  - Gemfile
53
53
  - LICENSE
54
54
  - README.md
@@ -89,6 +89,8 @@ files:
89
89
  - lib/netsuite/namespaces/tran_invt.rb
90
90
  - lib/netsuite/namespaces/tran_purch.rb
91
91
  - lib/netsuite/namespaces/tran_sales.rb
92
+ - lib/netsuite/passports/token.rb
93
+ - lib/netsuite/passports/user.rb
92
94
  - lib/netsuite/records/account.rb
93
95
  - lib/netsuite/records/accounting_period.rb
94
96
  - lib/netsuite/records/address.rb
@@ -157,6 +159,7 @@ files:
157
159
  - lib/netsuite/records/duration.rb
158
160
  - lib/netsuite/records/employee.rb
159
161
  - lib/netsuite/records/file.rb
162
+ - lib/netsuite/records/folder.rb
160
163
  - lib/netsuite/records/inventory_assignment.rb
161
164
  - lib/netsuite/records/inventory_assignment_list.rb
162
165
  - lib/netsuite/records/inventory_detail.rb
@@ -305,6 +308,8 @@ files:
305
308
  - spec/netsuite/records/discount_item_spec.rb
306
309
  - spec/netsuite/records/duration_spec.rb
307
310
  - spec/netsuite/records/employee_spec.rb
311
+ - spec/netsuite/records/file_spec.rb
312
+ - spec/netsuite/records/folder_spec.rb
308
313
  - spec/netsuite/records/inventory_assignment_list_spec.rb
309
314
  - spec/netsuite/records/inventory_assignment_spec.rb
310
315
  - spec/netsuite/records/inventory_detail_spec.rb
@@ -405,17 +410,17 @@ require_paths:
405
410
  - lib
406
411
  required_ruby_version: !ruby/object:Gem::Requirement
407
412
  requirements:
408
- - - ! '>='
413
+ - - ">="
409
414
  - !ruby/object:Gem::Version
410
415
  version: '0'
411
416
  required_rubygems_version: !ruby/object:Gem::Requirement
412
417
  requirements:
413
- - - ! '>='
418
+ - - ">="
414
419
  - !ruby/object:Gem::Version
415
420
  version: '0'
416
421
  requirements: []
417
422
  rubyforge_project:
418
- rubygems_version: 2.4.6
423
+ rubygems_version: 2.5.1
419
424
  signing_key:
420
425
  specification_version: 4
421
426
  summary: NetSuite SuiteTalk API (SOAP) Wrapper
@@ -479,6 +484,8 @@ test_files:
479
484
  - spec/netsuite/records/discount_item_spec.rb
480
485
  - spec/netsuite/records/duration_spec.rb
481
486
  - spec/netsuite/records/employee_spec.rb
487
+ - spec/netsuite/records/file_spec.rb
488
+ - spec/netsuite/records/folder_spec.rb
482
489
  - spec/netsuite/records/inventory_assignment_list_spec.rb
483
490
  - spec/netsuite/records/inventory_assignment_spec.rb
484
491
  - spec/netsuite/records/inventory_detail_spec.rb