matrioska 0.0.2 → 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.
- checksums.yaml +7 -0
- data/.gitignore +21 -1
- data/CHANGELOG.md +6 -1
- data/Gemfile +1 -2
- data/Guardfile +3 -22
- data/LICENSE.txt +2 -2
- data/README.md +2 -6
- data/lib/matrioska/app_runner.rb +45 -24
- data/lib/matrioska/dial_with_apps.rb +37 -0
- data/lib/matrioska/plugin.rb +2 -19
- data/lib/matrioska/version.rb +1 -1
- data/matrioska.gemspec +3 -3
- data/spec/matrioska/app_runner_spec.rb +55 -51
- data/spec/matrioska/dial_with_apps_spec.rb +98 -0
- data/spec/spec_helper.rb +5 -2
- metadata +19 -45
- data/Gemfile.lock +0 -131
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 97fa774330c3c99750e07cba0a43977c191e18bb
|
4
|
+
data.tar.gz: 7ae46033c383b6b3e2fd17aae1f16fabe3b8df6d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6e4b7426ee636edb6ec407ea7c7a8932f1e1ab0369f5083a82d303c6cc7b6223a731408669f29674a5873d3090dd83908e1ce10baf11547745a82df69c0d9874
|
7
|
+
data.tar.gz: 4315f6b5bebcf743733c52eb2fe3c3b1ea54d0a851794cc116d0872930144154c91f77003b9bdc726555e0f2113839ef44ea5e2863d315decbe0509c17c80671
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
# develop
|
2
2
|
|
3
|
+
# Version 0.1.0
|
4
|
+
* Added DialWithApps for a simple integration with `#dial`
|
5
|
+
* Bugfixes
|
6
|
+
* Minor cleanup
|
7
|
+
|
3
8
|
# Version 0.0.2
|
4
9
|
* Downgraded Adhearsion version requirement to 2.1
|
5
10
|
|
6
11
|
# Version 0.0.1
|
7
|
-
* First official release
|
12
|
+
* First official release
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,24 +1,5 @@
|
|
1
|
-
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
4
|
-
guard 'rspec' do
|
1
|
+
guard 'rspec', cli: '--format documentation', all_on_start: true do
|
5
2
|
watch(%r{^spec/.+_spec\.rb$})
|
6
|
-
watch(%r{^lib/(.+)\.rb$}) { |m| "spec
|
7
|
-
watch('spec/spec_helper.rb') { "spec" }
|
8
|
-
|
9
|
-
# Rails example
|
10
|
-
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
-
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
-
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
-
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
-
watch('config/routes.rb') { "spec/routing" }
|
15
|
-
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
-
|
17
|
-
# Capybara request specs
|
18
|
-
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
19
|
-
|
20
|
-
# Turnip features and steps
|
21
|
-
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
-
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
3
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
4
|
+
watch('spec/spec_helper.rb') { "spec/" }
|
23
5
|
end
|
24
|
-
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License
|
2
2
|
|
3
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2013 Adhearsion Foundation Inc.
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining
|
6
6
|
a copy of this software and associated documentation files (the
|
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -7,17 +7,13 @@ By mapping controllers or blocks to the desired applications, a listener object
|
|
7
7
|
## Usage Example
|
8
8
|
|
9
9
|
```ruby
|
10
|
-
#inside your controller
|
10
|
+
# inside your controller
|
11
11
|
runner = Matrioska::AppRunner.new self
|
12
12
|
runner.map_app 3 do
|
13
13
|
logger.info "hi there!"
|
14
14
|
end
|
15
15
|
runner.map_app 5, AppController
|
16
16
|
|
17
|
-
call.on_end do
|
18
|
-
runner.stop
|
19
|
-
end
|
20
|
-
|
21
17
|
runner.start
|
22
18
|
```
|
23
19
|
|
@@ -42,4 +38,4 @@ Original author: [Luca Pradovera](https://github.com/polysics)
|
|
42
38
|
|
43
39
|
### Copyright
|
44
40
|
|
45
|
-
Copyright (c) 2013 Adhearsion Foundation Inc. MIT license (see LICENSE for details).
|
41
|
+
Copyright (c) 2013 Adhearsion Foundation Inc. MIT license (see LICENSE for details).
|
data/lib/matrioska/app_runner.rb
CHANGED
@@ -5,25 +5,22 @@ module Matrioska
|
|
5
5
|
def initialize(call)
|
6
6
|
@call = call
|
7
7
|
@app_map = {}
|
8
|
+
@running = false
|
8
9
|
end
|
9
10
|
|
10
11
|
def start
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
logger.debug "MATRIOSKA START CALLED"
|
13
|
+
unless @running
|
14
|
+
component = Punchblock::Component::Input.new mode: :dtmf, grammar: { value: grammar_accept }
|
15
|
+
logger.debug "MATRIOSKA STARTING LISTENER"
|
16
|
+
component.register_event_handler Punchblock::Event::Complete do |event|
|
17
|
+
handle_input_complete event
|
18
|
+
end
|
19
|
+
@call.write_and_await_response component if @call.active?
|
18
20
|
end
|
19
|
-
@call.write_and_await_response component
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
-
@app_map
|
24
|
-
end
|
25
|
-
|
26
|
-
def map_app(digit, controller=nil, &block)
|
23
|
+
def map_app(digit, controller = nil, &block)
|
27
24
|
digit = digit.to_s
|
28
25
|
range = "1234567890*#"
|
29
26
|
|
@@ -42,24 +39,48 @@ module Matrioska
|
|
42
39
|
@app_map[digit] = payload
|
43
40
|
end
|
44
41
|
|
42
|
+
def handle_input_complete(event)
|
43
|
+
logger.debug "MATRIOSKA HANDLING INPUT"
|
44
|
+
result = event.reason.respond_to?(:utterance) ? event.reason.utterance : nil
|
45
|
+
digit = parse_dtmf result
|
46
|
+
match_and_run digit unless @running
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def app_map
|
52
|
+
@app_map
|
53
|
+
end
|
54
|
+
|
45
55
|
def match_and_run(digit)
|
46
56
|
if match = @app_map[digit]
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
57
|
+
logger.debug "MATRIOSKA #match_and_run called with #{digit}"
|
58
|
+
@running = true
|
59
|
+
callback = lambda do |call|
|
60
|
+
@running = false
|
61
|
+
logger.debug "MATRIOSKA CALLBACK RESTARTING LISTENER"
|
62
|
+
if call.active?
|
63
|
+
start
|
64
|
+
else
|
65
|
+
logger.debug "MATRIOSKA CALLBACK NOT DOING ANYTHING BECAUSE CALL IS DEAD"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if match.is_a? Proc
|
70
|
+
logger.debug "MATRIOSKA EXECUTING #{match} AS BLOCK"
|
71
|
+
@call.execute_controller(nil, callback, &match)
|
72
|
+
end
|
73
|
+
|
51
74
|
if match.is_a? Class
|
52
75
|
payload = match.new(@call)
|
76
|
+
logger.debug "MATRIOSKA EXECUTING #{payload.to_s} AS CONTROLLER"
|
53
77
|
@call.execute_controller(payload, callback)
|
54
78
|
end
|
79
|
+
else
|
80
|
+
start
|
55
81
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
def handle_input_complete(event)
|
60
|
-
result = event.reason.respond_to?(:utterance) ? event.reason.utterance : nil
|
61
|
-
digit = parse_dtmf result
|
62
|
-
match_and_run digit
|
82
|
+
rescue Adhearsion::Call::Hangup
|
83
|
+
logger.debug "Matrioska terminated because the call was disconnected"
|
63
84
|
end
|
64
85
|
end
|
65
86
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Matrioska
|
2
|
+
module DialWithApps
|
3
|
+
def dial_with_local_apps(to, options = {}, &block)
|
4
|
+
dial = Adhearsion::CallController::Dial::ParallelConfirmationDial.new to, options, call
|
5
|
+
|
6
|
+
runner = Matrioska::AppRunner.new call
|
7
|
+
yield runner, dial
|
8
|
+
runner.start
|
9
|
+
|
10
|
+
dial.track_originating_call
|
11
|
+
dial.prep_calls
|
12
|
+
dial.place_calls
|
13
|
+
dial.await_completion
|
14
|
+
dial.cleanup_calls
|
15
|
+
dial.status
|
16
|
+
end
|
17
|
+
|
18
|
+
def dial_with_remote_apps(to, options = {}, &block)
|
19
|
+
dial = Adhearsion::CallController::Dial::ParallelConfirmationDial.new to, options, call
|
20
|
+
|
21
|
+
dial.track_originating_call
|
22
|
+
|
23
|
+
dial.prep_calls do |new_call|
|
24
|
+
new_call.on_joined call do
|
25
|
+
runner = Matrioska::AppRunner.new new_call
|
26
|
+
yield runner, dial
|
27
|
+
runner.start
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
dial.place_calls
|
32
|
+
dial.await_completion
|
33
|
+
dial.cleanup_calls
|
34
|
+
dial.status
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/matrioska/plugin.rb
CHANGED
@@ -1,29 +1,12 @@
|
|
1
1
|
module Matrioska
|
2
2
|
class Plugin < Adhearsion::Plugin
|
3
|
-
# Actions to perform when the plugin is loaded
|
4
|
-
#
|
5
|
-
init :matrioska do
|
6
|
-
logger.warn "Matrioska has been loaded"
|
7
|
-
end
|
8
|
-
|
9
|
-
# Basic configuration for the plugin
|
10
|
-
#
|
11
|
-
config :matrioska do
|
12
|
-
greeting "Hello", :desc => "What to use to greet users"
|
13
|
-
end
|
14
|
-
|
15
|
-
# Defining a Rake task is easy
|
16
|
-
# The following can be invoked with:
|
17
|
-
# rake plugin_demo:info
|
18
|
-
#
|
19
3
|
tasks do
|
20
4
|
namespace :matrioska do
|
21
|
-
desc "Prints the
|
22
|
-
task :
|
5
|
+
desc "Prints the Matrioska plugin version"
|
6
|
+
task :version do
|
23
7
|
STDOUT.puts "Matrioska plugin v. #{VERSION}"
|
24
8
|
end
|
25
9
|
end
|
26
10
|
end
|
27
|
-
|
28
11
|
end
|
29
12
|
end
|
data/lib/matrioska/version.rb
CHANGED
data/matrioska.gemspec
CHANGED
@@ -7,9 +7,10 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.version = Matrioska::VERSION
|
8
8
|
s.authors = ["Luca Pradovera"]
|
9
9
|
s.email = ["lpradovera@mojolingo.com"]
|
10
|
-
s.homepage = ""
|
10
|
+
s.homepage = "https://github.com/polysics/matrioska"
|
11
11
|
s.summary = %q{Adhearsion plugin for in-call apps}
|
12
12
|
s.description = %q{Adhearsion plugin for in-call apps. Provides a features-style interface to run applications in calls.}
|
13
|
+
s.license = 'MIT'
|
13
14
|
|
14
15
|
s.rubyforge_project = "matrioska"
|
15
16
|
|
@@ -17,8 +18,7 @@ Gem::Specification.new do |s|
|
|
17
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
19
|
s.require_paths = ["lib"]
|
19
20
|
|
20
|
-
s.add_runtime_dependency %q<adhearsion>, ["~> 2.
|
21
|
-
s.add_runtime_dependency %q<activesupport>, [">= 3.0.10"]
|
21
|
+
s.add_runtime_dependency %q<adhearsion>, ["~> 2.4"]
|
22
22
|
|
23
23
|
s.add_development_dependency %q<bundler>, ["~> 1.0"]
|
24
24
|
s.add_development_dependency %q<rspec>, ["~> 2.5"]
|
@@ -2,35 +2,40 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Matrioska
|
4
4
|
describe AppRunner do
|
5
|
-
let(:
|
6
|
-
|
7
|
-
|
5
|
+
let(:call_id) { SecureRandom.uuid }
|
6
|
+
let(:call) { Adhearsion::Call.new }
|
7
|
+
|
8
|
+
before do
|
9
|
+
double call, write_command: true, id: call_id
|
10
|
+
end
|
11
|
+
|
12
|
+
subject { AppRunner.new call }
|
13
|
+
|
14
|
+
class MockController < Adhearsion::CallController
|
15
|
+
def run
|
16
|
+
call.do_stuff_from_a_class
|
17
|
+
end
|
18
|
+
end
|
8
19
|
|
9
20
|
describe "#start" do
|
10
21
|
let(:grxml) {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
22
|
+
RubySpeech::GRXML.draw mode: 'dtmf', root: 'inputdigits' do
|
23
|
+
rule id: 'inputdigits', scope: 'public' do
|
24
|
+
one_of do
|
25
|
+
0.upto(9) { |d| item { d.to_s } }
|
26
|
+
item { "#" }
|
27
|
+
item { "*" }
|
18
28
|
end
|
19
29
|
end
|
20
|
-
|
30
|
+
end
|
31
|
+
}
|
21
32
|
|
22
33
|
let(:input_component) {
|
23
|
-
Punchblock::Component::Input.new
|
24
|
-
{ :mode => :dtmf,
|
25
|
-
:grammar => {
|
26
|
-
:value => grxml.to_s
|
27
|
-
}
|
28
|
-
}
|
29
|
-
)
|
34
|
+
Punchblock::Component::Input.new mode: :dtmf, grammar: { value: grxml }
|
30
35
|
}
|
31
36
|
|
32
37
|
it "should start the appropriate component" do
|
33
|
-
|
38
|
+
call.should_receive(:write_and_await_response).with(input_component)
|
34
39
|
subject.start
|
35
40
|
end
|
36
41
|
end
|
@@ -39,61 +44,60 @@ module Matrioska
|
|
39
44
|
context "with invalid input" do
|
40
45
|
let(:too_long) { "ab" }
|
41
46
|
let(:wrong) { "a" }
|
47
|
+
|
42
48
|
it "should raise if the first argument is not a single digit string in the range" do
|
43
|
-
expect { subject.map_app(too_long){} }.to raise_error ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
|
44
|
-
expect { subject.map_app(wrong){} }.to raise_error ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
|
49
|
+
expect { subject.map_app(too_long) {} }.to raise_error ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
|
50
|
+
expect { subject.map_app(wrong) {} }.to raise_error ArgumentError, "The first argument should be a single digit String or number in the range 1234567890*#"
|
45
51
|
end
|
46
52
|
|
47
53
|
it "raises if called without either a class or a block" do
|
48
|
-
|
54
|
+
expect { subject.map_app 1 }.to raise_error ArgumentError, "You need to provide a block or a controller name."
|
49
55
|
end
|
50
56
|
|
51
57
|
it "raises if passed both a class and a block" do
|
52
|
-
|
58
|
+
expect { subject.map_app(1, Object) {} }.to raise_error ArgumentError, "You cannot specify both a block and a controller name."
|
53
59
|
end
|
54
60
|
end
|
61
|
+
end
|
55
62
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
subject.app_map["3"].should be_a Proc
|
60
|
-
end
|
61
|
-
it "properly sets the map for a class" do
|
62
|
-
subject.map_app(3, Object)
|
63
|
-
subject.app_map["3"].should be_a Class
|
64
|
-
end
|
63
|
+
describe "#handle_input_complete" do
|
64
|
+
def mock_event(digit)
|
65
|
+
double 'Event', reason: double('Reason', utterance: "dtmf-#{digit}")
|
65
66
|
end
|
66
|
-
end
|
67
67
|
|
68
|
-
describe "#match_and_run" do
|
69
68
|
before do
|
70
|
-
subject.map_app(3) {
|
69
|
+
subject.map_app(3) { call.do_stuff_from_a_block }
|
71
70
|
subject.map_app(5, MockController)
|
72
71
|
end
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
context "if there is no match" do
|
74
|
+
it "does nothing, and restarts the launcher" do
|
75
|
+
call.should_receive(:execute_controller).never
|
76
|
+
subject.should_receive(:start).once
|
77
|
+
subject.handle_input_complete mock_event("4")
|
78
|
+
end
|
79
|
+
|
80
|
+
context "if the call has been hung up" do
|
81
|
+
before { call.should_receive(:write_and_await_response).and_raise Adhearsion::Call::Hangup }
|
82
|
+
|
83
|
+
it "should not raise Hangup but stop cleanly" do
|
84
|
+
subject.handle_input_complete mock_event("4")
|
85
|
+
end
|
86
|
+
end
|
78
87
|
end
|
79
88
|
|
80
89
|
it "executes the block if the payload is a Proc" do
|
81
|
-
|
90
|
+
call.should_receive(:do_stuff_from_a_block).once
|
82
91
|
subject.should_receive(:start).once
|
83
|
-
subject.
|
92
|
+
subject.handle_input_complete mock_event("3")
|
93
|
+
sleep 0.1 # Give the controller time to finish and the callback to fire
|
84
94
|
end
|
95
|
+
|
85
96
|
it "executes the controller if the payload is a Class" do
|
86
|
-
|
97
|
+
call.should_receive(:do_stuff_from_a_class).once
|
87
98
|
subject.should_receive(:start).once
|
88
|
-
subject.
|
89
|
-
|
90
|
-
end
|
91
|
-
|
92
|
-
describe "#handle_input_complete" do
|
93
|
-
let(:mock_event) { mock('Event', :reason => mock('Reason', :utterance => "dtmf-5")) }
|
94
|
-
it "runs #match_and_run" do
|
95
|
-
subject.should_receive(:match_and_run).with("5").once
|
96
|
-
subject.handle_input_complete(mock_event)
|
99
|
+
subject.handle_input_complete mock_event("5")
|
100
|
+
sleep 0.1 # Give the controller time to finish and the callback to fire
|
97
101
|
end
|
98
102
|
end
|
99
103
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'matrioska/dial_with_apps'
|
4
|
+
|
5
|
+
describe Matrioska::DialWithApps do
|
6
|
+
let(:call_id) { SecureRandom.uuid }
|
7
|
+
let(:call) { Adhearsion::Call.new }
|
8
|
+
let(:controller_class) { Class.new Adhearsion::CallController }
|
9
|
+
let(:controller) { controller_class.new call }
|
10
|
+
|
11
|
+
let(:to) { 'sip:foo@bar.com' }
|
12
|
+
let(:other_call_id) { SecureRandom.uuid }
|
13
|
+
let(:other_mock_call) { Adhearsion::OutboundCall.new }
|
14
|
+
|
15
|
+
let(:second_to) { 'sip:baz@bar.com' }
|
16
|
+
let(:second_other_call_id) { SecureRandom.uuid }
|
17
|
+
let(:second_other_mock_call) { Adhearsion::OutboundCall.new }
|
18
|
+
|
19
|
+
let(:mock_answered) { Punchblock::Event::Answered.new }
|
20
|
+
|
21
|
+
before do
|
22
|
+
controller_class.mixin described_class
|
23
|
+
call.wrapped_object.stub id: call_id, write_command: true
|
24
|
+
other_mock_call.wrapped_object.stub id: other_call_id, write_command: true
|
25
|
+
second_other_mock_call.wrapped_object.stub id: second_other_call_id, write_command: true
|
26
|
+
end
|
27
|
+
|
28
|
+
def mock_end(reason = :hangup_command)
|
29
|
+
Punchblock::Event::End.new.tap { |event| event.stub reason: reason }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#dial_with_local_apps" do
|
33
|
+
it "starts an app listener on the originating call using the passed block, dials the call to the correct endpoint, and returns a dial status object" do
|
34
|
+
mock_app_runner = Matrioska::AppRunner.new call
|
35
|
+
Matrioska::AppRunner.should_receive(:new).once.with(call).and_return mock_app_runner
|
36
|
+
mock_app_runner.should_receive(:foo).once.with(instance_of(Adhearsion::CallController::Dial::ParallelConfirmationDial))
|
37
|
+
mock_app_runner.should_receive(:start).once
|
38
|
+
|
39
|
+
Adhearsion::OutboundCall.should_receive(:new).and_return other_mock_call
|
40
|
+
other_mock_call.should_receive(:dial).with(to, :from => 'foo').once
|
41
|
+
|
42
|
+
dial_thread = Thread.new do
|
43
|
+
status = controller.dial_with_local_apps(to, :from => 'foo') do |runner, dial|
|
44
|
+
runner.foo dial
|
45
|
+
end
|
46
|
+
|
47
|
+
status.should be_a Adhearsion::CallController::Dial::DialStatus
|
48
|
+
joined_status = status.joins[status.calls.first]
|
49
|
+
joined_status.duration.should == 0.0
|
50
|
+
joined_status.result.should == :no_answer
|
51
|
+
end
|
52
|
+
|
53
|
+
sleep 0.1
|
54
|
+
other_mock_call << mock_end
|
55
|
+
dial_thread.join.should be_true
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#dial_with_remote_apps" do
|
60
|
+
it "starts an app listener on the joined call using the passed block, dials the call to the correct endpoint, and returns a dial status object" do
|
61
|
+
call.should_receive(:answer).once
|
62
|
+
|
63
|
+
mock_app_runner = Matrioska::AppRunner.new other_mock_call
|
64
|
+
|
65
|
+
Matrioska::AppRunner.should_receive(:new).once.with(second_other_mock_call).and_return mock_app_runner
|
66
|
+
mock_app_runner.should_receive(:foo).once.with(instance_of(Adhearsion::CallController::Dial::ParallelConfirmationDial))
|
67
|
+
mock_app_runner.should_receive(:start).once
|
68
|
+
|
69
|
+
Adhearsion::OutboundCall.should_receive(:new).and_return other_mock_call, second_other_mock_call
|
70
|
+
|
71
|
+
other_mock_call.should_receive(:dial).with(to, :from => 'foo').once
|
72
|
+
other_mock_call.should_receive(:hangup).once.and_return do
|
73
|
+
other_mock_call << mock_end
|
74
|
+
end
|
75
|
+
|
76
|
+
second_other_mock_call.should_receive(:dial).with(second_to, :from => 'foo').once
|
77
|
+
second_other_mock_call.should_receive(:join).once.and_return do
|
78
|
+
second_other_mock_call << Punchblock::Event::Joined.new(call_uri: call_id)
|
79
|
+
end
|
80
|
+
|
81
|
+
dial_thread = Thread.new do
|
82
|
+
status = controller.dial_with_remote_apps([to, second_to], :from => 'foo') do |runner, dial|
|
83
|
+
runner.foo dial
|
84
|
+
end
|
85
|
+
|
86
|
+
status.should be_a Adhearsion::CallController::Dial::DialStatus
|
87
|
+
joined_status = status.joins[status.calls.first]
|
88
|
+
joined_status.duration.should == 0.0
|
89
|
+
joined_status.result.should == :no_answer
|
90
|
+
end
|
91
|
+
|
92
|
+
sleep 0.1
|
93
|
+
second_other_mock_call << Punchblock::Event::Answered.new
|
94
|
+
second_other_mock_call << mock_end
|
95
|
+
dial_thread.join.should be_true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -5,7 +5,10 @@ RSpec.configure do |config|
|
|
5
5
|
config.color_enabled = true
|
6
6
|
config.tty = true
|
7
7
|
|
8
|
-
config.filter_run :
|
8
|
+
config.filter_run focus: true
|
9
9
|
config.run_all_when_everything_filtered = true
|
10
|
-
end
|
11
10
|
|
11
|
+
config.before :suite do
|
12
|
+
Adhearsion::Logging.start Adhearsion::Logging.default_appenders, :trace, Adhearsion.config.platform.logging.formatter
|
13
|
+
end
|
14
|
+
end
|
metadata
CHANGED
@@ -1,52 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: matrioska
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Luca Pradovera
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-08-29 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: adhearsion
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
21
|
-
version: '2.
|
19
|
+
version: '2.4'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
29
|
-
version: '2.
|
30
|
-
- !ruby/object:Gem::Dependency
|
31
|
-
name: activesupport
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: 3.0.10
|
38
|
-
type: :runtime
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: 3.0.10
|
26
|
+
version: '2.4'
|
46
27
|
- !ruby/object:Gem::Dependency
|
47
28
|
name: bundler
|
48
29
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
30
|
requirements:
|
51
31
|
- - ~>
|
52
32
|
- !ruby/object:Gem::Version
|
@@ -54,7 +34,6 @@ dependencies:
|
|
54
34
|
type: :development
|
55
35
|
prerelease: false
|
56
36
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
37
|
requirements:
|
59
38
|
- - ~>
|
60
39
|
- !ruby/object:Gem::Version
|
@@ -62,7 +41,6 @@ dependencies:
|
|
62
41
|
- !ruby/object:Gem::Dependency
|
63
42
|
name: rspec
|
64
43
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
44
|
requirements:
|
67
45
|
- - ~>
|
68
46
|
- !ruby/object:Gem::Version
|
@@ -70,7 +48,6 @@ dependencies:
|
|
70
48
|
type: :development
|
71
49
|
prerelease: false
|
72
50
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
51
|
requirements:
|
75
52
|
- - ~>
|
76
53
|
- !ruby/object:Gem::Version
|
@@ -78,33 +55,29 @@ dependencies:
|
|
78
55
|
- !ruby/object:Gem::Dependency
|
79
56
|
name: rake
|
80
57
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
58
|
requirements:
|
83
|
-
- -
|
59
|
+
- - '>='
|
84
60
|
- !ruby/object:Gem::Version
|
85
61
|
version: '0'
|
86
62
|
type: :development
|
87
63
|
prerelease: false
|
88
64
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
65
|
requirements:
|
91
|
-
- -
|
66
|
+
- - '>='
|
92
67
|
- !ruby/object:Gem::Version
|
93
68
|
version: '0'
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: guard-rspec
|
96
71
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
72
|
requirements:
|
99
|
-
- -
|
73
|
+
- - '>='
|
100
74
|
- !ruby/object:Gem::Version
|
101
75
|
version: '0'
|
102
76
|
type: :development
|
103
77
|
prerelease: false
|
104
78
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
79
|
requirements:
|
107
|
-
- -
|
80
|
+
- - '>='
|
108
81
|
- !ruby/object:Gem::Version
|
109
82
|
version: '0'
|
110
83
|
description: Adhearsion plugin for in-call apps. Provides a features-style interface
|
@@ -119,43 +92,44 @@ files:
|
|
119
92
|
- .rspec
|
120
93
|
- CHANGELOG.md
|
121
94
|
- Gemfile
|
122
|
-
- Gemfile.lock
|
123
95
|
- Guardfile
|
124
96
|
- LICENSE.txt
|
125
97
|
- README.md
|
126
98
|
- Rakefile
|
127
99
|
- lib/matrioska.rb
|
128
100
|
- lib/matrioska/app_runner.rb
|
101
|
+
- lib/matrioska/dial_with_apps.rb
|
129
102
|
- lib/matrioska/plugin.rb
|
130
103
|
- lib/matrioska/version.rb
|
131
104
|
- matrioska.gemspec
|
132
105
|
- spec/matrioska/app_runner_spec.rb
|
106
|
+
- spec/matrioska/dial_with_apps_spec.rb
|
133
107
|
- spec/spec_helper.rb
|
134
|
-
homepage:
|
135
|
-
licenses:
|
108
|
+
homepage: https://github.com/polysics/matrioska
|
109
|
+
licenses:
|
110
|
+
- MIT
|
111
|
+
metadata: {}
|
136
112
|
post_install_message:
|
137
113
|
rdoc_options: []
|
138
114
|
require_paths:
|
139
115
|
- lib
|
140
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
-
none: false
|
142
117
|
requirements:
|
143
|
-
- -
|
118
|
+
- - '>='
|
144
119
|
- !ruby/object:Gem::Version
|
145
120
|
version: '0'
|
146
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
-
none: false
|
148
122
|
requirements:
|
149
|
-
- -
|
123
|
+
- - '>='
|
150
124
|
- !ruby/object:Gem::Version
|
151
125
|
version: '0'
|
152
126
|
requirements: []
|
153
127
|
rubyforge_project: matrioska
|
154
|
-
rubygems_version:
|
128
|
+
rubygems_version: 2.0.3
|
155
129
|
signing_key:
|
156
|
-
specification_version:
|
130
|
+
specification_version: 4
|
157
131
|
summary: Adhearsion plugin for in-call apps
|
158
132
|
test_files:
|
159
133
|
- spec/matrioska/app_runner_spec.rb
|
134
|
+
- spec/matrioska/dial_with_apps_spec.rb
|
160
135
|
- spec/spec_helper.rb
|
161
|
-
has_rdoc:
|
data/Gemfile.lock
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
matrioska (0.0.1)
|
5
|
-
activesupport (>= 3.0.10)
|
6
|
-
adhearsion (~> 2.2)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: http://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activesupport (3.2.10)
|
12
|
-
i18n (~> 0.6)
|
13
|
-
multi_json (~> 1.0)
|
14
|
-
adhearsion (2.2.0)
|
15
|
-
activesupport (~> 3.0)
|
16
|
-
adhearsion-loquacious (~> 1.9)
|
17
|
-
bundler (~> 1.0)
|
18
|
-
celluloid (~> 0.12, >= 0.12.1)
|
19
|
-
countdownlatch
|
20
|
-
deep_merge
|
21
|
-
ffi (~> 1.0)
|
22
|
-
future-resource (~> 1.0)
|
23
|
-
girl_friday
|
24
|
-
has-guarded-handlers (~> 1.5)
|
25
|
-
logging (~> 1.8)
|
26
|
-
pry
|
27
|
-
punchblock (~> 1.4)
|
28
|
-
rake
|
29
|
-
ruby_speech (~> 1.0)
|
30
|
-
thor
|
31
|
-
adhearsion-loquacious (1.9.3)
|
32
|
-
blather (0.8.2)
|
33
|
-
activesupport (>= 2.3.11)
|
34
|
-
eventmachine (>= 1.0.0)
|
35
|
-
girl_friday
|
36
|
-
niceogiri (~> 1.0)
|
37
|
-
nokogiri (~> 1.5, >= 1.5.6)
|
38
|
-
celluloid (0.12.4)
|
39
|
-
facter (>= 1.6.12)
|
40
|
-
timers (>= 1.0.0)
|
41
|
-
celluloid-io (0.12.1)
|
42
|
-
celluloid (~> 0.12.0)
|
43
|
-
nio4r (>= 0.4.0)
|
44
|
-
coderay (1.0.8)
|
45
|
-
connection_pool (0.9.3)
|
46
|
-
countdownlatch (1.0.0)
|
47
|
-
deep_merge (1.0.0)
|
48
|
-
diff-lcs (1.1.3)
|
49
|
-
eventmachine (1.0.0)
|
50
|
-
facter (1.6.17)
|
51
|
-
ffi (1.2.0)
|
52
|
-
future-resource (1.0.0)
|
53
|
-
girl_friday (0.11.1)
|
54
|
-
connection_pool (~> 0.9.0)
|
55
|
-
rubinius-actor
|
56
|
-
guard (1.5.0)
|
57
|
-
listen (>= 0.4.2)
|
58
|
-
lumberjack (>= 1.0.2)
|
59
|
-
pry (>= 0.9.10)
|
60
|
-
thor (>= 0.14.6)
|
61
|
-
guard-rspec (2.1.0)
|
62
|
-
guard (>= 1.1)
|
63
|
-
rspec (~> 2.11)
|
64
|
-
has-guarded-handlers (1.5.0)
|
65
|
-
i18n (0.6.1)
|
66
|
-
json (1.7.5)
|
67
|
-
listen (0.5.3)
|
68
|
-
little-plugger (1.1.3)
|
69
|
-
logging (1.8.1)
|
70
|
-
little-plugger (>= 1.1.3)
|
71
|
-
multi_json (>= 1.3.6)
|
72
|
-
lumberjack (1.0.2)
|
73
|
-
method_source (0.8.1)
|
74
|
-
multi_json (1.5.0)
|
75
|
-
niceogiri (1.1.1)
|
76
|
-
nokogiri (~> 1.5)
|
77
|
-
nio4r (0.4.3)
|
78
|
-
nokogiri (1.5.6)
|
79
|
-
pry (0.9.10)
|
80
|
-
coderay (~> 1.0.5)
|
81
|
-
method_source (~> 0.8)
|
82
|
-
slop (~> 3.3.1)
|
83
|
-
punchblock (1.7.1)
|
84
|
-
activesupport (~> 3.0)
|
85
|
-
blather (>= 0.7.0)
|
86
|
-
celluloid (~> 0.12, >= 0.12.3)
|
87
|
-
future-resource (~> 1.0)
|
88
|
-
has-guarded-handlers (~> 1.5)
|
89
|
-
niceogiri (~> 1.1)
|
90
|
-
ruby_ami (~> 1.2, >= 1.2.1)
|
91
|
-
ruby_fs (~> 1.0)
|
92
|
-
ruby_speech (~> 1.0)
|
93
|
-
state_machine (~> 1.0)
|
94
|
-
rake (0.9.2.2)
|
95
|
-
rspec (2.11.0)
|
96
|
-
rspec-core (~> 2.11.0)
|
97
|
-
rspec-expectations (~> 2.11.0)
|
98
|
-
rspec-mocks (~> 2.11.0)
|
99
|
-
rspec-core (2.11.1)
|
100
|
-
rspec-expectations (2.11.3)
|
101
|
-
diff-lcs (~> 1.1.3)
|
102
|
-
rspec-mocks (2.11.3)
|
103
|
-
rubinius-actor (0.0.2)
|
104
|
-
rubinius-core-api
|
105
|
-
rubinius-core-api (0.0.1)
|
106
|
-
ruby_ami (1.2.6)
|
107
|
-
celluloid-io (~> 0.12.0)
|
108
|
-
countdownlatch (~> 1.0)
|
109
|
-
future-resource
|
110
|
-
girl_friday
|
111
|
-
ruby_fs (1.0.3)
|
112
|
-
celluloid-io (~> 0.12.0)
|
113
|
-
json
|
114
|
-
ruby_speech (1.0.2)
|
115
|
-
activesupport (>= 3.0.7)
|
116
|
-
niceogiri (~> 1.1, >= 1.1.1)
|
117
|
-
nokogiri (~> 1.5, >= 1.5.6)
|
118
|
-
slop (3.3.3)
|
119
|
-
state_machine (1.1.2)
|
120
|
-
thor (0.16.0)
|
121
|
-
timers (1.0.2)
|
122
|
-
|
123
|
-
PLATFORMS
|
124
|
-
ruby
|
125
|
-
|
126
|
-
DEPENDENCIES
|
127
|
-
bundler (~> 1.0)
|
128
|
-
guard-rspec
|
129
|
-
matrioska!
|
130
|
-
rake
|
131
|
-
rspec (~> 2.5)
|