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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +34 -0
  7. data/Rakefile +1 -0
  8. data/lib/routengn_client/connection.rb +77 -0
  9. data/lib/routengn_client/exceptions.rb +8 -0
  10. data/lib/routengn_client/logging.rb +23 -0
  11. data/lib/routengn_client/middleware/routengn_response_middleware.rb +23 -0
  12. data/lib/routengn_client/model.rb +177 -0
  13. data/lib/routengn_client/models/account.rb +23 -0
  14. data/lib/routengn_client/models/allow_list.rb +38 -0
  15. data/lib/routengn_client/models/carrier.rb +14 -0
  16. data/lib/routengn_client/models/code.rb +32 -0
  17. data/lib/routengn_client/models/code_sheet.rb +11 -0
  18. data/lib/routengn_client/models/contact.rb +124 -0
  19. data/lib/routengn_client/models/end_point.rb +18 -0
  20. data/lib/routengn_client/models/inbound_end_point_group.rb +70 -0
  21. data/lib/routengn_client/models/inbound_rate.rb +13 -0
  22. data/lib/routengn_client/models/outbound_end_point_group.rb +51 -0
  23. data/lib/routengn_client/models/outbound_rate.rb +13 -0
  24. data/lib/routengn_client/models/rate_sheet.rb +13 -0
  25. data/lib/routengn_client/models/record.rb +231 -0
  26. data/lib/routengn_client/models/route.rb +42 -0
  27. data/lib/routengn_client/models/route_block.rb +7 -0
  28. data/lib/routengn_client/models/route_container.rb +18 -0
  29. data/lib/routengn_client/models/route_ordering_override.rb +7 -0
  30. data/lib/routengn_client/models/route_table.rb +30 -0
  31. data/lib/routengn_client/models/system_admin_account.rb +5 -0
  32. data/lib/routengn_client/models/uri_matcher.rb +72 -0
  33. data/lib/routengn_client/models/user.rb +20 -0
  34. data/lib/routengn_client/remote_model.rb +69 -0
  35. data/lib/routengn_client/request.rb +34 -0
  36. data/lib/routengn_client/response.rb +108 -0
  37. data/lib/routengn_client/utils.rb +20 -0
  38. data/lib/routengn_client/version.rb +3 -0
  39. data/lib/routengn_client.rb +72 -0
  40. data/routengn-client.gemspec +37 -0
  41. data/spec/lib/routengn_client/connection_spec.rb +44 -0
  42. data/spec/lib/routengn_client/logging_spec.rb +9 -0
  43. data/spec/lib/routengn_client/model_spec.rb +82 -0
  44. data/spec/lib/routengn_client/models/account_spec.rb +28 -0
  45. data/spec/lib/routengn_client/models/carrier_spec.rb +20 -0
  46. data/spec/lib/routengn_client/models/code_spec.rb +32 -0
  47. data/spec/lib/routengn_client/models/contact_spec.rb +57 -0
  48. data/spec/lib/routengn_client/models/inbound_end_point_group_spec.rb +33 -0
  49. data/spec/lib/routengn_client/models/inbound_rate_spec.rb +10 -0
  50. data/spec/lib/routengn_client/models/outbound_end_point_group_spec.rb +52 -0
  51. data/spec/lib/routengn_client/models/outbound_rate_spec.rb +10 -0
  52. data/spec/lib/routengn_client/models/rate_sheet_spec.rb +0 -0
  53. data/spec/lib/routengn_client/models/record_spec.rb +59 -0
  54. data/spec/lib/routengn_client/models/route_container_spec.rb +10 -0
  55. data/spec/lib/routengn_client/models/route_spec.rb +228 -0
  56. data/spec/lib/routengn_client/models/route_table_spec.rb +87 -0
  57. data/spec/lib/routengn_client/remote_model_spec.rb +60 -0
  58. data/spec/lib/routengn_client/request_spec.rb +14 -0
  59. data/spec/lib/routengn_client/response_spec.rb +29 -0
  60. data/spec/lib/routengn_client_spec.rb +5 -0
  61. data/spec/spec_helper.rb +34 -0
  62. data/spec/support/blueprints.rb +157 -0
  63. 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,3 @@
1
+ module RouteNGNClient
2
+ VERSION = '0.1.4'
3
+ 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,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe RouteNGNClient::Logging do
4
+
5
+ before do
6
+
7
+ end
8
+
9
+ 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,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe RouteNGNClient::InboundRate do
4
+
5
+ it "can be instanstiated" do
6
+ r = InboundRate.new
7
+ r.should be_an_instance_of(InboundRate)
8
+ end
9
+
10
+ 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