3 # Test that Thrasher::XMPPStreams works as expected.
4 use Test
::More
'no_plan';
14 use_ok
'Thrasher::XMPPStreamIn', qw(:all);
15 use_ok
'Thrasher::Constants', qw(:all);
16 use_ok
'Thrasher::Log', qw(:all);
17 use_ok
'Thrasher::Test', qw(:all);
18 use_ok
'Thrasher::XML', qw(:all);
21 # Verify the support code is working correctly
23 cmp_deeply
(normalize_name
("x"),
25 'normalizing works as expected');
26 cmp_deeply
(normalize_name
(['', 'x']),
28 cmp_deeply
(normalize_name
(['stream', 'x']),
30 cmp_deeply
(normalize_name
([$NS_STREAM, 'x']),
33 my $tag1 = normalize_name
('x');
35 my $tag3 = ['stream', 'x'];
36 my $tag4 = [$NS_STREAM, 'x'];
37 is
(same_name
($tag1, $tag2), 1, 'same names correctly compares names');
38 is
(same_name
($tag1, $tag1), 1);
39 is
(same_name
($tag2, $tag2), 1);
40 is
(same_name
($tag3, $tag3), 1);
41 is
(same_name
($tag3, $tag4), 1);
42 is
(same_name
($tag4, $tag4), 1);
43 is
(same_name
($tag1, $tag3), '');
44 is
(same_name
($tag2, $tag3), '');
47 # Verify that XML is handled in the expected manner
50 is
(ref($s), 'Thrasher::XMPPStreamIn', 'obj constructed');
52 my $messages = $s->parse(<<STREAM);
56 xmlns:stream='http://etherx.jabber.org/streams'
59 version='1.0'><stream:stream xmlns:stream="test" /></stream:stream>
66 [$NS_STREAM, 'stream'],
67 {'{}version' => '1.0',
68 "{$NS_STREAM}moo" => 'test',
69 '{}to' => 'example.com',
82 $messages = $s->parse(<<'STREAM');
86 xmlns:stream='http://etherx.jabber.org/streams'>
88 <iq type="set" to="moo">
89 <forbidden xmlns="stream-not-totally-awesome">
90 <yo>queiro taco bell?</yo>
94 <message to="moo@moo.com/Moo" from="baa@baa.com/Baa">
95 <body>You > make me smooth.</body>
96 <xhtml xmlns="oh.some.xhtml.ns.thingy">You > m<i>a</i>ke me smooth.</xhtml>
97 <stream:special xmlns:stream="specially.for.you">
98 <stream:termination />
104 cmp_deeply
($messages,
105 [[[$NS_STREAM, 'stream'],
106 {'{}to' => 'example.com'},
113 [['stream-not-totally-awesome',
118 [['stream-not-totally-awesome', 'yo'],
120 ['queiro taco bell?']
126 [[$NS_CLIENT, 'message'],
127 {'{}from' => 'baa@baa.com/Baa',
128 '{}to' => 'moo@moo.com/Moo'},
131 [[$NS_CLIENT, 'body'],
133 ['You > make me smooth.']],
136 [['oh.some.xhtml.ns.thingy', 'xhtml'],
139 [['oh.some.xhtml.ns.thingy', 'i'],
147 [['specially.for.you', 'special'],
152 [['specially.for.you', 'termination'],
162 'xml message parsing works as designed.');
167 my $test_element = [$NS_CLIENT, 'message'];
170 cmp_deeply
(extract
(undef, []), [],
171 'degenerate extraction case works');
175 extract
([[$NS_CLIENT, 'message'], undef, undef],
176 [[$NS_STREAM, 'message'], undef, undef]);
177 } 'namespace mismatch detected';
179 extract
([[$NS_CLIENT, 'message'], undef, undef],
180 [[$NS_CLIENT, 'iq'], undef, undef]);
181 } 'element name mismatch detected';
183 # attribute match fail
185 extract
([$test_element, { a
=> 'b' }, undef],
186 [[$NS_CLIENT, 'test'], {'{}a' => 'c'}, undef]);
187 } 'attribute mismatch detected.';
189 # Attribute matching works when the pattern just gives
190 # a straight attribute name with no preceding {} when
191 # the attribute is in the default namespace.
192 ok
(extract
([$test_element, { a
=> 'b' }, undef],
193 [$test_element, { '{}a' => 'b' }, undef]),
194 "don't have to provide default namespace specs for atts");
196 # children mismatch fail
198 extract
([$test_element, undef, ['x']],
199 [$test_element, undef, []]);
201 # children match succeed
202 cmp_deeply
(extract
([$test_element, undef, 'x'],
203 [$test_element, undef, ['y', 'x', []]]),
204 {}, 'simple children match works');
207 cmp_deeply
(extract
([save
("element"), undef, undef],
208 [[$NS_CLIENT, 'message'],
211 {element
=> [$NS_CLIENT, 'message']},
212 'non-recursive placeholder works');
214 # test sub placeholder
215 cmp_deeply
(extract
([save_sub
('element',
216 sub { my $x = shift; $x->[0] .=
217 'eee'; return $x; }),
219 [[$NS_CLIENT, 'message'], {}, []]),
220 {element
=> [$NS_CLIENT.'eee', 'message']},
221 'extracting with sub processing works.');
223 # test match placeholder
224 cmp_deeply
(extract
([[$NS_CLIENT, 'message'],
225 undef, save_match
([[$NS_CLIENT, 'body'],
226 undef, save
('body')])],
227 [[$NS_CLIENT, 'message'],
229 [[$NS_CLIENT, 'body'], {},
234 'extracting submatches works as expected');
238 extract
([take
('element'), undef, undef],
239 [[$NS_CLIENT, 'message'], {}, []],
240 {element
=> [$NS_CLIENT, 'message']});
242 extract
([[$NS_COMPONENT, 'handshake'], {}, []],
243 [[$NS_COMPONENT, 'handshake'], {}, []]);
246 extract
([take
('element'), undef, undef],
247 [[$NS_CLIENT, 'notamessage'], {}, []],
248 {element
=> [$NS_CLIENT, 'message']});
249 } 'Can pass in stuff to fill in placeholders.';
251 extract
([undef, {test
=> save
('x', 1)}, undef],
252 [[$NS_COMPONENT, 'test'], {}, []]);
253 pass
("Saving can be optional.");
255 extract
([undef, undef, save_match
('x', [undef, {x
=> 1}, []], 1)],
256 [[$NS_COMPONENT, 'test'], {}, []]);
257 pass
("save_matching can be optional");
259 # Recursive extracting: test that recursive extraction works as
261 my $XML = [[$NS_COMPONENT, 'top'], {},
262 [[[$NS_COMPONENT, 'middle'], {'{}x' => 1},
263 [[[$NS_COMPONENT, 'bottom'], {}, []]]]]];
264 my $results = recursive_extract
266 [[undef, 'top'], undef, save_match
('rec', [[undef, 'middle']])],
267 [undef, {x
=> save
('moo')}, save_match
('rec', [[undef, 'bottom']])]
269 is
($results->{moo
}, 1, 'found the attribute');
270 is
($results->{rec
}->[0]->[1], 'bottom',
271 'recurses as expected');
274 # These are packets that we encountered during testing that
275 # weren't handled correctly
277 # This is a message with typing notifications before the body,
278 # where the body is the word "menu", along with the XHTML.
279 my $message_with_typing = [
280 ['jabber:component:accept', 'message'],
283 '{}id' => 'purplea511de5f',
284 '{}from' => 'jbowers@barracudanetworks.com/Kopete',
285 '{}to' => 'gossipingabby@aim.transport'
288 [['jabber:x:event', 'x'],
291 [['jabber:x:event', 'composing'],
298 ['jabber:component:accept', 'body'],
303 ['http://jabber.org/protocol/xhtml-im', 'html'],
306 [['http://www.w3.org/1999/xhtml', 'body'],
315 my $match = [[$NS_COMPONENT, 'message'],
317 from
=> save
("from"),
318 type
=> save
("type")},
320 [[undef, 'body'], undef, undef])];
322 my $result = extract
($match, $message_with_typing);
323 cmp_deeply
($result->{body
},
324 [['jabber:component:accept', 'body'],
326 "body can be extracted even when not first");
331 'http://jabber.org/protocol/si/profile/file-transfer',
335 '{}size' => '3684376',
336 '{}name' => 'aim.capture.pkts'
342 'http://jabber.org/protocol/si/profile/file-transfer',
353 'http://jabber.org/protocol/si/profile/file-transfer',
363 $result = recursive_extract
366 save_match
('rec', [[undef, 'desc'], undef, undef])],
368 [undef, undef, save_sub
('desc', \
&text_extractor
)]);
370 cmp_deeply
($result->{desc
}, ['oeioei']);