voipms_rates 1.0.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.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/README.md +55 -0
- data/Rakefile +1 -0
- data/lib/voipms_rates.rb +3 -0
- data/lib/voipms_rates.rb~ +4 -0
- data/lib/voipms_rates/controller_methods.rb +69 -0
- data/lib/voipms_rates/controller_methods.rb~ +69 -0
- data/lib/voipms_rates/plugin.rb +52 -0
- data/lib/voipms_rates/plugin.rb~ +53 -0
- data/lib/voipms_rates/version.rb +3 -0
- data/lib/voipms_rates/version.rb~ +3 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/spec_helper.rb~ +21 -0
- data/spec/support/vcr_setup.rb +5 -0
- data/spec/support/vcr_setup.rb~ +5 -0
- data/spec/voipms_rates/controller_methods_spec.rb +100 -0
- data/spec/voipms_rates/controller_methods_spec.rb~ +100 -0
- metadata +208 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2f7dbba975776307743338eaaea14dfcc16ac458
|
4
|
+
data.tar.gz: ed82f5766454b66d3d54ee26ce3e04dab092f1d4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 42206a0d55a8e60b0fe57b6b37c8f4bc971b29484e63c8b917df2d05f1ad45e6a070401df39e33942f19f6ebf57c9f3b2f8b8045742b8da92458657b74fa66ac
|
7
|
+
data.tar.gz: f8d81ff82ea99a071c7d2ee74f42fdcb382f77170c6f0964d02dc2eaf7a1680f8b09abae47055509305247237e3abfe2ea29e638b12e11a14f12859c47a43e47
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
VoipmsRates
|
2
|
+
==========================
|
3
|
+
|
4
|
+
This [Adhearsion](adhearsion.com) plugin fetches the per minute rate from voip.ms for any phone number. It uses the
|
5
|
+
public [voip.ms API](https://voip.ms/rates/xml.php).
|
6
|
+
|
7
|
+
> Note that this is intended to be used within an Adhearsion app. If you require this gem to use anywhere else than an
|
8
|
+
> Adhearsion app, it will probably not work out of the box.
|
9
|
+
|
10
|
+
# Installation
|
11
|
+
Add `gem 'voipms_rates'` to your Gemfile and run `bundle install`.
|
12
|
+
|
13
|
+
# Configuration
|
14
|
+
The gem will fetch the standard rate by default. If you have changed the routing settings in your voip.ms account
|
15
|
+
(voip.ms > Main Menu > Account Settings > Account Routing) and use premium routing for Canadian and/or international
|
16
|
+
numbers, you can override the defaults by adding the following lines to your app's `config/adhearsion.rb`:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
##
|
20
|
+
# voipms_rates settings override
|
21
|
+
config.voipms_rates.canada_use_premium = true # default value is false
|
22
|
+
config.voipms_rates.intl_use_premium = true # default value is false
|
23
|
+
```
|
24
|
+
|
25
|
+
Alternatively, you can set the `AHN_VOIPMS_RATES_CANADA_USE_PREMIUM` and `AHN_VOIPMS_RATES_INTL_USE_PREMIUM`
|
26
|
+
environment variables to `true`.
|
27
|
+
|
28
|
+
# Usage
|
29
|
+
In your app's controller:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
include VoipmsRates::ControllerMethods
|
33
|
+
|
34
|
+
def run
|
35
|
+
@rate = get_rate_for(call.to)
|
36
|
+
say "This call will cost #{@rate} USD per minute."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
## `get_rate_for`
|
42
|
+
Expects one argument, either the [E.164](http://en.wikipedia.org/wiki/E.164) phone number without `+` or the `call.to`
|
43
|
+
string directly from the controller.
|
44
|
+
|
45
|
+
Example of an E.164 phone number:
|
46
|
+
|
47
|
+
Consider the following US number: `(555) 123-4567`. The US country code is `+1`, which we add to the beginning of the
|
48
|
+
phone number. Thus, we get `+1 (555) 123-4567`. We then strip any special chracters and the leading `+` whih results in
|
49
|
+
`15551234567`. This is the number `get_rate_for` expects.
|
50
|
+
|
51
|
+
The method can also handle standard SIP strings. For the sample US phone number above, that would be
|
52
|
+
`sip:15551234567@127.0.0.1`. This string is stored in `call.to` within the controller for the dialled number.
|
53
|
+
|
54
|
+
# License
|
55
|
+
MIT, see the `LICENSE` file within the repo.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/voipms_rates.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
module VoipmsRates
|
2
|
+
module ControllerMethods
|
3
|
+
|
4
|
+
require 'rest-client'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
# Parameters:
|
8
|
+
# phone_number [Int] The number for which we want to get the rate
|
9
|
+
def get_rate_for(phone_number)
|
10
|
+
if phone_number.match(/(\d*)@.*/)
|
11
|
+
@digits = phone_number.match(/(\d*)@.*/)[1]
|
12
|
+
elsif phone_number.match(/[\d]+/)
|
13
|
+
@digits = phone_number.match(/(\d+)/)[1]
|
14
|
+
else
|
15
|
+
raise(TypeError, "Unexpected input, received '#{phone_number}'", caller)
|
16
|
+
end
|
17
|
+
|
18
|
+
return try_patterns(@digits)
|
19
|
+
end
|
20
|
+
|
21
|
+
def try_patterns(digits)
|
22
|
+
rates_endpoint = Adhearsion.config[:voipms_rates].rates_endpoint
|
23
|
+
# The rates API only works with part of the phone number. If it gets the full phone number, it won't find the
|
24
|
+
# rate. If it doesn't get enough digits, it won't find the rate either. And if it gets too many digits, it won't
|
25
|
+
# find the rate...
|
26
|
+
# For example:
|
27
|
+
# To get the rate for '33912345678' (France), you would need to send '339'
|
28
|
+
# To get the rate for '15145551234' (Canada), you would need to send '1514'
|
29
|
+
# To get the rate for '12125551234' (USA), you would need to send '1'
|
30
|
+
#
|
31
|
+
high_count = digits.length >= 5 ? 5 : digits.length # This speeds things up with shorter numbers
|
32
|
+
for i in high_count.downto(1) do
|
33
|
+
pattern = digits[0, i]
|
34
|
+
api_response = RestClient.get(rates_endpoint, {
|
35
|
+
params: {
|
36
|
+
pattern: pattern
|
37
|
+
}
|
38
|
+
})
|
39
|
+
|
40
|
+
xml_doc = Nokogiri::XML(api_response)
|
41
|
+
|
42
|
+
if xml_doc.xpath('/results')[0]
|
43
|
+
country = xml_doc.at_xpath('/results/item/short_description').content.to_s
|
44
|
+
return xml_doc.at_xpath('/results/item/rate_premium').content.to_f if ((country === 'Canada' && Adhearsion.config[:voipms_rates].canada_use_premium) || ((country != 'Canada' || country != 'USA') && Adhearsion.config[:voipms_rates].intl_use_premium))
|
45
|
+
return xml_doc.at_xpath('/results/item/rate').content.to_f
|
46
|
+
|
47
|
+
# We use the premium route for Canada but the value route for all other destinations.
|
48
|
+
# Because the API sends back both premium and value rates, this has to be done:
|
49
|
+
#
|
50
|
+
# country = xml_doc.at_xpath('/results/item/short_description').content.to_s
|
51
|
+
# case country
|
52
|
+
# when 'Canada'
|
53
|
+
# return xml_doc.at_xpath('/results/item/rate_premium').content.to_f
|
54
|
+
# else
|
55
|
+
# return xml_doc.at_xpath('/results/item/rate').content.to_f
|
56
|
+
# end
|
57
|
+
elsif i === 1 && xml_doc.xpath('error')[0]
|
58
|
+
error_code = xml_doc.at_xpath('/error/code').content.to_s
|
59
|
+
error_desc = xml_doc.at_xpath('/error/description').content.to_s
|
60
|
+
|
61
|
+
logger.error("No rate found for '#{pattern}', error code '#{error_code}' (#{error_desc})")
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private :try_patterns
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module VoipmsRates
|
2
|
+
module ControllerMethods
|
3
|
+
|
4
|
+
require 'rest-client'
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
# Parameters:
|
8
|
+
# phone_number [Int] The number for which we want to get the rate
|
9
|
+
def get_rate_for(phone_number)
|
10
|
+
if phone_number.match(/(\d*)@.*/)
|
11
|
+
@digits = phone_number.match(/(\d*)@.*/)[1]
|
12
|
+
elsif phone_number.match(/[\d]+/)
|
13
|
+
@digits = phone_number.match(/(\d+)/)[1]
|
14
|
+
else
|
15
|
+
raise(TypeError)
|
16
|
+
end
|
17
|
+
|
18
|
+
return try_patterns(@digits)
|
19
|
+
end
|
20
|
+
|
21
|
+
def try_patterns(digits)
|
22
|
+
rates_endpoint = Adhearsion.config[:voipms_rates].rates_endpoint
|
23
|
+
# The rates API only works with part of the phone number. If it gets the full phone number, it won't find the
|
24
|
+
# rate. If it doesn't get enough digits, it won't find the rate either. And if it gets too many digits, it won't
|
25
|
+
# find the rate...
|
26
|
+
# For example:
|
27
|
+
# To get the rate for '33912345678' (France), you would need to send '339'
|
28
|
+
# To get the rate for '15145551234' (Canada), you would need to send '1514'
|
29
|
+
# To get the rate for '12125551234' (USA), you would need to send '1'
|
30
|
+
#
|
31
|
+
high_count = digits.length >= 5 ? 5 : digits.length # This speeds things up with shorter numbers
|
32
|
+
for i in high_count.downto(1) do
|
33
|
+
pattern = digits[0, i]
|
34
|
+
api_response = RestClient.get(rates_endpoint, {
|
35
|
+
params: {
|
36
|
+
pattern: pattern
|
37
|
+
}
|
38
|
+
})
|
39
|
+
|
40
|
+
xml_doc = Nokogiri::XML(api_response)
|
41
|
+
|
42
|
+
if xml_doc.xpath('/results')[0]
|
43
|
+
country = xml_doc.at_xpath('/results/item/short_description').content.to_s
|
44
|
+
return xml_doc.at_xpath('/results/item/rate_premium').content.to_f if ((country === 'Canada' && Adhearsion.config[:voipms_rates].canada_use_premium) || ((country != 'Canada' || country != 'USA') && Adhearsion.config[:voipms_rates].intl_use_premium))
|
45
|
+
return xml_doc.at_xpath('/results/item/rate').content.to_f
|
46
|
+
|
47
|
+
# We use the premium route for Canada but the value route for all other destinations.
|
48
|
+
# Because the API sends back both premium and value rates, this has to be done:
|
49
|
+
#
|
50
|
+
# country = xml_doc.at_xpath('/results/item/short_description').content.to_s
|
51
|
+
# case country
|
52
|
+
# when 'Canada'
|
53
|
+
# return xml_doc.at_xpath('/results/item/rate_premium').content.to_f
|
54
|
+
# else
|
55
|
+
# return xml_doc.at_xpath('/results/item/rate').content.to_f
|
56
|
+
# end
|
57
|
+
elsif i === 1 && xml_doc.xpath('error')[0]
|
58
|
+
error_code = xml_doc.at_xpath('/error/code').content.to_s
|
59
|
+
error_desc = xml_doc.at_xpath('/error/description').content.to_s
|
60
|
+
|
61
|
+
logger.error("No rate found for '#{pattern}', error code '#{error_code}' (#{error_desc})")
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private :try_patterns
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module VoipmsRates
|
2
|
+
class Plugin < Adhearsion::Plugin
|
3
|
+
|
4
|
+
require_relative "version"
|
5
|
+
|
6
|
+
# Actions to perform when the plugin is loaded
|
7
|
+
#
|
8
|
+
init :voipms_rates do
|
9
|
+
logger.warn "VoipmsRates has been loaded"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Basic configuration for the plugin
|
13
|
+
#
|
14
|
+
config :voipms_rates do
|
15
|
+
rates_endpoint 'https://www.voip.ms/rates/xmlapi.php', desc: "The URL for voip.ms' rates API endpoint"
|
16
|
+
canada_use_premium false, desc: "Set to true if you are using premium routing for calls to Canada or false for
|
17
|
+
standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
|
18
|
+
intl_use_premium false, desc: "Set to true if you are using premium routing for International calls or false for
|
19
|
+
standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Defining a Rake task is easy
|
23
|
+
# The following can be invoked with:
|
24
|
+
# rake plugin_demo:info
|
25
|
+
#
|
26
|
+
tasks do
|
27
|
+
namespace :voipms_rates do
|
28
|
+
desc "Prints the PluginTemplate information"
|
29
|
+
task :info do
|
30
|
+
STDOUT.puts "VoipmsRates plugin v. #{VERSION}"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Checks the current Canada routing setting (Should match your settings on voip.ms > Account Settings >
|
34
|
+
Account Routing)"
|
35
|
+
task :canada_use_premium do
|
36
|
+
rate = Adhearsion.config[:voipms_rates].canada_use_premium ? 'premium' : 'standard'
|
37
|
+
STDOUT.puts "Using Canada #{rate} routes rate."
|
38
|
+
STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Checks the current International routing setting (Should match your settings on voip.ms > Account
|
42
|
+
Settings > Account Routing)"
|
43
|
+
task :intl_use_premium do
|
44
|
+
rate = Adhearsion.config[:voipms_rates].intl_use_premium ? 'premium' : 'standard'
|
45
|
+
STDOUT.puts "Using international #{rate} routes rate."
|
46
|
+
STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module VoipmsRates
|
2
|
+
class Plugin < Adhearsion::Plugin
|
3
|
+
|
4
|
+
require_relative "version"
|
5
|
+
|
6
|
+
# Actions to perform when the plugin is loaded
|
7
|
+
#
|
8
|
+
init :voipms_rates do
|
9
|
+
logger.warn "VoipmsRates has been loaded"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Basic configuration for the plugin
|
13
|
+
#
|
14
|
+
config :voipms_rates do
|
15
|
+
rates_endpoint 'https://www.voip.ms/rates/xmlapi.php', desc: "The URL for voip.ms' rates API endpoint"
|
16
|
+
canada_use_premium false, desc: "Set to true if you are using premium routing for calls to Canada or false for
|
17
|
+
standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
|
18
|
+
intl_use_premium false, desc: "Set to true if you are using premium routing for International calls or false for
|
19
|
+
standard routing (change this setting on voip.ms > Account Settings > Account Routing)"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Defining a Rake task is easy
|
23
|
+
# The following can be invoked with:
|
24
|
+
# rake plugin_demo:info
|
25
|
+
#
|
26
|
+
tasks do
|
27
|
+
namespace :voipms_rates do
|
28
|
+
desc "Prints the PluginTemplate information"
|
29
|
+
task :info do
|
30
|
+
STDOUT.puts "VoipmsRates plugin v. #{VERSION}"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Checks the current Canada routing setting (Should match your settings on voip.ms > Account Settings >
|
34
|
+
Account Routing)"
|
35
|
+
task :canada_use_premium do
|
36
|
+
rate = Adhearsion.config[:voipms_rates].canada_use_premium ? 'premium' : 'standard'
|
37
|
+
STDOUT.puts "Using Canada #{rate} routes rate."
|
38
|
+
# TODO edit with instructions to set in config file
|
39
|
+
STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
|
40
|
+
end
|
41
|
+
|
42
|
+
desc "Checks the current International routing setting (Should match your settings on voip.ms > Account
|
43
|
+
Settings > Account Routing)"
|
44
|
+
task :intl_use_premium do
|
45
|
+
rate = Adhearsion.config[:voipms_rates].intl_use_premium ? 'premium' : 'standard'
|
46
|
+
STDOUT.puts "Using international #{rate} routes rate."
|
47
|
+
STDOUT.puts "The value can be changed in your app's config file at config/adhearsion.rb"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'adhearsion'
|
2
|
+
require 'voipms_rates'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
# Require any .rb file in spec/support
|
6
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.color = true
|
10
|
+
config.tty = true
|
11
|
+
|
12
|
+
config.filter_run :focus => true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
|
15
|
+
# config.before(:each) do
|
16
|
+
# stub_request(:get, /https:\/\/www\.voip\.ms\/rates\/xmlapi\.php/).
|
17
|
+
# with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
18
|
+
# to_return(:status => 200, :body => "", :headers => {})
|
19
|
+
# end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'adhearsion'
|
2
|
+
require 'voipms_rates'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
# Require any .rb file in spec/support
|
6
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.color = true
|
10
|
+
config.tty = true
|
11
|
+
|
12
|
+
config.filter_run :focus => true
|
13
|
+
config.run_all_when_everything_filtered = true
|
14
|
+
|
15
|
+
config.before(:each) do
|
16
|
+
stub_request(:get, /https:\/\/www\.voip\.ms\/rates\/xmlapi\.php/).
|
17
|
+
with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'User-Agent'=>'Ruby'}).
|
18
|
+
to_return(:status => 200, :body => "", :headers => {})
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module VoipmsRates
|
4
|
+
describe ControllerMethods do
|
5
|
+
describe "mixed in to a CallController" do
|
6
|
+
|
7
|
+
class TestController < Adhearsion::CallController
|
8
|
+
include VoipmsRates::ControllerMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:mock_call) { double 'Call' }
|
12
|
+
|
13
|
+
subject do
|
14
|
+
TestController.new mock_call
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#get_rate_for' do
|
18
|
+
|
19
|
+
let(:canadian_number) { '15145551234' }
|
20
|
+
let(:us_number) { '12125551234' }
|
21
|
+
let(:french_number) { '33953123456' }
|
22
|
+
let(:unroutable_number) { '9' }
|
23
|
+
let(:sip_string) { 'sip:15145551234@127.0.0.1' }
|
24
|
+
let(:invalid_string) { 'invalid number' }
|
25
|
+
|
26
|
+
context 'when the premium rate is requested' do
|
27
|
+
|
28
|
+
context 'with a valid number' do
|
29
|
+
it 'returns the premium rate for Canada' do
|
30
|
+
# This setting is toggled with `rake voipms_rates:canada_use_premium`
|
31
|
+
Adhearsion.config[:voipms_rates].canada_use_premium = true
|
32
|
+
VCR.use_cassette('canada_premium_rate') do
|
33
|
+
expect(subject.get_rate_for(canadian_number)).to eq(0.009)
|
34
|
+
end
|
35
|
+
Adhearsion.config[:voipms_rates].canada_use_premium = false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns the premium rate for the US' do
|
39
|
+
VCR.use_cassette('us_premium_rate') do
|
40
|
+
expect(subject.get_rate_for(us_number)).to eq(0.01)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns the premium rate for France' do
|
45
|
+
# This setting is toggled with `rake voipms_rates:intl_use_premium`
|
46
|
+
Adhearsion.config[:voipms_rates].intl_use_premium = true
|
47
|
+
VCR.use_cassette('france_premium_rate') do
|
48
|
+
expect(subject.get_rate_for(french_number)).to eq(0.0431)
|
49
|
+
end
|
50
|
+
Adhearsion.config[:voipms_rates].intl_use_premium = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with an unroutable number' do
|
55
|
+
it 'returns "nil"' do
|
56
|
+
VCR.use_cassette('unroutable_number') do
|
57
|
+
expect(subject.get_rate_for(unroutable_number)).to eq(nil)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when the premium rate isn't requested" do
|
64
|
+
context 'with a valid number' do
|
65
|
+
it 'returns the value rate' do
|
66
|
+
VCR.use_cassette('canada_standard_rate') do
|
67
|
+
expect(subject.get_rate_for(canadian_number)).to eq(0.0052)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with an unroutable number' do
|
73
|
+
it 'returns "nil"' do
|
74
|
+
VCR.use_cassette('unroutable_number') do
|
75
|
+
expect(subject.get_rate_for(unroutable_number)).to eq(nil)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with a sip string' do
|
81
|
+
it 'returns the rate' do
|
82
|
+
VCR.use_cassette('sip_string') do
|
83
|
+
expect(subject.get_rate_for(sip_string)).to eq(0.0052)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with an invalid string' do
|
90
|
+
it 'returns a TypeError' do
|
91
|
+
VCR.use_cassette('invalid_string') do
|
92
|
+
expect{subject.get_rate_for(invalid_string)}.to raise_error(TypeError)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module VoipmsRates
|
4
|
+
describe ControllerMethods do
|
5
|
+
describe "mixed in to a CallController" do
|
6
|
+
|
7
|
+
class TestController < Adhearsion::CallController
|
8
|
+
include VoipmsRates::ControllerMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:mock_call) { double 'Call' }
|
12
|
+
|
13
|
+
subject do
|
14
|
+
TestController.new mock_call
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#get_rate_for' do
|
18
|
+
|
19
|
+
let(:canadian_number) { '15145551234' }
|
20
|
+
let(:us_number) { '12125551234' }
|
21
|
+
let(:french_number) { '33953123456' }
|
22
|
+
let(:unroutable_number) { '9' }
|
23
|
+
let(:sip_string) { 'sip:15145551234@127.0.0.1' }
|
24
|
+
let(:invalid_string) { 'invalid number' }
|
25
|
+
|
26
|
+
context 'when the premium rate is requested' do
|
27
|
+
|
28
|
+
context 'with a valid number' do
|
29
|
+
it 'returns the premium rate for Canada' do
|
30
|
+
# This setting is toggled with `rake voipms_rates:canada_use_premium`
|
31
|
+
Adhearsion.config[:voipms_rates].canada_use_premium = true
|
32
|
+
VCR.use_cassette('canada_premium_rate') do
|
33
|
+
expect(subject.get_rate_for(canadian_number)).to eq(0.009)
|
34
|
+
end
|
35
|
+
Adhearsion.config[:voipms_rates].canada_use_premium = false
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns the premium rate for the US' do
|
39
|
+
VCR.use_cassette('us_premium_rate') do
|
40
|
+
expect(subject.get_rate_for(us_number)).to eq(0.01)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns the premium rate for France' do
|
45
|
+
# This setting is toggled with `rake voipms_rates:intl_use_premium`
|
46
|
+
Adhearsion.config[:voipms_rates].intl_use_premium = true
|
47
|
+
VCR.use_cassette('france_premium_rate') do
|
48
|
+
expect(subject.get_rate_for(french_number)).to eq(0.0431)
|
49
|
+
end
|
50
|
+
Adhearsion.config[:voipms_rates].intl_use_premium = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with an unroutable number' do
|
55
|
+
it 'returns "nil"' do
|
56
|
+
VCR.use_cassette('unroutable_number') do
|
57
|
+
expect(subject.get_rate_for(unroutable_number)).to eq(nil)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when the premium rate isn't requested" do
|
64
|
+
context 'with a valid number' do
|
65
|
+
it 'returns the value rate' do
|
66
|
+
VCR.use_cassette('canada_standard_rate') do
|
67
|
+
expect(subject.get_rate_for(canadian_number)).to eq(0.0052)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with an unroutable number' do
|
73
|
+
it 'returns "nil"' do
|
74
|
+
VCR.use_cassette('unroutable_number') do
|
75
|
+
expect(subject.get_rate_for(unroutable_number)).to eq(nil)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with a sip string' do
|
81
|
+
it 'returns the rate' do
|
82
|
+
VCR.use_cassette('sip_string') do
|
83
|
+
expect(subject.get_rate_for(sip_string)).to eq(0.0052)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'with an invalid string' do
|
90
|
+
it 'returns a TypeError' do
|
91
|
+
VCR.use_cassette('invalid_string') do
|
92
|
+
expect{subject.get_rate_for(invalid_string)}.to raise_error
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
metadata
ADDED
@@ -0,0 +1,208 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: voipms_rates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Coaxial
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: adhearsion
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.10
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.10
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rest-client
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.8.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.8.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.6.6.2
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.6.6.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard-rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: webmock
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.21.0
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.21.0
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: vcr
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.9.3
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 2.9.3
|
153
|
+
description: Uses the voip.ms public API to fetch premium or value rates per minute
|
154
|
+
for any phone number.
|
155
|
+
email:
|
156
|
+
- py@poujade.org
|
157
|
+
executables: []
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- Gemfile
|
162
|
+
- README.md
|
163
|
+
- Rakefile
|
164
|
+
- lib/voipms_rates.rb
|
165
|
+
- lib/voipms_rates.rb~
|
166
|
+
- lib/voipms_rates/controller_methods.rb
|
167
|
+
- lib/voipms_rates/controller_methods.rb~
|
168
|
+
- lib/voipms_rates/plugin.rb
|
169
|
+
- lib/voipms_rates/plugin.rb~
|
170
|
+
- lib/voipms_rates/version.rb
|
171
|
+
- lib/voipms_rates/version.rb~
|
172
|
+
- spec/spec_helper.rb
|
173
|
+
- spec/spec_helper.rb~
|
174
|
+
- spec/support/vcr_setup.rb
|
175
|
+
- spec/support/vcr_setup.rb~
|
176
|
+
- spec/voipms_rates/controller_methods_spec.rb
|
177
|
+
- spec/voipms_rates/controller_methods_spec.rb~
|
178
|
+
homepage: ''
|
179
|
+
licenses:
|
180
|
+
- MIT
|
181
|
+
metadata: {}
|
182
|
+
post_install_message:
|
183
|
+
rdoc_options: []
|
184
|
+
require_paths:
|
185
|
+
- lib
|
186
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
187
|
+
requirements:
|
188
|
+
- - ">="
|
189
|
+
- !ruby/object:Gem::Version
|
190
|
+
version: '0'
|
191
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
requirements: []
|
197
|
+
rubyforge_project: voipms_rates
|
198
|
+
rubygems_version: 2.2.2
|
199
|
+
signing_key:
|
200
|
+
specification_version: 4
|
201
|
+
summary: Get voip.ms calling rates for given phone numbers.
|
202
|
+
test_files:
|
203
|
+
- spec/spec_helper.rb
|
204
|
+
- spec/spec_helper.rb~
|
205
|
+
- spec/support/vcr_setup.rb
|
206
|
+
- spec/support/vcr_setup.rb~
|
207
|
+
- spec/voipms_rates/controller_methods_spec.rb
|
208
|
+
- spec/voipms_rates/controller_methods_spec.rb~
|