routengn-client 0.1.4
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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +34 -0
- data/Rakefile +1 -0
- data/lib/routengn_client/connection.rb +77 -0
- data/lib/routengn_client/exceptions.rb +8 -0
- data/lib/routengn_client/logging.rb +23 -0
- data/lib/routengn_client/middleware/routengn_response_middleware.rb +23 -0
- data/lib/routengn_client/model.rb +177 -0
- data/lib/routengn_client/models/account.rb +23 -0
- data/lib/routengn_client/models/allow_list.rb +38 -0
- data/lib/routengn_client/models/carrier.rb +14 -0
- data/lib/routengn_client/models/code.rb +32 -0
- data/lib/routengn_client/models/code_sheet.rb +11 -0
- data/lib/routengn_client/models/contact.rb +124 -0
- data/lib/routengn_client/models/end_point.rb +18 -0
- data/lib/routengn_client/models/inbound_end_point_group.rb +70 -0
- data/lib/routengn_client/models/inbound_rate.rb +13 -0
- data/lib/routengn_client/models/outbound_end_point_group.rb +51 -0
- data/lib/routengn_client/models/outbound_rate.rb +13 -0
- data/lib/routengn_client/models/rate_sheet.rb +13 -0
- data/lib/routengn_client/models/record.rb +231 -0
- data/lib/routengn_client/models/route.rb +42 -0
- data/lib/routengn_client/models/route_block.rb +7 -0
- data/lib/routengn_client/models/route_container.rb +18 -0
- data/lib/routengn_client/models/route_ordering_override.rb +7 -0
- data/lib/routengn_client/models/route_table.rb +30 -0
- data/lib/routengn_client/models/system_admin_account.rb +5 -0
- data/lib/routengn_client/models/uri_matcher.rb +72 -0
- data/lib/routengn_client/models/user.rb +20 -0
- data/lib/routengn_client/remote_model.rb +69 -0
- data/lib/routengn_client/request.rb +34 -0
- data/lib/routengn_client/response.rb +108 -0
- data/lib/routengn_client/utils.rb +20 -0
- data/lib/routengn_client/version.rb +3 -0
- data/lib/routengn_client.rb +72 -0
- data/routengn-client.gemspec +37 -0
- data/spec/lib/routengn_client/connection_spec.rb +44 -0
- data/spec/lib/routengn_client/logging_spec.rb +9 -0
- data/spec/lib/routengn_client/model_spec.rb +82 -0
- data/spec/lib/routengn_client/models/account_spec.rb +28 -0
- data/spec/lib/routengn_client/models/carrier_spec.rb +20 -0
- data/spec/lib/routengn_client/models/code_spec.rb +32 -0
- data/spec/lib/routengn_client/models/contact_spec.rb +57 -0
- data/spec/lib/routengn_client/models/inbound_end_point_group_spec.rb +33 -0
- data/spec/lib/routengn_client/models/inbound_rate_spec.rb +10 -0
- data/spec/lib/routengn_client/models/outbound_end_point_group_spec.rb +52 -0
- data/spec/lib/routengn_client/models/outbound_rate_spec.rb +10 -0
- data/spec/lib/routengn_client/models/rate_sheet_spec.rb +0 -0
- data/spec/lib/routengn_client/models/record_spec.rb +59 -0
- data/spec/lib/routengn_client/models/route_container_spec.rb +10 -0
- data/spec/lib/routengn_client/models/route_spec.rb +228 -0
- data/spec/lib/routengn_client/models/route_table_spec.rb +87 -0
- data/spec/lib/routengn_client/remote_model_spec.rb +60 -0
- data/spec/lib/routengn_client/request_spec.rb +14 -0
- data/spec/lib/routengn_client/response_spec.rb +29 -0
- data/spec/lib/routengn_client_spec.rb +5 -0
- data/spec/spec_helper.rb +34 -0
- data/spec/support/blueprints.rb +157 -0
- metadata +351 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module RouteNGNClient
|
2
|
+
class Request
|
3
|
+
|
4
|
+
attr_accessor :resource_attributes, :method, :path_parts, :path_ext, :params, :klass, :request_account_id
|
5
|
+
|
6
|
+
def initialize(resource_attributes, method, path_parts, path_ext, params = {}, options = {})
|
7
|
+
@resource_attributes, @method, @path_parts, @path_ext, @params, @options = resource_attributes, method, path_parts, path_ext, params, options
|
8
|
+
@request_account_id = @options[:account_id]
|
9
|
+
@klass = @options[:klass]
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute(connection)
|
13
|
+
self.build_params!
|
14
|
+
response = Response.new(self, connection.send(@method, self.build_path(@path_parts, @path_ext), @params, self.build_request_options))
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_params!
|
18
|
+
@params[:env] ||= {}
|
19
|
+
@params[:env][:account_id] ||= @request_account_id if @request_account_id
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_request_options
|
23
|
+
{}.merge!(@resource_attributes[:request_options])
|
24
|
+
end
|
25
|
+
|
26
|
+
def build_path(parts = [], ext = '.json')
|
27
|
+
parts.compact!
|
28
|
+
parts.map!{ |p| p.to_s }
|
29
|
+
|
30
|
+
"#{File.join(parts)}#{ext}"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module RouteNGNClient
|
2
|
+
class Response
|
3
|
+
|
4
|
+
METADATA_KEYS = [
|
5
|
+
:total_count,
|
6
|
+
:current_page,
|
7
|
+
:per_page,
|
8
|
+
:offset,
|
9
|
+
:total_pages
|
10
|
+
]
|
11
|
+
|
12
|
+
attr_accessor :request, :faraday_response
|
13
|
+
|
14
|
+
def initialize(request, faraday_response)
|
15
|
+
@request = request
|
16
|
+
@faraday_response = faraday_response
|
17
|
+
end
|
18
|
+
|
19
|
+
def env
|
20
|
+
@faraday_response.env
|
21
|
+
end
|
22
|
+
|
23
|
+
def status
|
24
|
+
self.env[:status]
|
25
|
+
end
|
26
|
+
|
27
|
+
def error_status?
|
28
|
+
(400...600).include? self.status
|
29
|
+
end
|
30
|
+
|
31
|
+
def body
|
32
|
+
self.env[:body]
|
33
|
+
end
|
34
|
+
|
35
|
+
def metadata
|
36
|
+
return @metadata if defined?(@metadata)
|
37
|
+
|
38
|
+
if status == 200 && self.body.kind_of?(Hash)
|
39
|
+
@metadata = {}.with_indifferent_access
|
40
|
+
|
41
|
+
METADATA_KEYS.each { |k| @metadata[k] = self.body[k] }
|
42
|
+
|
43
|
+
@metadata
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def pages_left
|
48
|
+
if self.metadata && self.metadata[:current_page] && self.metadata[:total_pages]
|
49
|
+
self.metadata[:total_pages] - self.metadata[:current_page]
|
50
|
+
else
|
51
|
+
0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def current_page
|
56
|
+
self.metadata[:current_page] if self.metadata
|
57
|
+
end
|
58
|
+
|
59
|
+
def total_pages
|
60
|
+
self.metadata[:total_pages] if self.metadata
|
61
|
+
end
|
62
|
+
|
63
|
+
def pages_left?
|
64
|
+
self.current_page && self.total_pages ? (self.current_page < self.total_pages) : false
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_models(&blk)
|
68
|
+
self.build_models(@request.resource_attributes[:collection_name], @request.klass, &blk)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_model
|
72
|
+
self.build_model(@request.resource_attributes[:collection_name], @request.klass)
|
73
|
+
end
|
74
|
+
|
75
|
+
def build_models(collection_name, klass, &blk)
|
76
|
+
raise RouteNGNResponseException, 'could not create Models from Response' if self.error_status?
|
77
|
+
|
78
|
+
models = []
|
79
|
+
|
80
|
+
self.body[collection_name.to_sym].each do |h|
|
81
|
+
if r = h[collection_name.singularize.to_sym]
|
82
|
+
m = klass.send :from_hash, r
|
83
|
+
m.request_account_id = @request.request_account_id
|
84
|
+
models << m
|
85
|
+
blk.call(m) if blk
|
86
|
+
else
|
87
|
+
next
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
models
|
92
|
+
end
|
93
|
+
|
94
|
+
def build_model(collection_name, klass)
|
95
|
+
raise RouteNGNResponseException, 'could not create Model from Response' if self.error_status?
|
96
|
+
|
97
|
+
model = nil
|
98
|
+
|
99
|
+
if r = self.body[collection_name.singularize.to_sym]
|
100
|
+
model = klass.send :from_hash, r
|
101
|
+
model.request_account_id = @request.request_account_id
|
102
|
+
end
|
103
|
+
|
104
|
+
model
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module RouteNGNClient
|
2
|
+
module Utils
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def string_subsets(s, options = {})
|
6
|
+
result = s.blank? ? [] : s.length.times.collect { |i| s[0,i+1] }
|
7
|
+
|
8
|
+
if options[:order] == :asc
|
9
|
+
result.sort! { |x,y| x <=> y }
|
10
|
+
else
|
11
|
+
result.sort! { |x,y| y <=> x }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def generate_uuid
|
16
|
+
SecureRandom.uuid
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
$:.push File.dirname(__FILE__)
|
2
|
+
require 'pry'
|
3
|
+
require 'logger'
|
4
|
+
require 'faraday'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'faraday_middleware'
|
7
|
+
require 'faraday_middleware/multi_json'
|
8
|
+
require 'multi_xml'
|
9
|
+
require 'comma'
|
10
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
11
|
+
require 'active_support/core_ext/object/blank'
|
12
|
+
require 'active_support/core_ext/module'
|
13
|
+
require 'active_support/inflector'
|
14
|
+
require 'active_support/notifications'
|
15
|
+
require 'routengn_client/version'
|
16
|
+
require 'routengn_client/exceptions'
|
17
|
+
require 'routengn_client/logging'
|
18
|
+
require 'routengn_client/utils'
|
19
|
+
require 'routengn_client/connection'
|
20
|
+
require 'routengn_client/request'
|
21
|
+
require 'routengn_client/response'
|
22
|
+
require 'routengn_client/model'
|
23
|
+
require 'routengn_client/remote_model'
|
24
|
+
|
25
|
+
module RouteNGNClient
|
26
|
+
autoload :RouteNGNResponseMiddleware, 'routengn_client/middleware/routengn_response_middleware'
|
27
|
+
autoload :Account, 'routengn_client/models/account'
|
28
|
+
autoload :SystemAdminAccount, 'routengn_client/models/system_admin_account'
|
29
|
+
autoload :User, 'routengn_client/models/user'
|
30
|
+
autoload :OutboundEndPointGroup, 'routengn_client/models/outbound_end_point_group'
|
31
|
+
autoload :InboundEndPointGroup, 'routengn_client/models/inbound_end_point_group'
|
32
|
+
autoload :Carrier, 'routengn_client/models/carrier'
|
33
|
+
autoload :Contact, 'routengn_client/models/contact'
|
34
|
+
autoload :EndPoint, 'routengn_client/models/end_point'
|
35
|
+
autoload :AllowList, 'routengn_client/models/allow_list'
|
36
|
+
autoload :URIMatcher, 'routengn_client/models/uri_matcher'
|
37
|
+
autoload :UriMatcher, 'routengn_client/models/uri_matcher'
|
38
|
+
autoload :RouteTable, 'routengn_client/models/route_table'
|
39
|
+
autoload :Route, 'routengn_client/models/route'
|
40
|
+
autoload :RouteContainer, 'routengn_client/models/route_container'
|
41
|
+
autoload :RateSheet, 'routengn_client/models/rate_sheet'
|
42
|
+
autoload :InboundRate, 'routengn_client/models/inbound_rate'
|
43
|
+
autoload :OutboundRate, 'routengn_client/models/outbound_rate'
|
44
|
+
autoload :CodeSet, 'routengn_client/models/code_set'
|
45
|
+
autoload :Code, 'routengn_client/models/code'
|
46
|
+
autoload :CodeSheet, 'routengn_client/models/code_sheet'
|
47
|
+
autoload :Record, 'routengn_client/models/record'
|
48
|
+
|
49
|
+
module ClassMethods
|
50
|
+
def connection
|
51
|
+
@connection ? @connection : (raise RateNGNClientConnectionException)
|
52
|
+
end
|
53
|
+
|
54
|
+
def connect(config = {})
|
55
|
+
@connection = Connection.new(:uri => config[:uri], :api_key => config[:api_key])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
extend ClassMethods
|
60
|
+
extend Logging
|
61
|
+
|
62
|
+
#MultiJson.use :yajl
|
63
|
+
#Faraday.default_adapter = :excon
|
64
|
+
Faraday.register_middleware :response, :routengn_response => lambda { RouteNGNResponseMiddleware }
|
65
|
+
end
|
66
|
+
|
67
|
+
ActiveSupport::Notifications.subscribe('request.faraday') do |name, start_time, end_time, _, env|
|
68
|
+
url = env[:url]
|
69
|
+
http_method = env[:method].to_s.upcase
|
70
|
+
duration = end_time - start_time
|
71
|
+
RouteNGNClient.logger.info '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration]
|
72
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'routengn_client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "routengn-client"
|
8
|
+
spec.version = RouteNGNClient::VERSION
|
9
|
+
spec.authors = ["Keith Larrimore"]
|
10
|
+
spec.email = ["klarrimore@icehook.com"]
|
11
|
+
spec.description = %q{RouteNGN Ruby Client Library}
|
12
|
+
spec.summary = %q{RouteNGN Ruby Client Library}
|
13
|
+
spec.homepage = "http://icehook.com/routengn"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'rspec', '>= 2.13.0'
|
23
|
+
spec.add_development_dependency 'ffaker', '~> 1.15.0'
|
24
|
+
spec.add_development_dependency 'machinist', '~> 2.0'
|
25
|
+
spec.add_development_dependency 'webmock', '~> 1.9.3'
|
26
|
+
spec.add_development_dependency 'guard-rspec', '~> 2.5.0'
|
27
|
+
spec.add_development_dependency 'rb-fsevent', '~> 0.9.3'
|
28
|
+
spec.add_development_dependency 'simplecov', '~> 0.7.1'
|
29
|
+
spec.add_development_dependency 'rsip', '~> 0.2.2'
|
30
|
+
spec.add_runtime_dependency 'pry', '~> 0.9.12'
|
31
|
+
spec.add_runtime_dependency 'activesupport', '~> 4.0.2'
|
32
|
+
spec.add_runtime_dependency 'faraday', '~> 0.8.8'
|
33
|
+
spec.add_runtime_dependency 'faraday_middleware', '~> 0.9.0'
|
34
|
+
spec.add_runtime_dependency 'faraday_middleware-multi_json', '~> 0.0.5'
|
35
|
+
spec.add_runtime_dependency 'multi_xml', '~> 0.5.3'
|
36
|
+
spec.add_runtime_dependency 'comma', '~> 3.2.0'
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::Connection do
|
4
|
+
|
5
|
+
before do
|
6
|
+
bodya = '{"total_count":1,"current_page":1,"per_page":200,"offset":0,"total_pages":1,"testa":[]}'
|
7
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/testa\.json.*/).to_return(:body => bodya,
|
8
|
+
:status => 200,
|
9
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
10
|
+
|
11
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/faila\.json.*/).to_return(:body => bodya,
|
12
|
+
:status => 500,
|
13
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should create a new instance given valid attributes" do
|
17
|
+
c = Connection.new
|
18
|
+
c.should be_an_instance_of(Connection)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#create_faraday' do
|
22
|
+
it "should return an instace of Faraday::Connection" do
|
23
|
+
c = Connection.new
|
24
|
+
f = c.create_faraday('http://localhost/test.json')
|
25
|
+
f.should be_an_instance_of(Faraday::Connection)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#request' do
|
30
|
+
it "should return an instace of Faraday::Response" do
|
31
|
+
c = Connection.new
|
32
|
+
f = c.create_faraday('http://127.0.0.1')
|
33
|
+
f.send(:get, 'testa.json').should be_an_instance_of(Faraday::Response)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should a bad status code should raise an exception" do
|
37
|
+
c = Connection.new
|
38
|
+
f = c.create_faraday('http://127.0.0.1')
|
39
|
+
expect { f.send(:get, 'faila.json') }.to raise_error
|
40
|
+
begin;f.send(:get, 'faila.json');rescue => e; e.should be_an_instance_of(UnexpectedHTTPException);end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::Model do
|
4
|
+
|
5
|
+
before do
|
6
|
+
RouteNGNClient.connect(:uri => 'http://127.0.0.1')
|
7
|
+
|
8
|
+
bodyc = '{"account":{}}'
|
9
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/system_admin\/accounts\/foobar\.json.*/).to_return(:body => bodyc,
|
10
|
+
:status => 200,
|
11
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
12
|
+
|
13
|
+
|
14
|
+
bodyd = '{"total_count":1,"current_page":1,"per_page":200,"offset":0,"total_pages":1,"carriers":[]}'
|
15
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/metallic\/carriers\/foobar\.json.*/).to_return(:body => bodyd,
|
16
|
+
:status => 200,
|
17
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create a new instance given valid attributes" do
|
21
|
+
m = Model.new
|
22
|
+
m.should be_an_instance_of(Model)
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#to_hash' do
|
26
|
+
it "should return an instace of Hash" do
|
27
|
+
m = Model.new(:test => 'foo')
|
28
|
+
m.to_hash.should be_an_instance_of(Hash)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#to_json' do
|
33
|
+
it "should return an instace of String" do
|
34
|
+
m = Model.new(:test => 'foo')
|
35
|
+
m.to_json.should be_an_instance_of(String)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#from_hash' do
|
40
|
+
it "should return an instace of Model" do
|
41
|
+
m = Model.from_hash(:test => 'foo')
|
42
|
+
m.should be_an_instance_of(Model)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#belongs_to' do
|
47
|
+
it "should set parents and accessors" do
|
48
|
+
c = Class.new(Model)
|
49
|
+
c.belongs_to :account
|
50
|
+
c.parents.length.should == 1
|
51
|
+
c.parents.first.should be_an_instance_of(RouteNGNClient::Account.class)
|
52
|
+
m = c.from_hash(:test => 'foo', :account_id => 'foobar')
|
53
|
+
m.should respond_to(:account)
|
54
|
+
m.account.should be_an_instance_of(Account)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe '#has_many' do
|
59
|
+
it "should set children and accessors" do
|
60
|
+
c = Class.new(Model)
|
61
|
+
c.has_many :carriers
|
62
|
+
c.children.length.should == 1
|
63
|
+
c.children.first.should be_an_instance_of(RouteNGNClient::Carrier.class)
|
64
|
+
m = c.from_hash(:test => 'foo', :carrier_id => 'foobar')
|
65
|
+
m.should respond_to(:carriers)
|
66
|
+
m.carriers.should be_an_instance_of(Array)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe '#has_one' do
|
71
|
+
it "should set child and accessors" do
|
72
|
+
c = Class.new(Model)
|
73
|
+
c.has_one :account
|
74
|
+
c.only_children.length.should == 1
|
75
|
+
c.only_children.first.should be_an_instance_of(RouteNGNClient::Account.class)
|
76
|
+
m = c.from_hash(:test => 'foo', :account_id => 'foobar')
|
77
|
+
m.should respond_to(:account)
|
78
|
+
m.account.should be_an_instance_of(Account)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::Account do
|
4
|
+
|
5
|
+
before do
|
6
|
+
RouteNGNClient.connect(:uri => 'http://127.0.0.1')
|
7
|
+
body = '{"total_count":3,"current_page":1,"per_page":25,"offset":0,"total_pages":1,"accounts":[{"account":{"company":"Call Processor","created_at":"2013-03-04T23:56:44Z","updated_at":"2013-03-04T23:56:44Z","id":"513534bc6f1cc938d5000001","system_admin":true}},{"account":{"company":"Nagios","created_at":"2013-03-04T23:56:45Z","updated_at":"2013-03-04T23:56:45Z","id":"513534bd6f1cc938d5000006","system_admin":false}},{"account":{"company":"testing","created_at":"2013-03-04T23:59:10Z","updated_at":"2013-03-04T23:59:10Z","id":"5135354e6f1cc9a140000004","system_admin":false}}]}'
|
8
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/system_admin\/accounts\.json.*/).to_return(:body => body,
|
9
|
+
:status => 200,
|
10
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should create a new instance given valid attributes" do
|
14
|
+
a = Account.new
|
15
|
+
a.should be_an_instance_of(Account)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#all' do
|
19
|
+
it "should return an instace of Array" do
|
20
|
+
accounts = Account.all
|
21
|
+
accounts.should be_an_instance_of(Array)
|
22
|
+
accounts.length.should == 3
|
23
|
+
accounts.first.should be_an_instance_of(Account)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::Carrier do
|
4
|
+
|
5
|
+
before do
|
6
|
+
RouteNGNClient.connect(:uri => 'http://127.0.0.1')
|
7
|
+
body = '{"total_count":2,"current_page":1,"per_page":25,"offset":0,"total_pages":1,"carriers":[{"carrier":{"name":"Carrier A","minimum_duration":null,"billing_increment":null,"color_code":"#f3a679","created_at":"2013-03-05T00:11:29Z","updated_at":"2013-03-05T00:11:29Z","id":"513538316f1cc9a140000011","account_id":"5135354e6f1cc9a140000004"}},{"carrier":{"name":"Carrier B","minimum_duration":null,"billing_increment":null,"color_code":"#f37990","created_at":"2013-03-05T00:12:04Z","updated_at":"2013-03-05T00:12:04Z","id":"513538546f1cc9a140000017","account_id":"5135354e6f1cc9a140000004"}}]}'
|
8
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/metallic\/carriers\.json.*/).to_return(:body => body,
|
9
|
+
:status => 200,
|
10
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can get all" do
|
14
|
+
RouteNGNClient::Carrier.all({}, :account_id => 'foofoo') do |models|
|
15
|
+
models.length.should == 2
|
16
|
+
models.first.should be_an_instance_of RouteNGNClient::Carrier
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::Code do
|
4
|
+
|
5
|
+
before do
|
6
|
+
RouteNGNClient.connect(:uri => 'http://127.0.0.1')
|
7
|
+
body = "{\"total_count\":1,\"current_page\":1,\"per_page\":25,\"offset\":0,\"total_pages\":1,\"codes\":[{\"code\":{\"dialcode\":\"2122226\",\"local\":null,\"city\":\"CAPITAL PENNS\",\"state\":\"PA\",\"country\":null,\"lata\":\"226\",\"ocn\":\"EOCN\",\"ocn_name\":null,\"lerg_category\":null,\"disabled\":null,\"blocked\":null,\"effective_at\":null,\"ineffective_at\":null,\"line_number\":null,\"created_at\":null,\"updated_at\":null,\"id\":\"5066a1e80a516552b9443d23\",\"code_sheet_id\":\"50669c9f4c6b97c82f00003d\"}}]}"
|
8
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/metallic\/codes\.json.*/).to_return(:body => body,
|
9
|
+
:status => 200,
|
10
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can be instanstiated" do
|
14
|
+
c = Code.new
|
15
|
+
c.should be_an_instance_of(Code)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can find_by_exploded_dialcode" do
|
19
|
+
codes1 = nil
|
20
|
+
codes2 = nil
|
21
|
+
|
22
|
+
codes1 = Code.find_by_exploded_dialcode('2122226263')
|
23
|
+
codes2 = Code.find_by_dialcodes(['2122226263', '212'])
|
24
|
+
|
25
|
+
codes1.length.should == 1
|
26
|
+
codes1.first.should be_an_instance_of(Code)
|
27
|
+
|
28
|
+
codes2.length.should == 1
|
29
|
+
codes2.first.should be_an_instance_of(Code)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::Contact do
|
4
|
+
|
5
|
+
it "can be instanstiated" do
|
6
|
+
c = Contact.new
|
7
|
+
c.should be_an_instance_of(Contact)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "can build uri" do
|
11
|
+
sip_request = RSIP::Message.parse(INVITE)
|
12
|
+
route = Route.new(:outbound_end_point_group => OEPG1)
|
13
|
+
oep = OEPG1.end_points.first
|
14
|
+
contact = Contact.new :route => route, :end_point => oep
|
15
|
+
|
16
|
+
uri = contact.build_uri(INVITE_SIP_REQUEST1)
|
17
|
+
uri.should be_an_instance_of(RSIP::Message::SIPURI)
|
18
|
+
uri.user.dialcode.should == "50246380762"
|
19
|
+
uri.user.params.should be_empty
|
20
|
+
uri.params.should == {"otg"=>"3", "npdi"=>"yes", "rn"=>"2123334545"}
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can build aor" do
|
24
|
+
sip_request = RSIP::Message.parse(INVITE)
|
25
|
+
route = Route.new(:outbound_end_point_group => OEPG1)
|
26
|
+
oep = OEPG1.end_points.first
|
27
|
+
contact = Contact.new :route => route, :end_point => oep
|
28
|
+
|
29
|
+
aor = contact.build_aor(INVITE_SIP_REQUEST1, IEPG1)
|
30
|
+
aor.should be_an_instance_of(String)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should URI.encode the aor" do
|
34
|
+
sip_request = RSIP::Message.parse(INVITE)
|
35
|
+
oepg2 = OEPG1.clone
|
36
|
+
oepg2.attributes.dialcode_template = "123\#${dialcode_match}"
|
37
|
+
oep = oepg2.end_points.first
|
38
|
+
route = Route.new(:outbound_end_point_group => oepg2)
|
39
|
+
contact = Contact.new :route => route, :end_point => oep
|
40
|
+
|
41
|
+
aor = contact.build_aor(sip_request, IEPG1)
|
42
|
+
aor.should == '<sip:123%2350246380762@1.1.1.1:5060;otg=3;npdi=yes;rn=2123334545>'
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should put the user params in the correct place" do
|
46
|
+
sip_request = RSIP::Message.parse(INVITE2)
|
47
|
+
oepg1 = OEPG1.clone
|
48
|
+
oepg1.attributes.dialcode_template = "123\#${dialcode_match}"
|
49
|
+
oep = oepg1.end_points.first
|
50
|
+
route = Route.new(:outbound_end_point_group => oepg1)
|
51
|
+
contact = Contact.new :route => route, :end_point => oep
|
52
|
+
|
53
|
+
aor = contact.build_aor(sip_request, IEPG1)
|
54
|
+
aor.should == '<sip:123%237772223333;npdi=yes;rn=2123334545;otg=4@1.1.1.1:5060>'
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::InboundEndPointGroup do
|
4
|
+
|
5
|
+
before do
|
6
|
+
RouteNGNClient.connect(:uri => 'http://127.0.0.1')
|
7
|
+
body = "{\"total_count\":1,\"current_page\":1,\"per_page\":25,\"offset\":0,\"total_pages\":1,\"inbound_end_point_groups\":[{\"inbound_end_point_group\":{\"name\":\"IEPG 1\",\"contact_template\":\"<sip:${ruri.dialcode}${ruri.user_params}${oepg.uri_user_params}@${oep.host}${oep.port}${ruri.params}${oepg.uri_params}>\",\"multi_line_contacts\":true,\"color_code\":\"#a4f379\",\"route_on_type\":\"DN\",\"min_percent_price_margin\":null,\"min_absolute_price_margin\":null,\"min_route_weight\":null,\"dialcode_expression\":\"([0-9]*)$\",\"dialcode_prefix_expression\":\"^(.*D+)\",\"ani_expression\":\"([0-9]*)$\",\"ani_prefix_expression\":\"^(.*D+)\",\"destination_billing_type\":\"DN\",\"external_lrn_lookup_enabled\":false,\"created_at\":\"2013-03-05T00:11:29Z\",\"updated_at\":\"2013-03-05T00:35:24Z\",\"id\":\"513538316f1cc9a140000010\",\"carrier_id\":\"513538316f1cc9a140000011\",\"primary_route_table_id\":\"513538666f1cc9a14000001b\",\"secondary_route_table_id\":\"\",\"allow_list\":{\"id\":\"513538316f1cc9a14000000e\",\"uri_matchers\":[{\"header\":\"request\",\"prefix\":\"\",\"user_params\":\"tgrp=foo\",\"uri_params\":\"\",\"created_at\":\"2013-03-05T00:11:29Z\",\"updated_at\":\"2013-03-05T00:11:29Z\",\"id\":\"513538316f1cc9a14000000f\"}]},\"end_points\":[{\"end_point\":{\"host\":\"127.0.0.1\",\"port\":5060,\"priority\":null,\"created_at\":null,\"updated_at\":null,\"id\":\"51353dcc6f1cc9f910000006\"}}]}}]}"
|
8
|
+
stub_request(:get, /^http:\/\/127\.0\.0\.1\/metallic\/inbound_end_point_groups\.json.*/).to_return(:body => body,
|
9
|
+
:status => 200,
|
10
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can get all via callback" do
|
14
|
+
iepgs = nil
|
15
|
+
|
16
|
+
RouteNGNClient::InboundEndPointGroup.all({}, :account_id => 'foofoo') do |models|
|
17
|
+
iepgs = models
|
18
|
+
end
|
19
|
+
|
20
|
+
iepgs.length.should == 1
|
21
|
+
iepgs.first.should be_an_instance_of RouteNGNClient::InboundEndPointGroup
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can get all via fibers" do
|
25
|
+
iepgs = nil
|
26
|
+
|
27
|
+
iepgs = RouteNGNClient::InboundEndPointGroup.all({}, :account_id => 'foofoo')
|
28
|
+
|
29
|
+
iepgs.length.should == 1
|
30
|
+
iepgs.first.should be_an_instance_of RouteNGNClient::InboundEndPointGroup
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RouteNGNClient::OutboundEndPointGroup do
|
4
|
+
|
5
|
+
before do
|
6
|
+
RouteNGNClient.connect(:uri => 'http://127.0.0.1', :api_key => 'foobar')
|
7
|
+
body = '{"total_count":1,"current_page":1,"per_page":25,"offset":0,"total_pages":1,"outbound_end_point_groups":[{"outbound_end_point_group":{"id":"513538546f1cc9a140000016","carrier_id":"513538546f1cc9a140000017","color_code":"#f379de","created_at":"2013-03-05 00:12:04 UTC","default_route_weight":null,"destination_billing_type":"DN","dialcode_expression":"([0-9]*)$","dialcode_template":"${dialcode_match}","end_points":[{"_id":"513538546f1cc9a140000018","port":5060,"host":"1.1.1.1","priority":null}],"max_contact_end_points":null,"name":"OEPG 1","rate_link_types":["dialcode"],"route_table_ids":["513538666f1cc9a14000001b"],"updated_at":"2013-03-05 00:12:04 UTC","uri_params":"","uri_params_blacklist":[],"uri_user_params":"","uri_user_params_blacklist":[]}}]}'
|
8
|
+
stub_request(:get, "http://127.0.0.1/metallic/outbound_end_point_groups.json?api_key=foobar&env%5Baccount_id%5D=foofoo3&include_paging_info=true&page=1&per_page=50").to_return(:body => body,
|
9
|
+
:status => 200,
|
10
|
+
:headers => { 'Content-Type' => 'application/json; charset=utf-8' })
|
11
|
+
end
|
12
|
+
|
13
|
+
it "can get all via callback" do
|
14
|
+
oepgs = nil
|
15
|
+
|
16
|
+
RouteNGNClient::OutboundEndPointGroup.all({}, :account_id => 'foofoo3') do |models|
|
17
|
+
oepgs = models
|
18
|
+
end
|
19
|
+
|
20
|
+
oepgs.length.should == 1
|
21
|
+
oepgs.first.should be_an_instance_of RouteNGNClient::OutboundEndPointGroup
|
22
|
+
end
|
23
|
+
|
24
|
+
it "can get all via fibers" do
|
25
|
+
oepgs = nil
|
26
|
+
|
27
|
+
oepgs = RouteNGNClient::OutboundEndPointGroup.all({}, :account_id => 'foofoo3')
|
28
|
+
|
29
|
+
oepgs.length.should == 1
|
30
|
+
oepgs.first.should be_an_instance_of RouteNGNClient::OutboundEndPointGroup
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can prioritize end_points based on priorities" do
|
34
|
+
h = OEPG1.to_hash
|
35
|
+
h[:end_points] += [EndPoint.new(:host => '2.2.2.2', :priority => 7), EndPoint.new(:host => '3.3.3.3', :priority => 5)]
|
36
|
+
oepg = OutboundEndPointGroup.new h
|
37
|
+
|
38
|
+
eps = oepg.prioritized_end_points
|
39
|
+
eps[0].attributes.host.should == '3.3.3.3'
|
40
|
+
eps[1].attributes.host.should == '2.2.2.2'
|
41
|
+
eps[2].attributes.host.should == '1.1.1.1'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should randomize end_points with the same priorities" do
|
45
|
+
h = OEPG1.to_hash
|
46
|
+
h[:end_points] = [EndPoint.new(:host => '2.2.2.2', :priority => 5), EndPoint.new(:host => '3.3.3.3', :priority => 5), EndPoint.new(:host => '1.1.1.1', :priority => 5)]
|
47
|
+
oepg = OutboundEndPointGroup.new h
|
48
|
+
a = 10.times.to_a.map { |i| oepg.prioritized_end_points }
|
49
|
+
a.select { |x| x.map { |ep| ep.attributes.host } != a.first.map { |ep| ep.attributes.host } }.length.should > 0 #some should have different orderings
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|