sipwizard 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +9 -3
- data/Guardfile +6 -5
- data/lib/sipwizard.rb +3 -0
- data/lib/sipwizard/account.rb +101 -0
- data/lib/sipwizard/binding.rb +40 -0
- data/lib/sipwizard/cdr.rb +59 -0
- data/lib/sipwizard/connection.rb +31 -7
- data/lib/sipwizard/customer.rb +81 -0
- data/lib/sipwizard/dial_plan.rb +91 -0
- data/lib/sipwizard/provider.rb +99 -0
- data/lib/sipwizard/provider_binding.rb +53 -0
- data/lib/sipwizard/rate.rb +81 -0
- data/lib/sipwizard/relation.rb +27 -0
- data/lib/sipwizard/version.rb +1 -1
- data/sipwizard.gemspec +6 -4
- data/spec/lib/sipwizard/account_spec.rb +80 -0
- data/spec/lib/sipwizard/binding_spec.rb +22 -0
- data/spec/lib/sipwizard/cdr_spec.rb +21 -0
- data/spec/lib/sipwizard/configuration_spec.rb +1 -1
- data/spec/lib/sipwizard/connection_spec.rb +19 -25
- data/spec/lib/sipwizard/customer_spec.rb +80 -0
- data/spec/lib/sipwizard/dial_plan_spec.rb +95 -0
- data/spec/lib/sipwizard/provider_binding_spec.rb +22 -0
- data/spec/lib/sipwizard/provider_spec.rb +107 -0
- data/spec/lib/sipwizard/rate_spec.rb +83 -0
- data/spec/lib/sipwizard_spec.rb +1 -1
- data/spec/spec.yml.sample +7 -0
- data/spec/spec_helper.rb +32 -9
- data/spec/vcr/sipsorcery/cdr/count.yml +70 -0
- data/spec/vcr/sipsorcery/cdr/get.yml +38 -0
- data/spec/vcr/sipsorcery/customeraccount/add.yml +73 -0
- data/spec/vcr/sipsorcery/customeraccount/count.yml +36 -0
- data/spec/vcr/sipsorcery/customeraccount/delete.yml +36 -0
- data/spec/vcr/sipsorcery/customeraccount/get.yml +36 -0
- data/spec/vcr/sipsorcery/customeraccount/update.yml +38 -0
- data/spec/vcr/sipsorcery/dialplan/add.yml +75 -0
- data/spec/vcr/sipsorcery/dialplan/copy.yml +36 -0
- data/spec/vcr/sipsorcery/dialplan/count.yml +36 -0
- data/spec/vcr/sipsorcery/dialplan/delete.yml +36 -0
- data/spec/vcr/sipsorcery/dialplan/get.yml +37 -0
- data/spec/vcr/sipsorcery/dialplan/update.yml +39 -0
- data/spec/vcr/sipsorcery/rate/add.yml +73 -0
- data/spec/vcr/sipsorcery/rate/count.yml +36 -0
- data/spec/vcr/sipsorcery/rate/delete.yml +36 -0
- data/spec/vcr/sipsorcery/rate/get.yml +36 -0
- data/spec/vcr/sipsorcery/rate/update.yml +38 -0
- data/spec/vcr/sipsorcery/sipaccount/add.yml +74 -0
- data/spec/vcr/sipsorcery/sipaccount/count.yml +36 -0
- data/spec/vcr/sipsorcery/sipaccount/delete.yml +69 -0
- data/spec/vcr/sipsorcery/sipaccount/get.yml +36 -0
- data/spec/vcr/sipsorcery/sipaccount/update.yml +37 -0
- data/spec/vcr/sipsorcery/sipaccountbinding/count.yml +36 -0
- data/spec/vcr/sipsorcery/sipaccountbinding/get.yml +36 -0
- data/spec/vcr/sipsorcery/sipprovider/add.yml +74 -0
- data/spec/vcr/sipsorcery/sipprovider/count.yml +36 -0
- data/spec/vcr/sipsorcery/sipprovider/delete.yml +36 -0
- data/spec/vcr/sipsorcery/sipprovider/get.yml +36 -0
- data/spec/vcr/sipsorcery/sipprovider/update.yml +38 -0
- data/spec/vcr/sipsorcery/sipproviderbinding/count.yml +36 -0
- data/spec/vcr/sipsorcery/sipproviderbinding/get.yml +69 -0
- metadata +129 -6
@@ -0,0 +1,99 @@
|
|
1
|
+
module Sipwizard
|
2
|
+
class Provider < Hashie::Trash
|
3
|
+
API_PATH_MAP = {
|
4
|
+
count: 'sipprovider/count',
|
5
|
+
find: 'sipprovider/get',
|
6
|
+
create: 'sipprovider/add',
|
7
|
+
update: 'sipprovider/update',
|
8
|
+
delete: 'sipprovider/delete'
|
9
|
+
}
|
10
|
+
|
11
|
+
string_to_bool = ->(string) { string == "true" }
|
12
|
+
|
13
|
+
property :id, from: :ID
|
14
|
+
property :provider_name, from: :ProviderName
|
15
|
+
property :provider_username, from: :ProviderUsername
|
16
|
+
property :provider_password, from: :ProviderPassword
|
17
|
+
property :provider_server, from: :ProviderServer
|
18
|
+
property :provider_auth_username, from: :ProviderAuthUsername
|
19
|
+
property :provider_outbound_proxy, from: :ProviderOutboundProxy
|
20
|
+
property :provider_type, from: :ProviderType
|
21
|
+
property :provider_from, from: :ProviderFrom
|
22
|
+
property :custom_headers, from: :CustomHeaders
|
23
|
+
property :register_contact, from: :RegisterContact
|
24
|
+
property :register_expiry, from: :RegisterExpiry
|
25
|
+
property :register_server, from: :RegisterServer
|
26
|
+
property :register_realm, from: :RegisterRealm
|
27
|
+
property :register_enabled, from: :RegisterEnabled, transform_with: ->(b) { string_to_bool.call(b) }
|
28
|
+
property :gv_callback_number, from: :GVCallbackNumber
|
29
|
+
property :gv_callback_pattern, from: :GVCallbackPattern
|
30
|
+
property :gv_callback_type, from: :GVCallbackType
|
31
|
+
|
32
|
+
alias :register_enabled? :register_enabled
|
33
|
+
|
34
|
+
def self.count(params={})
|
35
|
+
response = Connection.new.get(API_PATH_MAP[:count], params)
|
36
|
+
|
37
|
+
response['Success'] ? response['Result'] : -1
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.where(params)
|
41
|
+
Relation.new.where(params)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.find(id)
|
45
|
+
relation = self.where({ ID: id }).count(1)
|
46
|
+
|
47
|
+
result = Connection.new.get(API_PATH_MAP[:find], relation.relation)
|
48
|
+
|
49
|
+
return nil unless result['Success']
|
50
|
+
|
51
|
+
self.new(result['Result'][0])
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.build_for_request(h)
|
55
|
+
provider = self.new(h)
|
56
|
+
provider = Hash[provider.map{ |k,v| ["#{k}".camelize, v] }]
|
57
|
+
provider['ID'] = provider.delete('Id')
|
58
|
+
provider['GVCallbackType'] = provider.delete('GvCallbackType')
|
59
|
+
provider['GVCallbackNumber'] = provider.delete('GvCallbackType')
|
60
|
+
provider['GVCallbackPattern'] = provider.delete('GvCallbackPattern')
|
61
|
+
|
62
|
+
provider.delete_if{ |_,v| v.nil? } #delete all the keys for which we dont have value
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.create(params)
|
66
|
+
payload = self.build_for_request(params)
|
67
|
+
result = Connection.new.post(API_PATH_MAP[:create], payload)
|
68
|
+
|
69
|
+
raise ArgumentError.new(result["Error"]) unless result['Success']
|
70
|
+
|
71
|
+
result['Result'] #ID
|
72
|
+
end
|
73
|
+
|
74
|
+
def save
|
75
|
+
payload = Provider.build_for_request(self.to_hash)
|
76
|
+
result = Connection.new.post(API_PATH_MAP[:update], payload)
|
77
|
+
raise ArgumentError.new(result["Error"]) unless result['Success']
|
78
|
+
|
79
|
+
result['Result'] #ID
|
80
|
+
end
|
81
|
+
|
82
|
+
def binding(cache=true)
|
83
|
+
return @binding if @binding && cache
|
84
|
+
@binding = ProviderBinding.find_by_provider_id(self.id)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.delete(id)
|
88
|
+
result = Connection.new.get(API_PATH_MAP[:delete], {id: id})
|
89
|
+
|
90
|
+
raise ArgumentError.new(result["Error"]) unless result['Success']
|
91
|
+
|
92
|
+
result['Result'] #true | false
|
93
|
+
end
|
94
|
+
|
95
|
+
def delete
|
96
|
+
Provider.delete(self.id)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Sipwizard
|
2
|
+
class ProviderBinding < Hashie::Trash
|
3
|
+
API_PATH_MAP={
|
4
|
+
count: 'sipproviderbinding/count',
|
5
|
+
find: 'sipproviderbinding/get'
|
6
|
+
}
|
7
|
+
|
8
|
+
string_to_bool = ->(string) { string == "true" }
|
9
|
+
|
10
|
+
property :id, from: :ID
|
11
|
+
property :provider_id, from: :ProviderID
|
12
|
+
property :provider_name, from: :ProviderName
|
13
|
+
property :registration_failur_message, from: :RegistrationFailureMessage
|
14
|
+
property :last_register_time, from: :LastRegisterTime
|
15
|
+
property :next_registration_time, from: :NextRegistrationTime
|
16
|
+
property :last_register_attempt, from: :LastRegisterAttempt
|
17
|
+
property :is_registered, from: :IsRegistered, transform_with: ->(b) { string_to_bool.call(b) }
|
18
|
+
property :binding_expiry, from: :BindingExpiry
|
19
|
+
property :binding_uri, from: :BindingURI
|
20
|
+
property :registrar_sip_socket, from: :RegistrarSIPSocket
|
21
|
+
property :cseq, from: :CSeq
|
22
|
+
|
23
|
+
def self.count(params={})
|
24
|
+
response = Connection.new.get(API_PATH_MAP[:count], params)
|
25
|
+
|
26
|
+
response['Success'] ? response['Result'] : -1
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.where(params)
|
30
|
+
Relation.new.where(params)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.find(id)
|
34
|
+
relation = self.where({ ID: id }).count(1)
|
35
|
+
|
36
|
+
result = Connection.new.get(API_PATH_MAP[:find], relation.relation)
|
37
|
+
|
38
|
+
return nil unless result['Success']
|
39
|
+
|
40
|
+
self.new(result['Result'][0])
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.find_by_provider_id(id)
|
44
|
+
relation = self.where({ ProviderID: id }).count(1)
|
45
|
+
|
46
|
+
result = Connection.new.get(API_PATH_MAP[:find], relation.relation)
|
47
|
+
|
48
|
+
return nil unless result['Success']
|
49
|
+
|
50
|
+
self.new(result['Result'][0])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Sipwizard
|
2
|
+
class Rate < Hashie::Trash
|
3
|
+
API_PATH_MAP={
|
4
|
+
count: 'rate/count',
|
5
|
+
create: 'rate/add',
|
6
|
+
find: 'rate/get',
|
7
|
+
update: 'rate/update',
|
8
|
+
delete: 'rate/delete'
|
9
|
+
}
|
10
|
+
|
11
|
+
property :id, from: :ID
|
12
|
+
property :description, from: :Description
|
13
|
+
property :prefix, from: :Prefix
|
14
|
+
property :rate, from: :Rate
|
15
|
+
property :rate_code, from: :RateCode
|
16
|
+
property :setup_cost, from: :SetupCost
|
17
|
+
property :inserted, from: :Inserted
|
18
|
+
property :increment_seconds, from: :IncrementSeconds
|
19
|
+
|
20
|
+
def self.count(params={})
|
21
|
+
response = connection.get(API_PATH_MAP[:count], params)
|
22
|
+
|
23
|
+
response['Success'] ? response['Result'] : -1
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.build_for_request(h)
|
27
|
+
rate = self.new(h)
|
28
|
+
rate = Hash[rate.map{ |k,v| ["#{k}".camelize, v] }]
|
29
|
+
rate['ID'] = rate.delete('Id')
|
30
|
+
|
31
|
+
rate.delete_if{ |_,v| v.nil? } #delete all the keys for which we dont have value
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.create(params)
|
35
|
+
payload = self.build_for_request(params)
|
36
|
+
result = connection.post(API_PATH_MAP[:create], payload)
|
37
|
+
|
38
|
+
raise ArgumentError.new(result["Error"]) unless result['Success']
|
39
|
+
|
40
|
+
result['Result'] #ID
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.where(params)
|
44
|
+
Relation.new.where(params)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.find(id)
|
48
|
+
relation = self.where({ ID: id }).count(1)
|
49
|
+
result = connection.get(API_PATH_MAP[:find], relation.relation)
|
50
|
+
|
51
|
+
return nil unless result['Success']
|
52
|
+
|
53
|
+
self.new(result['Result'][0])
|
54
|
+
end
|
55
|
+
|
56
|
+
def save
|
57
|
+
payload = Rate.build_for_request(self.to_hash)
|
58
|
+
result = Connection.new(api_type: :accounting).post(API_PATH_MAP[:update], payload)
|
59
|
+
raise ArgumentError.new(result["Error"]) unless result['Success']
|
60
|
+
|
61
|
+
result['Result'] #ID
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.delete(id)
|
65
|
+
result = connection.get(API_PATH_MAP[:delete], {id: id})
|
66
|
+
|
67
|
+
raise ArgumentError.new(result["Error"]) unless result['Success']
|
68
|
+
|
69
|
+
result['Result'] #true | false
|
70
|
+
end
|
71
|
+
|
72
|
+
def delete
|
73
|
+
Rate.delete(self.id)
|
74
|
+
end
|
75
|
+
private
|
76
|
+
|
77
|
+
def self.connection
|
78
|
+
Connection.new(api_type: :accounting)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Sipwizard
|
2
|
+
class Relation
|
3
|
+
attr_reader :relation
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@relation = Hashie::Clash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def where(params)
|
10
|
+
@relation.where( hash_to_query(params) )
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def count(nb)
|
15
|
+
@relation.merge!({count: nb})
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
#Hack to comply with the api spec ... which sucks
|
22
|
+
def hash_to_query(h)
|
23
|
+
h = Hash[h.map{|k,v| [k, "\"#{v}\""]}]
|
24
|
+
Rack::Utils.unescape Rack::Utils.build_query(h)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/sipwizard/version.rb
CHANGED
data/sipwizard.gemspec
CHANGED
@@ -19,8 +19,10 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.
|
23
|
-
spec.
|
24
|
-
spec.
|
25
|
-
spec.
|
22
|
+
spec.add_dependency "rake"
|
23
|
+
spec.add_dependency 'rack', "~> 1.5.2"
|
24
|
+
spec.add_dependency "faraday", '~> 0.8.9'
|
25
|
+
spec.add_dependency "faraday_middleware", "~> 0.9.0"
|
26
|
+
spec.add_dependency "hashie", "~> 2.0.5"
|
27
|
+
spec.add_dependency "activesupport"
|
26
28
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sipwizard::Account do
|
4
|
+
describe '.count(params={})' do
|
5
|
+
subject{ described_class.count }
|
6
|
+
it 'returns a result' do
|
7
|
+
expect(subject).to be_instance_of Fixnum
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.find(id)' do
|
12
|
+
let(:id){ settings['sensitive_data']['ID'] }
|
13
|
+
|
14
|
+
subject{ described_class.find(id) }
|
15
|
+
|
16
|
+
it 'returns an account' do
|
17
|
+
subject.should be_instance_of Sipwizard::Account
|
18
|
+
subject.id.should eq id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.create(params)' do
|
23
|
+
let(:params) do
|
24
|
+
{
|
25
|
+
username: "foo",
|
26
|
+
password: "bar"
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
subject{ described_class.create(params) }
|
31
|
+
|
32
|
+
it 'creates a new account' do
|
33
|
+
response = subject
|
34
|
+
expect(response).not_to be_nil
|
35
|
+
expect(response).to be_instance_of String
|
36
|
+
expect(response).to match(/(?:\w|-)+/)
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'if the username already exists' do
|
40
|
+
it 'raise an argument error' do
|
41
|
+
expect do
|
42
|
+
described_class.create(params)
|
43
|
+
described_class.create({username: 'foo', password: 'bra'})
|
44
|
+
end.to raise_exception(ArgumentError)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '.save' do
|
50
|
+
let(:id){ settings['sensitive_data']['ID'] }
|
51
|
+
let(:account){ described_class.find(id) }
|
52
|
+
|
53
|
+
before{ account.should be_instance_of Sipwizard::Account }
|
54
|
+
|
55
|
+
subject{ account.save }
|
56
|
+
|
57
|
+
it 'updates the account' do
|
58
|
+
account.avatar_url = "foo"
|
59
|
+
response = subject
|
60
|
+
expect(response).not_to be_nil
|
61
|
+
expect(response).to be_instance_of String
|
62
|
+
expect(response).to match(/(?:\w|-)+/)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'delete' do
|
67
|
+
let(:id){ settings['sensitive_data']['ID'] }
|
68
|
+
|
69
|
+
let(:account){ described_class.find(id) }
|
70
|
+
|
71
|
+
before{ account.should be_instance_of Sipwizard::Account }
|
72
|
+
|
73
|
+
subject{ account.delete }
|
74
|
+
|
75
|
+
it 'delete the account' do
|
76
|
+
response = subject
|
77
|
+
expect(response).to be_true
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sipwizard::Binding do
|
4
|
+
describe '.count' do
|
5
|
+
subject{ described_class.count }
|
6
|
+
|
7
|
+
it 'returns the nb of account bindings' do
|
8
|
+
expect(subject).to be_instance_of Fixnum
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.find(id)' do
|
13
|
+
let(:id){ settings['sensitive_data']['ACCOUNT_BINDING_ID'] }
|
14
|
+
|
15
|
+
subject{ described_class.find(id) }
|
16
|
+
|
17
|
+
it 'returns an account binding' do
|
18
|
+
subject.should be_instance_of Sipwizard::Binding
|
19
|
+
subject.id.should eq id
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sipwizard::Cdr do
|
4
|
+
describe '.count' do
|
5
|
+
subject{ described_class.count }
|
6
|
+
it 'returns a result' do
|
7
|
+
expect(subject).to be_instance_of Fixnum
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.find(id)' do
|
12
|
+
let(:id){ settings['sensitive_data']['CDR_ID'] }
|
13
|
+
|
14
|
+
subject{ described_class.find(id) }
|
15
|
+
|
16
|
+
it 'returns an account' do
|
17
|
+
subject.should be_instance_of Sipwizard::Cdr
|
18
|
+
subject.id.should eq id
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,40 +2,34 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Sipwizard::Connection do
|
4
4
|
let(:default_faraday_adapter) { Faraday::Adapter::NetHttp }
|
5
|
-
subject{
|
5
|
+
subject{ described_class.new }
|
6
6
|
|
7
7
|
it 'returns a Faraday::Connection with the nethttp adapter' do
|
8
|
-
subject.faraday_connection.
|
9
|
-
subject.faraday_connection.builder.handlers.
|
8
|
+
subject.faraday_connection.should be_instance_of Faraday::Connection
|
9
|
+
subject.faraday_connection.builder.handlers.should include(default_faraday_adapter)
|
10
10
|
end
|
11
11
|
|
12
|
-
describe '
|
13
|
-
|
14
|
-
subject{ Sipwizard::Connection.uri_for_path(path) }
|
12
|
+
describe '#get(params)' do
|
13
|
+
subject{ described_class.new.get('cdr/count') }
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
describe 'get(params)' do
|
22
|
-
let(:params){ { foo: 'bar' } }
|
23
|
-
let(:path){ '/path' }
|
24
|
-
let(:uri){ Sipwizard::Connection.uri_for_path(path) }
|
25
|
-
let(:faraday_connection) { Minitest::Mock.new }
|
26
|
-
let(:connection) do
|
27
|
-
Sipwizard::Connection.new.tap do |connection|
|
28
|
-
connection.faraday_connection = faraday_connection
|
15
|
+
context 'when the api key is valid' do
|
16
|
+
it 'doesnt complain' do
|
17
|
+
expect(subject["Error"]).to be_nil
|
18
|
+
expect(subject["Success"]).to be_true
|
29
19
|
end
|
30
20
|
end
|
31
21
|
|
32
|
-
|
22
|
+
context 'when the api key is invalid' do
|
23
|
+
let(:connection){ described_class.new }
|
24
|
+
subject{ connection.get('cdr/count') }
|
25
|
+
before do
|
26
|
+
connection.faraday_connection.headers['apikey'] = 'bar'
|
27
|
+
end
|
33
28
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
faraday_connection.verify
|
29
|
+
it 'returns an error' do
|
30
|
+
expect(subject["Error"]).not_to be_nil
|
31
|
+
expect(subject["Success"]).to be_false
|
32
|
+
end
|
39
33
|
end
|
40
34
|
end
|
41
35
|
end
|