sipwizard 0.0.1 → 0.1.0

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 (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