cancer 0.1.0.a1
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/.autotest +3 -0
- data/.gitignore +5 -0
- data/LICENSE.txt +22 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/cancer.gemspec +156 -0
- data/documentation/STREAM_INITIATION.markdown +18 -0
- data/examples/example.rb +80 -0
- data/examples/example_2.rb +20 -0
- data/examples/example_em.rb +11 -0
- data/examples/example_em_helper.rb +23 -0
- data/examples/example_im_roster.rb +26 -0
- data/examples/example_xep_0004.rb +124 -0
- data/examples/example_xep_0047.rb +35 -0
- data/examples/example_xep_0050.rb +78 -0
- data/examples/example_xep_0065.rb +66 -0
- data/examples/example_xep_0096.dup.rb +40 -0
- data/examples/example_xep_0096_xep_0047.rb +42 -0
- data/examples/example_xep_0096_xep_0065.rb +40 -0
- data/lib/cancer.rb +122 -0
- data/lib/cancer/adapter.rb +33 -0
- data/lib/cancer/adapters/em.rb +88 -0
- data/lib/cancer/adapters/socket.rb +122 -0
- data/lib/cancer/builder.rb +28 -0
- data/lib/cancer/controller.rb +32 -0
- data/lib/cancer/dependencies.rb +187 -0
- data/lib/cancer/events/abstract_event.rb +10 -0
- data/lib/cancer/events/base_matchers.rb +63 -0
- data/lib/cancer/events/binary_matchers.rb +30 -0
- data/lib/cancer/events/eventable.rb +92 -0
- data/lib/cancer/events/exception_events.rb +28 -0
- data/lib/cancer/events/handler.rb +33 -0
- data/lib/cancer/events/manager.rb +130 -0
- data/lib/cancer/events/named_events.rb +25 -0
- data/lib/cancer/events/proc_matcher.rb +16 -0
- data/lib/cancer/events/xml_events.rb +44 -0
- data/lib/cancer/exceptions.rb +53 -0
- data/lib/cancer/jid.rb +215 -0
- data/lib/cancer/lock.rb +32 -0
- data/lib/cancer/spec.rb +35 -0
- data/lib/cancer/spec/error.rb +18 -0
- data/lib/cancer/spec/extentions.rb +79 -0
- data/lib/cancer/spec/matcher.rb +30 -0
- data/lib/cancer/spec/mock_adapter.rb +139 -0
- data/lib/cancer/spec/mock_stream.rb +15 -0
- data/lib/cancer/spec/transcript.rb +107 -0
- data/lib/cancer/stream.rb +182 -0
- data/lib/cancer/stream/builder.rb +20 -0
- data/lib/cancer/stream/controller.rb +36 -0
- data/lib/cancer/stream/event_helper.rb +12 -0
- data/lib/cancer/stream/xep.rb +52 -0
- data/lib/cancer/stream_parser.rb +144 -0
- data/lib/cancer/support.rb +27 -0
- data/lib/cancer/support/hash.rb +32 -0
- data/lib/cancer/support/string.rb +22 -0
- data/lib/cancer/synchronized_stanza.rb +79 -0
- data/lib/cancer/thread_pool.rb +118 -0
- data/lib/cancer/xep.rb +43 -0
- data/lib/cancer/xeps/core.rb +109 -0
- data/lib/cancer/xeps/core/bind.rb +33 -0
- data/lib/cancer/xeps/core/sasl.rb +113 -0
- data/lib/cancer/xeps/core/session.rb +22 -0
- data/lib/cancer/xeps/core/stream.rb +18 -0
- data/lib/cancer/xeps/core/terminator.rb +21 -0
- data/lib/cancer/xeps/core/tls.rb +34 -0
- data/lib/cancer/xeps/im.rb +323 -0
- data/lib/cancer/xeps/xep_0004_x_data.rb +692 -0
- data/lib/cancer/xeps/xep_0020_feature_neg.rb +35 -0
- data/lib/cancer/xeps/xep_0030_disco.rb +167 -0
- data/lib/cancer/xeps/xep_0047_ibb.rb +322 -0
- data/lib/cancer/xeps/xep_0050_commands.rb +256 -0
- data/lib/cancer/xeps/xep_0065_bytestreams.rb +306 -0
- data/lib/cancer/xeps/xep_0066_oob.rb +69 -0
- data/lib/cancer/xeps/xep_0095_si.rb +211 -0
- data/lib/cancer/xeps/xep_0096_si_filetransfer.rb +173 -0
- data/lib/cancer/xeps/xep_0114_component.rb +73 -0
- data/lib/cancer/xeps/xep_0115_caps.rb +180 -0
- data/lib/cancer/xeps/xep_0138_compress.rb +134 -0
- data/lib/cancer/xeps/xep_0144_rosterx.rb +250 -0
- data/lib/cancer/xeps/xep_0184_receipts.rb +40 -0
- data/lib/cancer/xeps/xep_0199_ping.rb +41 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/stream/stanza_errors_spec.rb +47 -0
- data/spec/stream/stream_errors_spec.rb +38 -0
- data/spec/stream/stream_initialization_spec.rb +160 -0
- data/spec/xep_0050/local_spec.rb +165 -0
- data/spec/xep_0050/remote_spec.rb +44 -0
- metadata +200 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
module Cancer
|
3
|
+
# Message Receipts
|
4
|
+
module XEP_0184
|
5
|
+
include Cancer::XEP
|
6
|
+
|
7
|
+
NS = 'urn:xmpp:receipts'
|
8
|
+
|
9
|
+
dependency 'core'
|
10
|
+
|
11
|
+
def self.enhance_stream(stream)
|
12
|
+
stream.extend_builder do
|
13
|
+
include Cancer::XEP_0184::Builder
|
14
|
+
end
|
15
|
+
stream.install_controller(Cancer::XEP_0184::Controller)
|
16
|
+
end
|
17
|
+
|
18
|
+
module Builder
|
19
|
+
|
20
|
+
def request_receipt
|
21
|
+
request :xmlns => NS
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
class Controller < Cancer::Controller
|
27
|
+
|
28
|
+
priority 1000
|
29
|
+
|
30
|
+
on { |e| e.xpath('/c:message/n:request', 'n' => NS, 'c' => CLIENT_NS) }
|
31
|
+
def respond_with_received(e)
|
32
|
+
send_message(e.sender, nil, e.id) do |x|
|
33
|
+
x.received :xmlns => NS
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
module Cancer
|
3
|
+
# XMPP Ping
|
4
|
+
# http://xmpp.org/extensions/xep-0199.html
|
5
|
+
module XEP_0199
|
6
|
+
include Cancer::XEP
|
7
|
+
|
8
|
+
NS = 'urn:xmpp:ping'
|
9
|
+
|
10
|
+
dependency 'core'
|
11
|
+
dependency 'xep-0030'
|
12
|
+
|
13
|
+
def self.enhance_stream(stream)
|
14
|
+
stream.extend_stream do
|
15
|
+
include Cancer::XEP_0199::StreamHelpers
|
16
|
+
end
|
17
|
+
stream.install_controller(Cancer::XEP_0199::Controller)
|
18
|
+
stream.disco.feature(NS)
|
19
|
+
end
|
20
|
+
|
21
|
+
module StreamHelpers
|
22
|
+
|
23
|
+
def ping(to)
|
24
|
+
send_iq(to) do |x|
|
25
|
+
x.ping(:xmlns => NS)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
class Controller < Cancer::Controller
|
32
|
+
|
33
|
+
on { |e| e.xpath('/c:iq/p:ping', 'p' => NS, 'c' => CLIENT_NS) }
|
34
|
+
def pong(e)
|
35
|
+
send_iq(e.sender, :result, e.id)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/cancer')
|
2
|
+
|
3
|
+
module Kernel
|
4
|
+
def hp(object)
|
5
|
+
puts "<pre>"+object.inspect.gsub('<', '<')+"</pre>"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Cancer::Spec.debug = false
|
10
|
+
Cancer.logger.level = Logger::FATAL
|
11
|
+
|
12
|
+
Spec::Runner.configure do |config|
|
13
|
+
config.include(Cancer::Spec)
|
14
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Cancer::StanzaError do
|
4
|
+
|
5
|
+
it "should be raised when a stream error is received" do
|
6
|
+
dialog_with do |stream|
|
7
|
+
|
8
|
+
lambda do
|
9
|
+
stream.send_iq('knave@wonderland.lit')
|
10
|
+
end.should raise_error(Cancer::StanzaModifyError)
|
11
|
+
|
12
|
+
end.should_produce_transcript do |t|
|
13
|
+
t.out %{<iq type="get" to="knave@wonderland.lit" id="cancer-3"/>}
|
14
|
+
t.in %{<iq type="error" to="alice@wonderland.lit" id="cancer-3"><error type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error></iq>}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should contain error conditions" do
|
19
|
+
dialog_with do |stream|
|
20
|
+
|
21
|
+
lambda do
|
22
|
+
stream.send_iq('knave@wonderland.lit')
|
23
|
+
end.should raise_error(Cancer::StanzaModifyError) { |error|
|
24
|
+
error.conditions.should_not be_empty
|
25
|
+
error.conditions.first.name.should == 'bad-request'
|
26
|
+
}
|
27
|
+
|
28
|
+
end.should_produce_transcript do |t|
|
29
|
+
t.out %{<iq type="get" to="knave@wonderland.lit" id="cancer-3"/>}
|
30
|
+
t.in %{<iq type="error" to="alice@wonderland.lit" id="cancer-3"><error type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error></iq>}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should have message equal to error/text if present" do
|
35
|
+
dialog_with do |stream|
|
36
|
+
|
37
|
+
lambda do
|
38
|
+
stream.send_iq('knave@wonderland.lit')
|
39
|
+
end.should raise_error(Cancer::StanzaModifyError, 'My error message')
|
40
|
+
|
41
|
+
end.should_produce_transcript do |t|
|
42
|
+
t.out %{<iq type="get" to="knave@wonderland.lit" id="cancer-3"/>}
|
43
|
+
t.in %{<iq type="error" to="alice@wonderland.lit" id="cancer-3"><error type="modify"><bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /><text xmlns='urn:ietf:params:xml:ns:xmpp-streams'>My error message</text></error></iq>}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Cancer::StreamError do
|
4
|
+
|
5
|
+
it "should be raised when a stream error is received" do
|
6
|
+
lambda do
|
7
|
+
dialog_with do |stream|
|
8
|
+
|
9
|
+
end.should_produce_transcript do |t|
|
10
|
+
t.in %{<stream:error><bad-format xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error>}
|
11
|
+
end
|
12
|
+
end.should raise_error(Cancer::StreamError)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should contain error conditions" do
|
16
|
+
lambda do
|
17
|
+
dialog_with do |stream|
|
18
|
+
|
19
|
+
end.should_produce_transcript do |t|
|
20
|
+
t.in %{<stream:error><bad-format xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error>}
|
21
|
+
end
|
22
|
+
end.should raise_error(Cancer::StreamError) { |error|
|
23
|
+
error.conditions.should_not be_empty
|
24
|
+
error.conditions.first.name.should == 'bad-format'
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have message equal to stream:error/text if present" do
|
29
|
+
lambda do
|
30
|
+
dialog_with do |stream|
|
31
|
+
|
32
|
+
end.should_produce_transcript do |t|
|
33
|
+
t.in %{<stream:error><bad-format xmlns='urn:ietf:params:xml:ns:xmpp-streams'/><text xmlns='urn:ietf:params:xml:ns:xmpp-streams'>My error message</text></stream:error>}
|
34
|
+
end
|
35
|
+
end.should raise_error(Cancer::StreamError, 'My error message')
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Cancer::Stream do
|
4
|
+
|
5
|
+
it "should initiate with tls sasl bind and session" do
|
6
|
+
dialog do |adapter|
|
7
|
+
Cancer::Stream.open(:adapter => adapter,
|
8
|
+
:jid => 'alice@wonderland.lit', :password => 'ihatethequeen') { }
|
9
|
+
end.should_produce_transcript do |t|
|
10
|
+
t.start_stream('alice@wonderland.lit')
|
11
|
+
t.in %{<stream:features>
|
12
|
+
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls">
|
13
|
+
<optional/>
|
14
|
+
</starttls>
|
15
|
+
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
16
|
+
<mechanism>PLAIN</mechanism>
|
17
|
+
<required/>
|
18
|
+
</mechanisms>
|
19
|
+
</stream:features>}
|
20
|
+
|
21
|
+
t.out %{<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>}
|
22
|
+
t.in %{<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>}
|
23
|
+
|
24
|
+
t.start_stream('alice@wonderland.lit')
|
25
|
+
t.in %{<stream:features>
|
26
|
+
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
27
|
+
<mechanism>PLAIN</mechanism>
|
28
|
+
<required/>
|
29
|
+
</mechanisms>
|
30
|
+
</stream:features>}
|
31
|
+
|
32
|
+
t.out %{<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGFsaWNlQHdvbmRlcmxhbmQubGl0AGloYXRldGhlcXVlZW4=</auth>}
|
33
|
+
t.in %{<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl" />}
|
34
|
+
|
35
|
+
t.start_stream('alice@wonderland.lit')
|
36
|
+
t.in %{<stream:features>
|
37
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
38
|
+
<required/>
|
39
|
+
</bind>
|
40
|
+
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
|
41
|
+
<optional/>
|
42
|
+
</session>
|
43
|
+
</stream:features>}
|
44
|
+
|
45
|
+
t.out %{<iq type="set" id="cancer-1"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>}
|
46
|
+
t.in %{<iq type="result" id="cancer-1">
|
47
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
48
|
+
<jid>alice@wonderland.lit/rabbithole</jid></bind></iq>}
|
49
|
+
|
50
|
+
t.out %{<iq type="set" id="cancer-2"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>}
|
51
|
+
t.in %{<iq type="result" id="cancer-2" />}
|
52
|
+
|
53
|
+
t.close_stream
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should initiate with sasl bind and session" do
|
59
|
+
dialog do |adapter|
|
60
|
+
Cancer::Stream.open(:adapter => adapter,
|
61
|
+
:jid => 'alice@wonderland.lit', :password => 'ihatethequeen') { }
|
62
|
+
end.should_produce_transcript do |t|
|
63
|
+
|
64
|
+
t.start_stream('alice@wonderland.lit')
|
65
|
+
t.in %{<stream:features>
|
66
|
+
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
67
|
+
<mechanism>PLAIN</mechanism>
|
68
|
+
<required/>
|
69
|
+
</mechanisms>
|
70
|
+
</stream:features>}
|
71
|
+
|
72
|
+
t.out %{<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">AGFsaWNlQHdvbmRlcmxhbmQubGl0AGloYXRldGhlcXVlZW4=</auth>}
|
73
|
+
t.in %{<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl" />}
|
74
|
+
|
75
|
+
t.start_stream('alice@wonderland.lit')
|
76
|
+
t.in %{<stream:features>
|
77
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
78
|
+
<required/>
|
79
|
+
</bind>
|
80
|
+
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
|
81
|
+
<optional/>
|
82
|
+
</session>
|
83
|
+
</stream:features>}
|
84
|
+
|
85
|
+
t.out %{<iq type="set" id="cancer-1"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>}
|
86
|
+
t.in %{<iq type="result" id="cancer-1">
|
87
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
88
|
+
<jid>alice@wonderland.lit/rabbithole</jid></bind></iq>}
|
89
|
+
|
90
|
+
t.out %{<iq type="set" id="cancer-2"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>}
|
91
|
+
t.in %{<iq type="result" id="cancer-2" />}
|
92
|
+
|
93
|
+
t.close_stream
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should initiate with bind and session" do
|
99
|
+
dialog do |adapter|
|
100
|
+
Cancer::Stream.open(:adapter => adapter,
|
101
|
+
:jid => 'alice@wonderland.lit', :password => 'ihatethequeen') { }
|
102
|
+
end.should_produce_transcript do |t|
|
103
|
+
|
104
|
+
t.start_stream('alice@wonderland.lit')
|
105
|
+
t.in %{<stream:features>
|
106
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
107
|
+
<required/>
|
108
|
+
</bind>
|
109
|
+
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
|
110
|
+
<optional/>
|
111
|
+
</session>
|
112
|
+
</stream:features>}
|
113
|
+
|
114
|
+
t.out %{<iq type="set" id="cancer-1"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>}
|
115
|
+
t.in %{<iq type="result" id="cancer-1">
|
116
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
117
|
+
<jid>alice@wonderland.lit/rabbithole</jid></bind></iq>}
|
118
|
+
|
119
|
+
t.out %{<iq type="set" id="cancer-2"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>}
|
120
|
+
t.in %{<iq type="result" id="cancer-2" />}
|
121
|
+
|
122
|
+
t.close_stream
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should initiate with bind" do
|
128
|
+
dialog do |adapter|
|
129
|
+
Cancer::Stream.open(:adapter => adapter,
|
130
|
+
:jid => 'alice@wonderland.lit', :password => 'ihatethequeen') { }
|
131
|
+
end.should_produce_transcript do |t|
|
132
|
+
|
133
|
+
t.start_stream('alice@wonderland.lit')
|
134
|
+
t.in %{<stream:features>
|
135
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
136
|
+
<required/>
|
137
|
+
</bind>
|
138
|
+
</stream:features>}
|
139
|
+
|
140
|
+
t.out %{<iq type="set" id="cancer-1"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>}
|
141
|
+
t.in %{<iq type="result" id="cancer-1">
|
142
|
+
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
143
|
+
<jid>alice@wonderland.lit/rabbithole</jid></bind></iq>}
|
144
|
+
|
145
|
+
|
146
|
+
t.close_stream
|
147
|
+
|
148
|
+
t.verify { |stream| stream.options[:jid].to_s.should == "alice@wonderland.lit/rabbithole" }
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should initiate " do
|
153
|
+
dialog_with() do |stream|
|
154
|
+
|
155
|
+
end.should_produce_transcript do |t|
|
156
|
+
t.verify { |stream| stream.options[:jid].to_s.should == "alice@wonderland.lit/rabbithole" }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Cancer::XEP_0050, '#local' do
|
4
|
+
|
5
|
+
it "handles command events" do
|
6
|
+
dialog_with(:xeps => %w( xep-0050 )) do |stream|
|
7
|
+
|
8
|
+
stream.controller do
|
9
|
+
|
10
|
+
on { |e| e.command(:config) }
|
11
|
+
def config(e)
|
12
|
+
e.session.instance_variable_set :@id, 'config-1' # mock the session id
|
13
|
+
|
14
|
+
e.session.complete! do |x|
|
15
|
+
x.note(:type => 'info') do
|
16
|
+
x.text "Service 'httpd' has been configured."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
ensure
|
21
|
+
$waiting_thread.wakeup
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
$waiting_thread = Thread.current and Thread.stop
|
27
|
+
|
28
|
+
end.should_produce_transcript do |t|
|
29
|
+
t.in %{<iq type="set" from="knave@wonderland.lit" id="cancer-3"><command xmlns='http://jabber.org/protocol/commands' node='config' action='execute'/></iq>}
|
30
|
+
t.out %{<iq type='result' to='knave@wonderland.lit' id='cancer-3'><command xmlns='http://jabber.org/protocol/commands' sessionid='config-1' node='config' status='completed'><note type='info'>Service 'httpd' has been configured.</note></command></iq>}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "handles multistage commands" do
|
35
|
+
dialog_with(:xeps => %w( xep-0050 )) do |stream|
|
36
|
+
|
37
|
+
stream.controller do
|
38
|
+
|
39
|
+
define_form 'config.form' do |form|
|
40
|
+
form.title = "Setup your profile"
|
41
|
+
form.instructions << "Enter your profile in the fields below."
|
42
|
+
|
43
|
+
form.define :name do |f|
|
44
|
+
f.type = :'text-single'
|
45
|
+
f.required = true
|
46
|
+
f.label = "Name"
|
47
|
+
end
|
48
|
+
|
49
|
+
form.define :sex do |f|
|
50
|
+
f.type = :'list-single'
|
51
|
+
f.add_option 'm', 'Man'
|
52
|
+
f.add_option 'w', 'Woman'
|
53
|
+
f.add_option 'o', 'Other'
|
54
|
+
f.label = "Sex"
|
55
|
+
end
|
56
|
+
|
57
|
+
form.define :jid do |f|
|
58
|
+
f.type = :'jid-single'
|
59
|
+
f.required = true
|
60
|
+
f.add_option 'alice@wonderland.lit'
|
61
|
+
f.add_option 'knave@wonderland.lit'
|
62
|
+
f.label = "JID"
|
63
|
+
f.description = 'Choose your preferred jabber address.'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
on { |e| e.command(:config) }
|
68
|
+
def config(e)
|
69
|
+
|
70
|
+
e.session.next! :run, 'config.form', :values => { :name => 'Simon Menke'}
|
71
|
+
|
72
|
+
throw :halt
|
73
|
+
rescue Exception => e
|
74
|
+
$action_exception = e
|
75
|
+
ensure
|
76
|
+
$waiting_thread.wakeup
|
77
|
+
end
|
78
|
+
|
79
|
+
on { |e| e.command(:config, :stage => :run) }
|
80
|
+
def config_run(e)
|
81
|
+
|
82
|
+
e.session.complete! do |x|
|
83
|
+
x.note(:type => 'info') do
|
84
|
+
x.text "Your profile has been updated."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
rescue Exception => e
|
89
|
+
$action_exception = e
|
90
|
+
ensure
|
91
|
+
$waiting_thread.wakeup
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
$waiting_thread = Thread.current and Thread.stop
|
97
|
+
raise $action_exception if $action_exception
|
98
|
+
|
99
|
+
$waiting_thread = Thread.current and Thread.stop
|
100
|
+
raise $action_exception if $action_exception
|
101
|
+
|
102
|
+
end.should_produce_transcript do |t|
|
103
|
+
t.in %{
|
104
|
+
<iq type="set" from="knave@wonderland.lit" id="cancer-3">
|
105
|
+
<command xmlns="http://jabber.org/protocol/commands" node="config" action="execute" sessionid="config-1"/>
|
106
|
+
</iq>}
|
107
|
+
|
108
|
+
t.out %{
|
109
|
+
<iq type="result" to="knave@wonderland.lit" id="cancer-3">
|
110
|
+
<command xmlns="http://jabber.org/protocol/commands" status="executing" node="config" sessionid="config-1">
|
111
|
+
<actions/>
|
112
|
+
<x xmlns="jabber:x:data" type="form">
|
113
|
+
<title>Setup your profile</title>
|
114
|
+
<instructions>Enter your profile in the fields below.</instructions>
|
115
|
+
<field label="Name" var="name">
|
116
|
+
<required/>
|
117
|
+
<value>Simon Menke</value>
|
118
|
+
</field>
|
119
|
+
<field type="list-single" label="Sex" var="sex">
|
120
|
+
<option label="Woman">
|
121
|
+
<value>w</value>
|
122
|
+
</option>
|
123
|
+
<option label="Man">
|
124
|
+
<value>m</value>
|
125
|
+
</option>
|
126
|
+
<option label="Other">
|
127
|
+
<value>o</value>
|
128
|
+
</option>
|
129
|
+
</field>
|
130
|
+
<field type="jid-single" label="JID" var="jid">
|
131
|
+
<required/>
|
132
|
+
<desc>Choose your preferred jabber address.</desc>
|
133
|
+
<option>
|
134
|
+
<value>knave@wonderland.lit</value>
|
135
|
+
</option>
|
136
|
+
<option>
|
137
|
+
<value>alice@wonderland.lit</value>
|
138
|
+
</option>
|
139
|
+
</field>
|
140
|
+
</x>
|
141
|
+
</command>
|
142
|
+
</iq>}
|
143
|
+
|
144
|
+
t.in %{
|
145
|
+
<iq type="set" from="knave@wonderland.lit" id="cancer-4">
|
146
|
+
<command xmlns="http://jabber.org/protocol/commands" action="execute" node="config" sessionid="config-1">
|
147
|
+
<x xmlns="jabber:x:data" type="submit">
|
148
|
+
<field var="name">
|
149
|
+
<value>Hans Spooren</value>
|
150
|
+
</field>
|
151
|
+
<field type="list-single" var="sex">
|
152
|
+
<value>m</value>
|
153
|
+
</field>
|
154
|
+
<field type="jid-single" var="jid">
|
155
|
+
<value>knave@wonderland.lit</value>
|
156
|
+
</field>
|
157
|
+
</x>
|
158
|
+
</command>
|
159
|
+
</iq>}
|
160
|
+
|
161
|
+
t.out %{<iq type='result' to='knave@wonderland.lit' id='cancer-4'><command xmlns='http://jabber.org/protocol/commands' sessionid='config-1' node='config' status='completed'><note type='info'>Your profile has been updated.</note></command></iq>}
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|