suite_rest 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTFjZDEzODNjM2I5OTMwNDg2NTlmMTE1NWEzZmIyNmQ0N2Q2NjllMg==
5
+ data.tar.gz: !binary |-
6
+ MjUxNTAwZjdiZDFkODIyZTQ3ZmJmMDc3NTRiNDg1NGY1MTZmNzAyMw==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjEzNmUzNTJjZjJmNWJlODRlOGIxZWE4ZmE2NmQxYzRhZjExMzlhODY2MDVm
10
+ ZDM4ZDcyY2IyMmE0NTdiM2VhZjk5Zjc1ZGVlMGM4NDYzNWFlZWUyNjdkYTFh
11
+ ZDA5MzRkOWJhOWY3ZTg2ODBiMWFjMTgxNmRlYzI3YzAyNzlhNzc=
12
+ data.tar.gz: !binary |-
13
+ ZjY1NWE5MjkyMzRjMmZkN2MzYWFkMjA4MjQxM2M2NzRhZTE5ODgxN2E2YTg0
14
+ ZTUxYWJkMjg3ZmFkYzY4OTIyYjVjYWNhNzNlYTgyMzJmNGJhM2E0ZDJjZTJh
15
+ NDU0ODE5NTVhYzFkZTA3M2I1N2Q1MTYxMjhjM2U5NTE0ZmQ3YmU=
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in suite_rest.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ben DiFrancesco
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,109 @@
1
+ # SuiteRest
2
+
3
+ A gem to simplify interaction with NetSuite RESTlets. You will find SuiteRest useful if:
4
+
5
+ 1. You have already created (or are developing) a RESTlet in NetSuite
6
+ 2. You want to interact with that RESTlet in a Ruby environment
7
+
8
+ SuiteRest makes it easy to configure NetSuite authentication, define the RESTlet you want to interact with, call that RESTlet, and receive return values. It reduces the boilerplate and allows for cleaner code.
9
+
10
+ ## Installation
11
+
12
+ SuiteRest is available on RubyGems and can be installed as such:
13
+
14
+ $ gem install suite_rest
15
+
16
+ Or add this line to your application's Gemfile:
17
+
18
+ gem 'suite_rest'
19
+
20
+
21
+ ## Usage
22
+
23
+ ### Configuration
24
+
25
+ Configure SuiteRest with your account information. The configuration block is global and needs only be done once per session.
26
+
27
+ ```Ruby
28
+ SuiteRest.configure do |config|
29
+ config.account = 123456
30
+ config.email = "email@mail.com"
31
+ config.role = 1010
32
+ config.signature = "password"
33
+ end
34
+ ```
35
+
36
+
37
+ ### Example
38
+
39
+ Let's assume you have a NetSuite RESTlet deployed with the following function bound to `GET`:
40
+
41
+ ```JavaScript
42
+ function getTest(datain) {
43
+ if(datain.worldDescription) {
44
+ return("Hello " + datain.worldDescription + " World");
45
+ } else {
46
+ return("Hello World");
47
+ }
48
+ }
49
+ ```
50
+
51
+ Each RESTlet is defined by an **instance** of a `SuiteRest::RestService` object. Initialize the instance with the definition of the service.
52
+
53
+ ```Ruby
54
+ get_world = SuiteRest::RestService.new( :type => :get,
55
+ :script_id => 27,
56
+ :deploy_id => 1,
57
+ :args_def => [:world_description] )
58
+ ```
59
+
60
+ Now simply `call` this service and get back a response:
61
+
62
+ ```Ruby
63
+ get_world.call(:world_description => "Big") # "Hello Big World"
64
+ ```
65
+
66
+ Valid values for `:type` are the REST-ful services supported by NetSuite RESTlets:
67
+
68
+ * `:get`
69
+ * `:put`
70
+ * `:post`
71
+ * `:delete`
72
+
73
+ Values for `:script_id` and `:deploy_id` are defined on your Script Deployment record in NetSuite.
74
+
75
+ An array of all argument names you will send to your RESTlet should be included in `:args_def`. Note that SuiteRest automatically camelizes your parameter names so you can write idiomatic JavaScript in your RESTlet and idiomatic Ruby in your Ruby app. SuiteRest assumes this convention and could break if you use non-idiomatic names.
76
+
77
+ SuiteRest **only** manages case of parameters defined in `:args_def`. Keys in hashes, for example, will be converted to JSON and sent as-is to your RESTlet. For example the following Ruby hash…
78
+
79
+ ```Ruby
80
+ some_data = {
81
+ :a => "Hello",
82
+ :b_key => "World",
83
+ "string_key" => :symbol_val
84
+ }
85
+ ```
86
+
87
+ …if passed in a argument to a RESTlet would appear as such in your JavaScript:
88
+
89
+ ```JavaScript
90
+ // datain.someData
91
+ {
92
+ "a": "Hello",
93
+ "b_key": "World",
94
+ "string_key": "symbol_val"
95
+ }
96
+ ```
97
+
98
+ To call the service with other args you should define a new service:
99
+
100
+ ```Ruby
101
+ get_world_no_args = SuiteRest::RestService.new( :type => :get,
102
+ :script_id => 27,
103
+ :deploy_id => 1 )
104
+ get_world_no_args.call # "Hello World"
105
+ ```
106
+
107
+ ## Contributing
108
+
109
+ SuiteRest is a simple Gem, but it is version 0.1.0 software so be sure to test extensively before deploying. If you find a bug, please submit an issue or pull request and I'll happily fix the issue.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,37 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ require "suite_rest/version"
6
+ require "suite_rest/rest_service_utils"
7
+ require "suite_rest/rest_service"
8
+
9
+ module SuiteRest
10
+ class << self
11
+ attr_accessor :configuration
12
+ end
13
+
14
+ def self.configure
15
+ self.configuration ||= Configuration.new
16
+ yield(configuration)
17
+ end
18
+
19
+ def self.reset!
20
+ self.configuration = Configuration.new
21
+ end
22
+
23
+ class Configuration
24
+ attr_accessor :account, :sandbox, :email, :role, :signature
25
+
26
+ def initialize
27
+ @sandbox = true # safe default
28
+ end
29
+
30
+ def auth_string
31
+ "NLAuth nlauth_account=" + @account.to_s + \
32
+ ", nlauth_email=" + @email.to_s + \
33
+ ", nlauth_signature=" + @signature.to_s + \
34
+ ", nlauth_role=" + @role.to_s
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,76 @@
1
+ module SuiteRest
2
+ class RestService
3
+
4
+ extend SuiteRest::RestServiceUtils
5
+ attr_accessor :type, :script_id, :deploy_id, :args_def
6
+
7
+ def initialize(service_def)
8
+ @type = service_def[:type]
9
+ @script_id = service_def[:script_id]
10
+ @deploy_id = service_def[:deploy_id]
11
+ @args_def = service_def[:args_def] ? service_def[:args_def] : []
12
+ end
13
+
14
+ def get_or_delete(args={})
15
+ uri = self.class.parsed_uri(@script_id, @deploy_id,
16
+ SuiteRest.configuration.sandbox, self.class.urlify(args, @args_def))
17
+ http = self.class.http(uri)
18
+
19
+ case @type
20
+ when :get
21
+ request = Net::HTTP::Get.new(uri.request_uri)
22
+ when :delete
23
+ request = Net::HTTP::Delete.new(uri.request_uri)
24
+ end
25
+
26
+ self.class.add_request_fields(request, SuiteRest.configuration.auth_string)
27
+ response = self.class.check_response(http.request(request))
28
+
29
+ # By NS definition, delete restlets should not return anything, so we'll
30
+ # return true/false based on server response
31
+ if @type == :delete
32
+ true
33
+ else
34
+ self.class.parse_body(response.body)
35
+ end
36
+ end
37
+
38
+ def post_or_put(args={})
39
+ uri = self.class.parsed_uri(@script_id, @deploy_id, SuiteRest.configuration.sandbox)
40
+ http = self.class.http(uri)
41
+
42
+ case @type
43
+ when :put
44
+ request = Net::HTTP::Put.new(uri.request_uri)
45
+ when :post
46
+ request = Net::HTTP::Post.new(uri.request_uri)
47
+ end
48
+
49
+ self.class.add_request_fields(request, SuiteRest.configuration.auth_string)
50
+ request.body = self.class.payloadify(args, @args_def)
51
+ response = self.class.check_response(http.request(request))
52
+
53
+ self.class.parse_body(response.body)
54
+ end
55
+
56
+ alias_method :put, :post_or_put
57
+ alias_method :post, :post_or_put
58
+ alias_method :get, :get_or_delete
59
+ alias_method :delete, :get_or_delete
60
+
61
+ def call(args={})
62
+ case @type
63
+ when :put
64
+ self.put(args)
65
+ when :post
66
+ self.post(args)
67
+ when :get
68
+ self.get(args)
69
+ when :delete
70
+ self.delete(args)
71
+ else
72
+ raise "Invalid Service Type :#{@type}, use :get, :put, :post, or :delete"
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,83 @@
1
+ module SuiteRest
2
+ module RestServiceUtils
3
+ extend self
4
+
5
+ def service_uri(script_id, deploy_id, is_sandbox)
6
+ if is_sandbox
7
+ "https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl?script=#{script_id}&deploy=#{deploy_id}"
8
+ else
9
+ "https://rest.netsuite.com/app/site/hosting/restlet.nl?script=#{script_id}&deploy=#{deploy_id}"
10
+ end
11
+ end
12
+
13
+ def parsed_uri(script_id, deploy_id, is_sandbox, args="")
14
+ URI.parse(self.service_uri(script_id, deploy_id, is_sandbox) + URI.escape(args))
15
+ end
16
+
17
+ def http(parsed_uri)
18
+ http = Net::HTTP.new(parsed_uri.host, parsed_uri.port)
19
+ http.use_ssl = true
20
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
21
+ http
22
+ end
23
+
24
+ def camel_case_lower(a_string)
25
+ a_string.split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
26
+ end
27
+
28
+ def add_request_fields(request, auth_string)
29
+ request.add_field("Authorization", auth_string)
30
+ request.add_field("Content-Type", "application/json")
31
+ #request.add_field("Content-Type", "text/plain") should this be an init option?
32
+ end
33
+
34
+ def urlify(args, args_def)
35
+ url_string = ""
36
+ args_def.each do |arg_def|
37
+ url_string = "#{url_string}&#{self.camel_case_lower(arg_def.to_s)}=#{args[arg_def]}"
38
+ end
39
+ url_string
40
+ end
41
+
42
+ def payloadify(args, args_def)
43
+ payload = {}
44
+ args_def.each do |arg_def|
45
+ payload[self.camel_case_lower(arg_def.to_s)] = args[arg_def]
46
+ end
47
+ payload.to_json
48
+ end
49
+
50
+ def check_response(http_response)
51
+ if http_response.code == "200"
52
+ return http_response
53
+ else
54
+ raise "Error Code #{http_response.code}: #{http_response.msg}"
55
+ end
56
+ end
57
+
58
+ def parse_body(body)
59
+ begin
60
+ JSON.parse(body)
61
+ rescue JSON::ParserError
62
+ string_body = body.gsub(/"/, '')
63
+
64
+ if string_body == string_body.to_i.to_s
65
+ return string_body.to_i
66
+ elsif string_body == string_body.to_f.to_s
67
+ return string_body.to_f
68
+ elsif string_body == 'null'
69
+ return nil
70
+ elsif string_body.start_with?("org.mozilla.javascript.Undefined")
71
+ return nil
72
+ elsif string_body == 'false'
73
+ return false
74
+ elsif string_body == 'true'
75
+ return true
76
+ else
77
+ return string_body
78
+ end
79
+ end
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,3 @@
1
+ module SuiteRest
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,21 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+
8
+ require 'pry-debugger'
9
+ require 'suite_rest'
10
+
11
+ RSpec.configure do |config|
12
+ config.treat_symbols_as_metadata_keys_with_true_values = true
13
+ config.run_all_when_everything_filtered = true
14
+ config.filter_run :focus
15
+
16
+ # Run specs in random order to surface order dependencies. If you find an
17
+ # order dependency and want to debug it, you can fix the order by providing
18
+ # the seed, which is printed after each run.
19
+ # --seed 1234
20
+ config.order = 'random'
21
+ end
@@ -0,0 +1,165 @@
1
+ require 'spec_helper'
2
+
3
+ describe SuiteRest::RestService do
4
+ context "creating a standard RestService" do
5
+ let(:account) { 12345 }
6
+ let(:email) { "fake@gmail.com" }
7
+ let(:role) { 1001 }
8
+ let(:signature) { "asdfji2435;'!"}
9
+
10
+ let(:script_id) { 29 }
11
+ let(:deploy_id) { 1 }
12
+ let(:args_def) { [:trans_id, :trans_type] }
13
+ let(:payload_args) do
14
+ {
15
+ 'transId' => 45334,
16
+ 'transType' => 'invoice'
17
+ }.to_json
18
+ end
19
+ let(:call_args) do
20
+ {
21
+ :trans_id => 45334,
22
+ :trans_type => 'invoice'
23
+ }
24
+ end
25
+
26
+ before(:each) do
27
+ SuiteRest.reset!
28
+ SuiteRest.configure do |config|
29
+ config.account = account
30
+ config.email = email
31
+ config.role = role
32
+ config.signature = signature
33
+ end
34
+
35
+ @get_svc = SuiteRest::RestService.new(
36
+ :type => :get,
37
+ :script_id => script_id,
38
+ :deploy_id => deploy_id,
39
+ :args_def => args_def
40
+ )
41
+
42
+ @put_svc = SuiteRest::RestService.new(
43
+ :type => :put,
44
+ :script_id => script_id,
45
+ :deploy_id => deploy_id,
46
+ :args_def => args_def
47
+ )
48
+
49
+ @delete_svc = SuiteRest::RestService.new(
50
+ :type => :delete,
51
+ :script_id => script_id,
52
+ :deploy_id => deploy_id,
53
+ :args_def => args_def
54
+ )
55
+
56
+ @post_svc = SuiteRest::RestService.new(
57
+ :type => :post,
58
+ :script_id => script_id,
59
+ :deploy_id => deploy_id,
60
+ :args_def => args_def
61
+ )
62
+
63
+ @http = double(Net::HTTP, :use_ssl= => nil, :verify_mode= => nil, :request => double(Net::HTTPOK, :code => "200", :body => "body"))
64
+ @http_get = double(Net::HTTP::Get, :add_field => nil)
65
+ @http_post = double(Net::HTTP::Post, :add_field => nil)
66
+ @http_put = double(Net::HTTP::Put, :add_field => nil)
67
+ @http_delete = double(Net::HTTP::Delete, :add_field => nil)
68
+ end
69
+
70
+ it "should retain each service definition arguments" do
71
+ @get_svc.type.should eq(:get)
72
+ @get_svc.script_id.should eq(script_id)
73
+ @get_svc.deploy_id.should eq(deploy_id)
74
+ @get_svc.args_def.should eq(args_def)
75
+
76
+ @put_svc.type.should eq(:put)
77
+ @put_svc.script_id.should eq(script_id)
78
+ @put_svc.deploy_id.should eq(deploy_id)
79
+ @put_svc.args_def.should eq(args_def)
80
+
81
+ @delete_svc.type.should eq(:delete)
82
+ @delete_svc.script_id.should eq(script_id)
83
+ @delete_svc.deploy_id.should eq(deploy_id)
84
+ @delete_svc.args_def.should eq(args_def)
85
+
86
+ @post_svc.type.should eq(:post)
87
+ @post_svc.script_id.should eq(script_id)
88
+ @post_svc.deploy_id.should eq(deploy_id)
89
+ @post_svc.args_def.should eq(args_def)
90
+ end
91
+
92
+ context "when args_def is not defined" do
93
+ let(:args_def) { nil }
94
+
95
+ it "should default to empty array args_def" do
96
+ @get_svc.args_def.should eq([])
97
+ @put_svc.args_def.should eq([])
98
+ @delete_svc.args_def.should eq([])
99
+ @post_svc.args_def.should eq([])
100
+ end
101
+ end
102
+
103
+ it "should call get for a get service" do
104
+ @get_svc.should_receive(:get).with(call_args)
105
+ @get_svc.call(call_args)
106
+ end
107
+
108
+ it "should call put for a put service" do
109
+ @put_svc.should_receive(:put).with(call_args)
110
+ @put_svc.call(call_args)
111
+ end
112
+
113
+ it "should call delete for a delete service" do
114
+ @delete_svc.should_receive(:delete).with(call_args)
115
+ @delete_svc.call(call_args)
116
+ end
117
+
118
+ it "should call post for a post service" do
119
+ @post_svc.should_receive(:post).with(call_args)
120
+ @post_svc.call(call_args)
121
+ end
122
+
123
+ it "should build and execute a get request" do
124
+ SuiteRest::RestService.should_receive(:http).and_return(@http)
125
+ Net::HTTP::Get.should_receive(:new).and_return(@http_get)
126
+ @http.should_receive(:request).with(@http_get)
127
+ SuiteRest::RestService.should_receive(:parse_body).with("body")
128
+
129
+ @get_svc.get(call_args)
130
+ end
131
+
132
+ it "should build and execute a put request" do
133
+ SuiteRest::RestService.should_receive(:http).and_return(@http)
134
+ Net::HTTP::Put.should_receive(:new).and_return(@http_put)
135
+ @http_put.should_receive(:body=).with(payload_args)
136
+ @http.should_receive(:request).with(@http_put)
137
+ SuiteRest::RestService.should_receive(:parse_body).with("body")
138
+
139
+ @put_svc.put(call_args)
140
+ end
141
+
142
+ it "should build and execute a delete request" do
143
+ SuiteRest::RestService.should_receive(:http).and_return(@http)
144
+ Net::HTTP::Delete.should_receive(:new).and_return(@http_delete)
145
+ @http.should_receive(:request).with(@http_delete)
146
+
147
+ @delete_svc.delete(call_args).should eq(true)
148
+ end
149
+
150
+ it "should build and execute a post request" do
151
+ SuiteRest::RestService.should_receive(:http).and_return(@http)
152
+ Net::HTTP::Post.should_receive(:new).and_return(@http_post)
153
+ @http_post.should_receive(:body=).with(payload_args)
154
+ @http.should_receive(:request).with(@http_post)
155
+ SuiteRest::RestService.should_receive(:parse_body).with("body")
156
+
157
+ @post_svc.post(call_args)
158
+ end
159
+
160
+ it "should throw an error for a bad type" do
161
+ @get_svc.type = :bad_type
162
+ expect{ @get_svc.call }.to raise_error(RuntimeError)
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ describe SuiteRest::RestServiceUtils do
4
+
5
+ context "when testing service_uri" do
6
+ context "when given valid arguments and sandbox" do
7
+ let(:script_id){ Random.rand(1..1000) }
8
+ let(:deploy_id){ Random.rand(1..1000) }
9
+ let(:is_sandbox){ true }
10
+
11
+ it "should return correct URI" do
12
+ uri = SuiteRest::RestServiceUtils.service_uri(script_id, deploy_id, is_sandbox)
13
+ uri.should eq("https://rest.sandbox.netsuite.com/app/site/hosting/restlet.nl?script=#{script_id}&deploy=#{deploy_id}")
14
+ end
15
+ end
16
+
17
+ context "when given valid arguments and production" do
18
+ let(:script_id){ Random.rand(1..1000) }
19
+ let(:deploy_id){ Random.rand(1..1000) }
20
+ let(:is_sandbox){ false }
21
+
22
+ it "should return correct URI" do
23
+ uri = SuiteRest::RestServiceUtils.service_uri(script_id, deploy_id, is_sandbox)
24
+ uri.should eq("https://rest.netsuite.com/app/site/hosting/restlet.nl?script=#{script_id}&deploy=#{deploy_id}")
25
+ end
26
+ end
27
+ end
28
+
29
+ context "when testing parsed_uri" do
30
+ context "when given valid input and arguments" do
31
+ let(:script_id){ Random.rand(1..1000) }
32
+ let(:deploy_id){ Random.rand(1..1000) }
33
+ let(:is_sandbox){ false }
34
+ let(:args) { "&transId=45334&transType=invoice"}
35
+
36
+ it "should properly parse the URI" do
37
+ SuiteRest::RestServiceUtils.should_receive(:service_uri).and_return("uri")
38
+ URI.should_receive(:escape).with(args).and_return("escape")
39
+ URI.should_receive(:parse).with("uriescape")
40
+
41
+ SuiteRest::RestServiceUtils.parsed_uri(script_id, deploy_id, is_sandbox, args)
42
+ end
43
+ end
44
+
45
+ context "when given valid input and no arguments" do
46
+ let(:script_id){ Random.rand(1..1000) }
47
+ let(:deploy_id){ Random.rand(1..1000) }
48
+ let(:is_sandbox){ false }
49
+
50
+ it "should properly parse the URI" do
51
+ SuiteRest::RestServiceUtils.should_receive(:service_uri).and_return("uri")
52
+ URI.should_receive(:escape).with("").and_return("")
53
+ URI.should_receive(:parse).with("uri")
54
+
55
+ SuiteRest::RestServiceUtils.parsed_uri(script_id, deploy_id, is_sandbox)
56
+ end
57
+ end
58
+
59
+ context "when testing http" do
60
+ before(:each) do
61
+ @parsed_uri = double(URI, :host => "host", :port => "port")
62
+ @http = double(Net::HTTP)
63
+ end
64
+
65
+ context "when calling http with a parsed uri" do
66
+ it "should process and return an http instance" do
67
+ Net::HTTP.should_receive(:new).with("host", "port").and_return(@http)
68
+ @http.should_receive(:use_ssl=).with(true)
69
+ @http.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
70
+
71
+ SuiteRest::RestServiceUtils.http(@parsed_uri).should eq(@http)
72
+ end
73
+ end
74
+ end
75
+
76
+ context "when testing camel_case_lower" do
77
+ it { SuiteRest::RestServiceUtils.camel_case_lower("trans_id").should eq("transId") }
78
+ it { SuiteRest::RestServiceUtils.camel_case_lower("deploy_id").should eq("deployId") }
79
+ it { SuiteRest::RestServiceUtils.camel_case_lower("is_new_customer").should eq("isNewCustomer") }
80
+ it { SuiteRest::RestServiceUtils.camel_case_lower("a_b_c").should eq("aBC") }
81
+ it { SuiteRest::RestServiceUtils.camel_case_lower("number_1_fan").should eq("number1Fan") }
82
+ end
83
+
84
+ context "when testing add_request_fields" do
85
+ before(:each) do
86
+ @request = double()
87
+ end
88
+
89
+ context "when its called with a request and auth string" do
90
+
91
+ it "should add fields to the request correctly" do
92
+ @request.should_receive(:add_field).with("Authorization", "auth_string")
93
+ @request.should_receive(:add_field).with("Content-Type", "application/json")
94
+
95
+ SuiteRest::RestServiceUtils.add_request_fields(@request, "auth_string")
96
+ end
97
+ end
98
+ end
99
+
100
+ context "when testing urlify" do
101
+ let(:args_def) { [:trans_id, :trans_type] }
102
+ let(:args) do
103
+ {
104
+ :trans_id => 45334,
105
+ :trans_type => 'invoice'
106
+ }
107
+ end
108
+
109
+ it "should return a correct url arg string" do
110
+ SuiteRest::RestServiceUtils.urlify(args, args_def).should eq("&transId=45334&transType=invoice")
111
+ end
112
+ end
113
+
114
+ context "when testing payloadify" do
115
+ let(:args_def) { [:trans_id, :trans_type] }
116
+ let(:args) do
117
+ {
118
+ :trans_id => 45334,
119
+ :trans_type => 'invoice'
120
+ }
121
+ end
122
+
123
+ it "should return a correct JSON payload" do
124
+ SuiteRest::RestServiceUtils.payloadify(args, args_def).should eq("{\"transId\":45334,\"transType\":\"invoice\"}")
125
+ end
126
+ end
127
+
128
+ context "when testing check_response" do
129
+ before(:each) do
130
+ @response = double()
131
+ end
132
+
133
+ it "should return the response if the message is HTTP_OK" do
134
+ @response.should_receive(:code).and_return("200")
135
+
136
+ response_return = SuiteRest::RestServiceUtils.check_response(@response)
137
+ response_return.should eq(@response)
138
+ end
139
+
140
+ it "should raise an error if the message is not HTTPOK" do
141
+ @response.should_receive(:code).twice.and_return("404")
142
+ @response.should_receive(:msg).and_return("Not Found")
143
+
144
+ expect{ SuiteRest::RestServiceUtils.check_response(@response) }.to raise_error(RuntimeError)
145
+ end
146
+ end
147
+
148
+ context "when testing parse_body" do
149
+ it { SuiteRest::RestServiceUtils.parse_body("\"false\"").should eq(false) }
150
+ it { SuiteRest::RestServiceUtils.parse_body("\"true\"").should eq(true) }
151
+ it { SuiteRest::RestServiceUtils.parse_body("\"116\"").should eq(116) }
152
+ it { SuiteRest::RestServiceUtils.parse_body("\"116.14\"").should eq(116.14) }
153
+ it { SuiteRest::RestServiceUtils.parse_body("\"null\"").should eq(nil) }
154
+ it { SuiteRest::RestServiceUtils.parse_body("\"org.mozilla.javascript.Undefined@27129ebf\"").should eq(nil) }
155
+ it { SuiteRest::RestServiceUtils.parse_body("\"One string return\"").should eq("One string return") }
156
+ it { SuiteRest::RestServiceUtils.parse_body("\"1 string\"").should eq("1 string") }
157
+ it { SuiteRest::RestServiceUtils.parse_body("\"true string\"").should eq("true string") }
158
+ it { SuiteRest::RestServiceUtils.parse_body("\"null string\"").should eq("null string") }
159
+ it { SuiteRest::RestServiceUtils.parse_body("\"False\"").should eq("False") }
160
+ it { SuiteRest::RestServiceUtils.parse_body("\"1.10\"").should eq("1.10") }
161
+
162
+ it "should parse a JSON return correctly" do
163
+ rest_return = "{\"a\":5,\"b_key\":\"A string\",\"array_key\":[1,2,3,4,5],\"subHash\":{\"a\":5,\"b\":\"A string\"}}"
164
+ correct_parse = {"a"=>5, "b_key"=>"A string", "array_key"=>[1, 2, 3, 4, 5], "subHash"=>{"a" => 5, "b" => "A string"}}
165
+ SuiteRest::RestServiceUtils.parse_body(rest_return).should eq(correct_parse)
166
+ end
167
+ end
168
+ end
169
+
170
+
171
+ end
@@ -0,0 +1,79 @@
1
+ require 'spec_helper'
2
+
3
+ describe SuiteRest do
4
+
5
+ it "should respond to :configure" do
6
+ should respond_to(:configure)
7
+ end
8
+
9
+ it "should respond to configuration" do
10
+ should respond_to(:configuration)
11
+ end
12
+
13
+ it "should respond to reset!" do
14
+ should respond_to(:reset!)
15
+ end
16
+
17
+ context "when testing varios configurations" do
18
+ let(:account) { 12345 }
19
+ let(:email) { "fake@gmail.com" }
20
+ let(:role) { 1001 }
21
+ let(:signature) { "asdfji2435;'!"}
22
+ let(:auth_string) {
23
+ "NLAuth nlauth_account=" + account.to_s + \
24
+ ", nlauth_email=" + email.to_s + \
25
+ ", nlauth_signature=" + signature.to_s + \
26
+ ", nlauth_role=" + role.to_s
27
+ }
28
+
29
+ before(:each) { SuiteRest.reset! }
30
+
31
+ context "when creating a basic Sandbox config" do
32
+ before do
33
+ SuiteRest.configure do |config|
34
+ config.account = account
35
+ config.email = email
36
+ config.role = role
37
+ config.signature = signature
38
+ end
39
+ end
40
+
41
+ it "should remember the base config settings" do
42
+ SuiteRest.configuration.email.should eq(email)
43
+ SuiteRest.configuration.account.should eq(account)
44
+ SuiteRest.configuration.role.should eq(role)
45
+ SuiteRest.configuration.signature.should eq(signature)
46
+ SuiteRest.configuration.sandbox.should eq(true)
47
+ end
48
+
49
+ it "should return a proper auth string" do
50
+ SuiteRest.configuration.auth_string.should eq(auth_string)
51
+ end
52
+ end
53
+
54
+ context "when creating a basic production config" do
55
+ before do
56
+ SuiteRest.configure do |config|
57
+ config.account = account
58
+ config.email = email
59
+ config.role = role
60
+ config.signature = signature
61
+ config.sandbox = false
62
+ end
63
+ end
64
+
65
+ it "should remember the base config settings" do
66
+ SuiteRest.configuration.email.should eq(email)
67
+ SuiteRest.configuration.account.should eq(account)
68
+ SuiteRest.configuration.role.should eq(role)
69
+ SuiteRest.configuration.signature.should eq(signature)
70
+ SuiteRest.configuration.sandbox.should eq(false)
71
+ end
72
+
73
+ it "should return a proper auth string" do
74
+ SuiteRest.configuration.auth_string.should eq(auth_string)
75
+ end
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'suite_rest/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "suite_rest"
8
+ gem.version = SuiteRest::VERSION
9
+ gem.authors = ["Ben DiFrancesco"]
10
+ gem.email = ["ben.difrancesco@gmail.com"]
11
+ gem.description = "Easy interaction with NetSuite RESTlets"
12
+ gem.summary = gem.description
13
+ gem.homepage = "http://github.com/apbendi/suite_rest"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'json', '~> 1.8.1'
21
+
22
+ gem.add_development_dependency 'rspec', '~> 2.10'
23
+ gem.add_development_dependency 'pry-debugger'
24
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: suite_rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben DiFrancesco
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.8.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.8.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '2.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-debugger
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ! '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Easy interaction with NetSuite RESTlets
56
+ email:
57
+ - ben.difrancesco@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - lib/suite_rest.rb
69
+ - lib/suite_rest/rest_service.rb
70
+ - lib/suite_rest/rest_service_utils.rb
71
+ - lib/suite_rest/version.rb
72
+ - spec/spec_helper.rb
73
+ - spec/suite_rest/rest_service_spec.rb
74
+ - spec/suite_rest/rest_service_utils_spec.rb
75
+ - spec/suite_rest_spec.rb
76
+ - suite_rest.gemspec
77
+ homepage: http://github.com/apbendi/suite_rest
78
+ licenses: []
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.2.2
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Easy interaction with NetSuite RESTlets
100
+ test_files:
101
+ - spec/spec_helper.rb
102
+ - spec/suite_rest/rest_service_spec.rb
103
+ - spec/suite_rest/rest_service_utils_spec.rb
104
+ - spec/suite_rest_spec.rb