punchblock 0.4.3 → 0.5.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.
- data/CHANGELOG.md +3 -0
- data/bin/punchblock-console +11 -10
- data/lib/punchblock.rb +2 -1
- data/lib/punchblock/client.rb +64 -0
- data/lib/punchblock/client/component_registry.rb +22 -0
- data/lib/punchblock/command/dial.rb +1 -4
- data/lib/punchblock/component.rb +6 -8
- data/lib/punchblock/connection.rb +4 -206
- data/lib/punchblock/connection/connected.rb +15 -0
- data/lib/punchblock/connection/xmpp.rb +161 -0
- data/lib/punchblock/dsl.rb +4 -4
- data/lib/punchblock/rayo_node.rb +2 -2
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +1 -1
- data/spec/punchblock/client/component_registry_spec.rb +15 -0
- data/spec/punchblock/client_spec.rb +125 -0
- data/spec/punchblock/command/dial_spec.rb +1 -8
- data/spec/punchblock/component/input_spec.rb +3 -2
- data/spec/punchblock/component/output_spec.rb +10 -9
- data/spec/punchblock/component/record_spec.rb +5 -4
- data/spec/punchblock/component/tropo/ask_spec.rb +3 -2
- data/spec/punchblock/component/tropo/conference_spec.rb +6 -5
- data/spec/punchblock/component/tropo/say_spec.rb +5 -4
- data/spec/punchblock/component/tropo/transfer_spec.rb +3 -2
- data/spec/punchblock/component_spec.rb +3 -9
- data/spec/punchblock/connection/xmpp_spec.rb +201 -0
- metadata +45 -38
- data/lib/punchblock/generic_connection.rb +0 -18
- data/spec/punchblock/connection_spec.rb +0 -216
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
%w{
|
|
2
|
+
timeout
|
|
3
|
+
blather/client/dsl
|
|
4
|
+
punchblock/core_ext/blather/stanza
|
|
5
|
+
punchblock/core_ext/blather/stanza/presence
|
|
6
|
+
}.each { |f| require f }
|
|
7
|
+
|
|
8
|
+
module Punchblock
|
|
9
|
+
module Connection
|
|
10
|
+
class XMPP
|
|
11
|
+
include Blather::DSL
|
|
12
|
+
attr_accessor :event_handler
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Initialize the required connection attributes
|
|
16
|
+
#
|
|
17
|
+
# @param [Hash] options
|
|
18
|
+
# @option options [String] :username client JID
|
|
19
|
+
# @option options [String] :password XMPP password
|
|
20
|
+
# @option options [String] :rayo_domain the domain on which Rayo is running
|
|
21
|
+
# @option options [Logger] :wire_logger to which all XMPP transactions will be logged
|
|
22
|
+
# @option options [Boolean, Optional] :auto_reconnect whether or not to auto reconnect
|
|
23
|
+
# @option options [Numeric, Optional] :write_timeout for which to wait on a command response
|
|
24
|
+
# @option options [Numeric, nil, Optional] :ping_period interval in seconds on which to ping the server. Nil or false to disable
|
|
25
|
+
#
|
|
26
|
+
def initialize(options = {})
|
|
27
|
+
raise ArgumentError unless (@username = options[:username]) && options[:password]
|
|
28
|
+
|
|
29
|
+
setup *[:username, :password, :host, :port, :certs].map { |key| options.delete key }
|
|
30
|
+
|
|
31
|
+
@rayo_domain = options[:rayo_domain] || Blather::JID.new(@username).domain
|
|
32
|
+
|
|
33
|
+
@callmap = {} # This hash maps call IDs to their XMPP domain.
|
|
34
|
+
|
|
35
|
+
@auto_reconnect = !!options[:auto_reconnect]
|
|
36
|
+
@reconnect_attempts = 0
|
|
37
|
+
|
|
38
|
+
@ping_period = options.has_key?(:ping_period) ? options[:ping_period] : 60
|
|
39
|
+
|
|
40
|
+
@event_handler = lambda { |event| raise 'No event handler set' }
|
|
41
|
+
|
|
42
|
+
Blather.logger = options.delete(:wire_logger) if options.has_key?(:wire_logger)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def write(command, options = {})
|
|
46
|
+
iq = prep_command_for_execution command, options
|
|
47
|
+
client.write_with_handler iq do |response|
|
|
48
|
+
if response.result?
|
|
49
|
+
handle_iq_result response, command
|
|
50
|
+
elsif response.error?
|
|
51
|
+
handle_error response, command
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
command.request!
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def prep_command_for_execution(command, options = {})
|
|
58
|
+
call_id, component_id = options.values_at :call_id, :component_id
|
|
59
|
+
command.connection = self
|
|
60
|
+
command.call_id = call_id
|
|
61
|
+
jid = command.is_a?(Command::Dial) ? @rayo_domain : "#{call_id}@#{@callmap[call_id]}"
|
|
62
|
+
jid << "/#{component_id}" if component_id
|
|
63
|
+
create_iq(jid).tap do |iq|
|
|
64
|
+
@logger.debug "Sending IQ ID #{iq.id} #{command.inspect} to #{jid}" if @logger
|
|
65
|
+
iq << command
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Fire up the connection
|
|
71
|
+
#
|
|
72
|
+
def run
|
|
73
|
+
register_handlers
|
|
74
|
+
connect
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def connect
|
|
78
|
+
begin
|
|
79
|
+
EM.run { client.run }
|
|
80
|
+
rescue Blather::SASLError, Blather::StreamError => e
|
|
81
|
+
raise ProtocolError.new(e.class.to_s, e.message)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def stop
|
|
86
|
+
@reconnect_attempts = nil
|
|
87
|
+
client.close
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def connected?
|
|
91
|
+
client.connected?
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
private
|
|
95
|
+
|
|
96
|
+
def handle_presence(p)
|
|
97
|
+
throw :pass unless p.rayo_event? && p.from.domain == @rayo_domain
|
|
98
|
+
@logger.info "Receiving event for call ID #{p.call_id}" if @logger
|
|
99
|
+
@callmap[p.call_id] = p.from.domain
|
|
100
|
+
@logger.debug p.inspect if @logger
|
|
101
|
+
event = p.event
|
|
102
|
+
event.connection = self
|
|
103
|
+
event_handler.call event
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def handle_iq_result(iq, command)
|
|
107
|
+
# FIXME: Do we need to raise a warning if the domain changes?
|
|
108
|
+
@callmap[iq.from.node] = iq.from.domain
|
|
109
|
+
@logger.debug "Command #{iq.id} completed successfully" if @logger
|
|
110
|
+
command.response = iq.rayo_node.is_a?(Ref) ? iq.rayo_node : true
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def handle_error(iq, command = nil)
|
|
114
|
+
e = Blather::StanzaError.import iq
|
|
115
|
+
protocol_error = ProtocolError.new e.name, e.text, iq.call_id, iq.component_id
|
|
116
|
+
command.response = protocol_error if command
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def register_handlers
|
|
120
|
+
# Push a message to the queue and the log that we connected
|
|
121
|
+
when_ready do
|
|
122
|
+
event_handler.call Connected
|
|
123
|
+
@logger.info "Connected to XMPP as #{@username}" if @logger
|
|
124
|
+
@reconnect_attempts = 0
|
|
125
|
+
@rayo_ping = EM::PeriodicTimer.new(@ping_period) { ping_rayo } if @ping_period
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
disconnected do
|
|
129
|
+
@rayo_ping.cancel if @rayo_ping
|
|
130
|
+
if @auto_reconnect && @reconnect_attempts
|
|
131
|
+
timer = 30 * 2 ** @reconnect_attempts
|
|
132
|
+
@logger.warn "XMPP disconnected. Tried to reconnect #{@reconnect_attempts} times. Reconnecting in #{timer}s." if @logger
|
|
133
|
+
sleep timer
|
|
134
|
+
@logger.info "Trying to reconnect..." if @logger
|
|
135
|
+
@reconnect_attempts += 1
|
|
136
|
+
connect
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Read/handle presence requests. This is how we get events.
|
|
141
|
+
presence do |msg|
|
|
142
|
+
handle_presence msg
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def ping_rayo
|
|
147
|
+
client.write_with_handler Blather::Stanza::Iq::Ping.new(:set, @rayo_domain) do |response|
|
|
148
|
+
begin
|
|
149
|
+
handle_error response if response.is_a? Blather::BlatherError
|
|
150
|
+
rescue ProtocolError => e
|
|
151
|
+
raise e unless e.name == :feature_not_implemented
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def create_iq(jid = nil)
|
|
157
|
+
Blather::Stanza::Iq.new :set, jid || @call_id
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
data/lib/punchblock/dsl.rb
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
# THIS IS IMPERMANENT AND WILL DISAPPEAR
|
|
5
5
|
module Punchblock
|
|
6
6
|
class DSL
|
|
7
|
-
def initialize(
|
|
8
|
-
@
|
|
7
|
+
def initialize(client, call_id, queue) # :nodoc:
|
|
8
|
+
@client, @call_id, @queue = client, call_id, queue
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def accept # :nodoc:
|
|
@@ -38,8 +38,8 @@ module Punchblock
|
|
|
38
38
|
component.complete_event.resource
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def write(
|
|
42
|
-
@
|
|
41
|
+
def write(command) # :nodoc:
|
|
42
|
+
@client.execute_command command, :call_id => @call_id, :async => false
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
data/lib/punchblock/rayo_node.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Punchblock
|
|
|
7
7
|
|
|
8
8
|
class_attribute :registered_ns, :registered_name
|
|
9
9
|
|
|
10
|
-
attr_accessor :call_id, :component_id, :connection, :original_component
|
|
10
|
+
attr_accessor :call_id, :component_id, :connection, :client, :original_component
|
|
11
11
|
|
|
12
12
|
# Register a new stanza class to a name and/or namespace
|
|
13
13
|
#
|
|
@@ -78,7 +78,7 @@ module Punchblock
|
|
|
78
78
|
# @return [RayoNode] the original command issued that lead to this event
|
|
79
79
|
#
|
|
80
80
|
def source
|
|
81
|
-
@source ||=
|
|
81
|
+
@source ||= client.find_component_by_id component_id if client && component_id
|
|
82
82
|
@source ||= original_component
|
|
83
83
|
end
|
|
84
84
|
|
data/lib/punchblock/version.rb
CHANGED
data/punchblock.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|
|
28
28
|
s.add_runtime_dependency %q<activesupport>, [">= 2.1.0"]
|
|
29
29
|
s.add_runtime_dependency %q<state_machine>, [">= 1.0.1"]
|
|
30
30
|
s.add_runtime_dependency %q<future-resource>, [">= 0.0.2"]
|
|
31
|
-
s.add_runtime_dependency %q<has-guarded-handlers>, [">= 0.0
|
|
31
|
+
s.add_runtime_dependency %q<has-guarded-handlers>, [">= 0.1.0"]
|
|
32
32
|
|
|
33
33
|
s.add_development_dependency %q<bundler>, ["~> 1.0.0"]
|
|
34
34
|
s.add_development_dependency %q<rspec>, ["~> 2.3.0"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Punchblock
|
|
4
|
+
class Client
|
|
5
|
+
describe ComponentRegistry do
|
|
6
|
+
let(:component_id) { 'abc123' }
|
|
7
|
+
let(:component) { stub 'Component', :component_id => component_id }
|
|
8
|
+
|
|
9
|
+
it 'should store components and allow lookup by ID' do
|
|
10
|
+
subject << component
|
|
11
|
+
subject.find_by_id(component_id).should be component
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
module Punchblock
|
|
4
|
+
describe Client do
|
|
5
|
+
let(:connection) { Connection::XMPP.new :username => '1@call.rayo.net', :password => 1 }
|
|
6
|
+
|
|
7
|
+
subject { Client.new :connection => connection }
|
|
8
|
+
|
|
9
|
+
its(:event_queue) { should be_a Queue }
|
|
10
|
+
its(:connection) { should be connection }
|
|
11
|
+
its(:component_registry) { should be_a Client::ComponentRegistry }
|
|
12
|
+
|
|
13
|
+
let(:call_id) { 'abc123' }
|
|
14
|
+
let(:mock_event) { stub_everything 'Event' }
|
|
15
|
+
let(:component_id) { 'abc123' }
|
|
16
|
+
let(:mock_component) { stub 'Component', :component_id => component_id }
|
|
17
|
+
let(:mock_command) { stub 'Command' }
|
|
18
|
+
|
|
19
|
+
describe '#run' do
|
|
20
|
+
it 'should start up the connection' do
|
|
21
|
+
connection.expects(:run).once
|
|
22
|
+
subject.run
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe '#stop' do
|
|
27
|
+
it 'should stop the connection' do
|
|
28
|
+
connection.expects(:stop).once
|
|
29
|
+
subject.stop
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'should handle connection events' do
|
|
34
|
+
subject.expects(:handle_event).with(mock_event).once
|
|
35
|
+
connection.event_handler.call mock_event
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
describe '#handle_event' do
|
|
39
|
+
it "sets the event's client" do
|
|
40
|
+
event = Event::Offer.new
|
|
41
|
+
subject.handle_event event
|
|
42
|
+
event.client.should be subject
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context 'if the event can be associated with a source component' do
|
|
46
|
+
before do
|
|
47
|
+
mock_event.stubs(:source).returns mock_component
|
|
48
|
+
mock_component.expects(:add_event).with mock_event
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should not queue up the event' do
|
|
52
|
+
subject.handle_event mock_event
|
|
53
|
+
subject.event_queue.should be_empty
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'should not call event handlers' do
|
|
57
|
+
handler = mock 'handler'
|
|
58
|
+
handler.expects(:call).never
|
|
59
|
+
subject.register_event_handler do |event|
|
|
60
|
+
handler.call event
|
|
61
|
+
throw :halt
|
|
62
|
+
end
|
|
63
|
+
subject.handle_event mock_event
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
context 'if the event cannot be associated with a source component' do
|
|
68
|
+
context 'if event handlers have been set' do
|
|
69
|
+
it 'should call the event handler and not queue up the event' do
|
|
70
|
+
handler = mock 'handler'
|
|
71
|
+
handler.expects(:call).once.with mock_event
|
|
72
|
+
subject.register_event_handler do |event|
|
|
73
|
+
handler.call event
|
|
74
|
+
throw :halt
|
|
75
|
+
end
|
|
76
|
+
subject.handle_event mock_event
|
|
77
|
+
subject.event_queue.should be_empty
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context 'if event handlers have not been set' do
|
|
82
|
+
it 'should queue up the event' do
|
|
83
|
+
subject.handle_event mock_event
|
|
84
|
+
subject.event_queue.pop(true).should == mock_event
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'should be able to register and retrieve components' do
|
|
91
|
+
subject.register_component mock_component
|
|
92
|
+
subject.find_component_by_id(component_id).should be mock_component
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe '#execute_command' do
|
|
96
|
+
let(:component) { Component::Output.new }
|
|
97
|
+
let(:event) { Event::Complete.new }
|
|
98
|
+
|
|
99
|
+
before do
|
|
100
|
+
connection.expects(:write).once.with component, :call_id => call_id
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
let :execute_command do
|
|
104
|
+
subject.execute_command component, :call_id => call_id
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it 'should write the command to the connection' do
|
|
108
|
+
execute_command
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "should set the command's client" do
|
|
112
|
+
execute_command
|
|
113
|
+
component.client.should be subject
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it "should handle a component's events" do
|
|
117
|
+
subject.expects(:trigger_handler).with(:event, event).once
|
|
118
|
+
execute_command
|
|
119
|
+
component.request!
|
|
120
|
+
component.execute!
|
|
121
|
+
component.add_event event
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end # describe Client
|
|
125
|
+
end # Punchblock
|
|
@@ -37,15 +37,8 @@ module Punchblock
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
let :iq do
|
|
41
|
-
Blather::Stanza::Iq.new(:result, 'blah').tap do |iq|
|
|
42
|
-
iq.from = "call.rayo.net"
|
|
43
|
-
iq << ref
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
40
|
it "should set the call ID from the ref" do
|
|
48
|
-
subject.response =
|
|
41
|
+
subject.response = ref
|
|
49
42
|
subject.call_id.should == call_id
|
|
50
43
|
end
|
|
51
44
|
end
|
|
@@ -92,12 +92,13 @@ module Punchblock
|
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
describe "actions" do
|
|
95
|
+
let(:mock_client) { mock 'Client' }
|
|
95
96
|
let(:command) { Input.new :grammar => '[5 DIGITS]' }
|
|
96
97
|
|
|
97
98
|
before do
|
|
98
99
|
command.component_id = 'abc123'
|
|
99
100
|
command.call_id = '123abc'
|
|
100
|
-
command.
|
|
101
|
+
command.client = mock_client
|
|
101
102
|
end
|
|
102
103
|
|
|
103
104
|
describe '#stop_action' do
|
|
@@ -116,7 +117,7 @@ module Punchblock
|
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
it "should send its command properly" do
|
|
119
|
-
|
|
120
|
+
mock_client.expects(:execute_command).with(command.stop_action, :call_id => '123abc', :component_id => 'abc123')
|
|
120
121
|
command.stop!
|
|
121
122
|
end
|
|
122
123
|
end
|
|
@@ -51,12 +51,13 @@ module Punchblock
|
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
describe "actions" do
|
|
54
|
+
let(:mock_client) { mock 'Client' }
|
|
54
55
|
let(:command) { Output.new :text => 'Once upon a time there was a message...', :voice => 'kate' }
|
|
55
56
|
|
|
56
57
|
before do
|
|
57
58
|
command.component_id = 'abc123'
|
|
58
59
|
command.call_id = '123abc'
|
|
59
|
-
command.
|
|
60
|
+
command.client = mock_client
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
describe '#pause_action' do
|
|
@@ -75,7 +76,7 @@ module Punchblock
|
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
it "should send its command properly" do
|
|
78
|
-
|
|
79
|
+
mock_client.expects(:execute_command).with(command.pause_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
79
80
|
command.expects :paused!
|
|
80
81
|
command.pause!
|
|
81
82
|
end
|
|
@@ -119,7 +120,7 @@ module Punchblock
|
|
|
119
120
|
end
|
|
120
121
|
|
|
121
122
|
it "should send its command properly" do
|
|
122
|
-
|
|
123
|
+
mock_client.expects(:execute_command).with(command.resume_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
123
124
|
command.expects :resumed!
|
|
124
125
|
command.resume!
|
|
125
126
|
end
|
|
@@ -163,7 +164,7 @@ module Punchblock
|
|
|
163
164
|
end
|
|
164
165
|
|
|
165
166
|
it "should send its command properly" do
|
|
166
|
-
|
|
167
|
+
mock_client.expects(:execute_command).with(command.stop_action, :call_id => '123abc', :component_id => 'abc123')
|
|
167
168
|
command.stop!
|
|
168
169
|
end
|
|
169
170
|
end
|
|
@@ -196,7 +197,7 @@ module Punchblock
|
|
|
196
197
|
it "should send its command properly" do
|
|
197
198
|
seek_action = command.seek_action seek_options
|
|
198
199
|
command.stubs(:seek_action).returns seek_action
|
|
199
|
-
|
|
200
|
+
mock_client.expects(:execute_command).with(seek_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
200
201
|
command.expects :seeking!
|
|
201
202
|
command.expects :stopped_seeking!
|
|
202
203
|
command.seek! seek_options
|
|
@@ -263,7 +264,7 @@ module Punchblock
|
|
|
263
264
|
it "should send its command properly" do
|
|
264
265
|
speed_up_action = command.speed_up_action
|
|
265
266
|
command.stubs(:speed_up_action).returns speed_up_action
|
|
266
|
-
|
|
267
|
+
mock_client.expects(:execute_command).with(speed_up_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
267
268
|
command.expects :speeding_up!
|
|
268
269
|
command.expects :stopped_speeding!
|
|
269
270
|
command.speed_up!
|
|
@@ -321,7 +322,7 @@ module Punchblock
|
|
|
321
322
|
it "should send its command properly" do
|
|
322
323
|
slow_down_action = command.slow_down_action
|
|
323
324
|
command.stubs(:slow_down_action).returns slow_down_action
|
|
324
|
-
|
|
325
|
+
mock_client.expects(:execute_command).with(slow_down_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
325
326
|
command.expects :slowing_down!
|
|
326
327
|
command.expects :stopped_speeding!
|
|
327
328
|
command.slow_down!
|
|
@@ -396,7 +397,7 @@ module Punchblock
|
|
|
396
397
|
it "should send its command properly" do
|
|
397
398
|
volume_up_action = command.volume_up_action
|
|
398
399
|
command.stubs(:volume_up_action).returns volume_up_action
|
|
399
|
-
|
|
400
|
+
mock_client.expects(:execute_command).with(volume_up_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
400
401
|
command.expects :voluming_up!
|
|
401
402
|
command.expects :stopped_voluming!
|
|
402
403
|
command.volume_up!
|
|
@@ -454,7 +455,7 @@ module Punchblock
|
|
|
454
455
|
it "should send its command properly" do
|
|
455
456
|
volume_down_action = command.volume_down_action
|
|
456
457
|
command.stubs(:volume_down_action).returns volume_down_action
|
|
457
|
-
|
|
458
|
+
mock_client.expects(:execute_command).with(volume_down_action, :call_id => '123abc', :component_id => 'abc123').returns true
|
|
458
459
|
command.expects :voluming_down!
|
|
459
460
|
command.expects :stopped_voluming!
|
|
460
461
|
command.volume_down!
|