sipwizard 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +9 -3
  3. data/Guardfile +6 -5
  4. data/lib/sipwizard.rb +3 -0
  5. data/lib/sipwizard/account.rb +101 -0
  6. data/lib/sipwizard/binding.rb +40 -0
  7. data/lib/sipwizard/cdr.rb +59 -0
  8. data/lib/sipwizard/connection.rb +31 -7
  9. data/lib/sipwizard/customer.rb +81 -0
  10. data/lib/sipwizard/dial_plan.rb +91 -0
  11. data/lib/sipwizard/provider.rb +99 -0
  12. data/lib/sipwizard/provider_binding.rb +53 -0
  13. data/lib/sipwizard/rate.rb +81 -0
  14. data/lib/sipwizard/relation.rb +27 -0
  15. data/lib/sipwizard/version.rb +1 -1
  16. data/sipwizard.gemspec +6 -4
  17. data/spec/lib/sipwizard/account_spec.rb +80 -0
  18. data/spec/lib/sipwizard/binding_spec.rb +22 -0
  19. data/spec/lib/sipwizard/cdr_spec.rb +21 -0
  20. data/spec/lib/sipwizard/configuration_spec.rb +1 -1
  21. data/spec/lib/sipwizard/connection_spec.rb +19 -25
  22. data/spec/lib/sipwizard/customer_spec.rb +80 -0
  23. data/spec/lib/sipwizard/dial_plan_spec.rb +95 -0
  24. data/spec/lib/sipwizard/provider_binding_spec.rb +22 -0
  25. data/spec/lib/sipwizard/provider_spec.rb +107 -0
  26. data/spec/lib/sipwizard/rate_spec.rb +83 -0
  27. data/spec/lib/sipwizard_spec.rb +1 -1
  28. data/spec/spec.yml.sample +7 -0
  29. data/spec/spec_helper.rb +32 -9
  30. data/spec/vcr/sipsorcery/cdr/count.yml +70 -0
  31. data/spec/vcr/sipsorcery/cdr/get.yml +38 -0
  32. data/spec/vcr/sipsorcery/customeraccount/add.yml +73 -0
  33. data/spec/vcr/sipsorcery/customeraccount/count.yml +36 -0
  34. data/spec/vcr/sipsorcery/customeraccount/delete.yml +36 -0
  35. data/spec/vcr/sipsorcery/customeraccount/get.yml +36 -0
  36. data/spec/vcr/sipsorcery/customeraccount/update.yml +38 -0
  37. data/spec/vcr/sipsorcery/dialplan/add.yml +75 -0
  38. data/spec/vcr/sipsorcery/dialplan/copy.yml +36 -0
  39. data/spec/vcr/sipsorcery/dialplan/count.yml +36 -0
  40. data/spec/vcr/sipsorcery/dialplan/delete.yml +36 -0
  41. data/spec/vcr/sipsorcery/dialplan/get.yml +37 -0
  42. data/spec/vcr/sipsorcery/dialplan/update.yml +39 -0
  43. data/spec/vcr/sipsorcery/rate/add.yml +73 -0
  44. data/spec/vcr/sipsorcery/rate/count.yml +36 -0
  45. data/spec/vcr/sipsorcery/rate/delete.yml +36 -0
  46. data/spec/vcr/sipsorcery/rate/get.yml +36 -0
  47. data/spec/vcr/sipsorcery/rate/update.yml +38 -0
  48. data/spec/vcr/sipsorcery/sipaccount/add.yml +74 -0
  49. data/spec/vcr/sipsorcery/sipaccount/count.yml +36 -0
  50. data/spec/vcr/sipsorcery/sipaccount/delete.yml +69 -0
  51. data/spec/vcr/sipsorcery/sipaccount/get.yml +36 -0
  52. data/spec/vcr/sipsorcery/sipaccount/update.yml +37 -0
  53. data/spec/vcr/sipsorcery/sipaccountbinding/count.yml +36 -0
  54. data/spec/vcr/sipsorcery/sipaccountbinding/get.yml +36 -0
  55. data/spec/vcr/sipsorcery/sipprovider/add.yml +74 -0
  56. data/spec/vcr/sipsorcery/sipprovider/count.yml +36 -0
  57. data/spec/vcr/sipsorcery/sipprovider/delete.yml +36 -0
  58. data/spec/vcr/sipsorcery/sipprovider/get.yml +36 -0
  59. data/spec/vcr/sipsorcery/sipprovider/update.yml +38 -0
  60. data/spec/vcr/sipsorcery/sipproviderbinding/count.yml +36 -0
  61. data/spec/vcr/sipsorcery/sipproviderbinding/get.yml +69 -0
  62. 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
@@ -1,3 +1,3 @@
1
1
  module Sipwizard
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -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.add_development_dependency "rake"
23
- spec.add_development_dependency 'rack', "~> 1.5.2"
24
- spec.add_development_dependency "faraday", '~> 0.8.9'
25
- spec.add_development_dependency "faraday_middleware", "~> 0.9.0"
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
@@ -7,7 +7,7 @@ describe Sipwizard::Configuration do
7
7
  let(:api_key){ 'foo' }
8
8
 
9
9
  it 'has a api_key' do
10
- subject.api_key.must_equal api_key
10
+ subject.api_key.should eq api_key
11
11
  end
12
12
  end
13
13
  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{ Sipwizard::Connection.new }
5
+ subject{ described_class.new }
6
6
 
7
7
  it 'returns a Faraday::Connection with the nethttp adapter' do
8
- subject.faraday_connection.must_be_instance_of Faraday::Connection
9
- subject.faraday_connection.builder.handlers.must_include default_faraday_adapter
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 '.uri_for_path' do
13
- let(:path){ 'bar' }
14
- subject{ Sipwizard::Connection.uri_for_path(path) }
12
+ describe '#get(params)' do
13
+ subject{ described_class.new.get('cdr/count') }
15
14
 
16
- it "returns the base_uri of the api" do
17
- subject.must_equal "#{Sipwizard::Connection::API_PATH}#{path}"
18
- end
19
- end
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
- subject { connection.get(path, params) }
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
- it 'calls connection.get with the right uri' do
35
- response = Minitest::Mock.new
36
- faraday_connection.expect :get, response, [uri, params]
37
- subject
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