1#!/bin/env perl 2 3BEGIN { 4 unless(grep /blib/, @INC) { 5 chdir 't' if -d 't'; 6 unshift @INC, '../lib' if -d '../lib'; 7 } 8} 9 10use strict; 11use Test; 12 13BEGIN { plan tests => 42; } 14 15use SOAP::Lite; 16 17my($a, $s, $r, $serialized, $deserialized); 18 19{ # check 'use ...' 20 print "'use SOAP::Lite ...' test(s)...\n"; 21 eval 'use SOAP::Lite 99.99'; # hm, definitely should fail 22 ok(scalar $@ =~ /99.+required/); 23} 24 25# These tests are for backwards compatibility 26{ # check use of use_prefix and uri together 27 # test 2 - turn OFF default namespace 28 $SIG{__WARN__} = sub { ; }; # turn off deprecation warnings 29 $serialized = SOAP::Serializer->use_prefix(1)->uri("urn:Test")->method( 30 'testMethod', SOAP::Data->name(test => 123) 31 ); 32 ok($serialized =~ m!<soap:Body><namesp(\d):testMethod><test xsi:type="xsd:int">123</test></namesp\1:testMethod></soap:Body>!); 33 34 # test 3 - turn ON default namespace 35 $serialized = SOAP::Serializer->use_prefix(0)->uri("urn:Test")->method( 36 'testMethod', SOAP::Data->name(test => 123) 37 ); 38 ok($serialized =~ m!<soap:Envelope(?: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"| xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"| xmlns:xsd="http://www.w3.org/2001/XMLSchema"| soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"| xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"){5}><soap:Body><testMethod xmlns="urn:Test"><test xsi:type="xsd:int">123</test></testMethod></soap:Body></soap:Envelope>!); 39 40} 41 42{ # check use of default_ns, ns, and use_prefix 43 # test 4 44 $serialized = SOAP::Serializer->ns("urn:Test")->method( 45 'testMethod', SOAP::Data->name(test => 123) 46 ); 47 ok($serialized =~ m!<namesp(\d):testMethod><test xsi:type="xsd:int">123</test></namesp\1:testMethod>!); 48 49 # test 5 50 $serialized = SOAP::Serializer->ns("urn:Test","testns")->method( 51 'testMethod', SOAP::Data->name(test => 123) 52 ); 53 ok($serialized =~ m!<testns:testMethod><test xsi:type="xsd:int">123</test></testns:testMethod>!); 54 55 # test 6 56 $serialized = SOAP::Serializer->default_ns("urn:Test")->method( 57 'testMethod', SOAP::Data->name(test => 123) 58 ); 59 ok($serialized =~ m!<soap:Body><testMethod xmlns="urn:Test"><test xsi:type="xsd:int">123</test></testMethod></soap:Body>!); 60} 61 62{ # check serialization 63 print "Arrays, structs, refs serialization test(s)...\n"; 64 $serialized = SOAP::Serializer->serialize( 65 SOAP::Data->name(test => \SOAP::Data->value(1, [1,2], {a=>3}, \4)) 66 ); 67 ok($serialized =~ m!<test(?: xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"| xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"| xmlns:xsd="http://www.w3.org/2001/XMLSchema"){4}><c-gensym(\d+) xsi:type="xsd:int">1</c-gensym\1><soapenc:Array(?: xsi:type="soapenc:Array"| soapenc:arrayType="xsd:int\[2\]"){2}><item xsi:type="xsd:int">1</item><item xsi:type="xsd:int">2</item></soapenc:Array><c-gensym(\d+)><a xsi:type="xsd:int">3</a></c-gensym\2><c-gensym(\d+)><c-gensym(\d+) xsi:type="xsd:int">4</c-gensym\4></c-gensym\3></test>!); 68 69} 70 71{ # check simple circular references 72 print "Simple circular references (\$a=\\\$a) serialization test(s)...\n"; 73 74 $a = \$a; 75 $serialized = SOAP::Serializer->namespaces({})->serialize($a); 76 77 ok($serialized =~ m!<c-gensym(\d+) id="ref-(\w+)"><c-gensym(\d+) href="#ref-\2" /></c-gensym\1>!); 78 79 $a = SOAP::Deserializer->deserialize($serialized)->root; 80 ok(0+$a == 0+(values%$a)[0]); 81} 82 83{ # check complex circular references 84 print "Complex circlular references serialization test(s)...\n"; 85 86 $a = SOAP::Deserializer->deserialize(<<'EOX')->root; 87<root xmlns="urn:Foo"> 88 <a id="id1"> 89 <x>1</x> 90 <next id="id2"> 91 <x>7</x> 92 <next href="#id3" /> 93 </next> 94 </a> 95 <item id="id3"> 96 <x>8</x> 97 <next href="#id1" /> 98 </item> 99</root> 100EOX 101 102 ok($a->{a}->{next}->{next}->{next}->{next}->{x} == 103 $a->{a}->{next}->{x}); 104 105 $a = { a => 1 }; my $b = { b => $a }; $a->{a} = $b; 106 $serialized = SOAP::Serializer->autotype(0)->namespaces({})->serialize($a); 107 108 ok($serialized =~ m!<c-gensym(\d+) id="ref-(\w+)"><a id="ref-\w+"><b href="#ref-\2" /></a></c-gensym\1>!); 109} 110 111{ # check multirefs 112 print "Multireferences serialization test(s)...\n"; 113 114 $a = 1; my $b = \$a; 115 116 $serialized = SOAP::Serializer->new(multirefinplace=>1)->serialize( 117 SOAP::Data->name(test => \SOAP::Data->value($b, $b)) 118 ); 119 120 ok($serialized =~ m!<test(?: xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"| xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"| xmlns:xsd="http://www.w3.org/2001/XMLSchema"){4}><c-gensym(\d+) id="ref-(\w+)"><c-gensym(\d+) xsi:type="xsd:int">1</c-gensym\3></c-gensym\1><c-gensym\d+ href="#ref-\2" /></test>!); 121 122 $serialized = SOAP::Serializer->namespaces({})->serialize( 123 SOAP::Data->name(test => \SOAP::Data->value($b, $b)) 124 ); 125print $serialized, "\n"; 126 ok($serialized =~ m!<c-gensym\d+ href="#ref-(\w+)" /><c-gensym\d+ href="#ref-\1" /><c-gensym(\d+) id="ref-\1"><c-gensym(\d+) xsi:type="xsd:int">1</c-gensym\3></c-gensym\2>!); 127} 128 129{ # check base64, XML encoding of elements and attributes 130 print "base64, XML encoding of elements and attributes test(s)...\n"; 131 132 $serialized = SOAP::Serializer->serialize( 133 SOAP::Data->name(test => \SOAP::Data->value("\0\1\2\3 \4\5\6", "<123>&\015</123>")) 134 ); 135 136 ok($serialized =~ m!<c-gensym(\d+) xsi:type="xsd:base64Binary">AAECAyAgIAQFBg==</c-gensym\1><c-gensym(\d+) xsi:type="xsd:string"><123>&amp;
</123></c-gensym\2>!); 137 138 $serialized = SOAP::Serializer->namespaces({})->serialize( 139 SOAP::Data->name(name=>'value')->attr({attr => '<123>"&"</123>'}) 140 ); 141 142 ok($serialized =~ m!^<\?xml version="1.0" encoding="UTF-8"\?><name(?: xsi:type="xsd:string"| attr="<123>"&amp"</123>"){2}>value</name>$!); 143} 144 145{ # check objects and SOAP::Data 146 print "Blessed references and SOAP::Data encoding test(s)...\n"; 147 148 $serialized = SOAP::Serializer->serialize(SOAP::Data->uri('some_urn' => bless {a => 1} => 'ObjectType')); 149 150 ok($serialized =~ m!<namesp(\d+):c-gensym(\d+)(:? xsi:type="namesp\d+:ObjectType"| xmlns:namesp\d+="http://namespaces.soaplite.com/perl"| xmlns:namesp\1="some_urn"| xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"| xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"| xmlns:xsd="http://www.w3.org/2001/XMLSchema"){7}><a xsi:type="xsd:int">1</a></namesp\1:c-gensym\2>!); 151} 152 153{ # check serialization/deserialization of simple types 154 print "Serialization/deserialization of simple types test(s)...\n"; 155 156 $a = 'abc234xyz'; 157 158 $serialized = SOAP::Serializer->serialize(SOAP::Data->type(hex => $a)); 159 160 ok($serialized =~ m!<c-gensym(\d+)(?: xsi:type="xsd:hexBinary"| xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"| xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"| xmlns:xsd="http://www.w3.org/2001/XMLSchema"){5}>61626332333478797A</c-gensym(\d+)>!); 161 ok(SOAP::Deserializer->deserialize($serialized)->root eq $a); 162 163 $a = <<"EOBASE64"; 164qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?`1234567890-=\~!@#$%^&*()_+| 165EOBASE64 166 167 $serialized = SOAP::Serializer->serialize($a); 168 169 ok(index($serialized, quotemeta(q!qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>?`1234567890-=~\!@#0^&*()_+|!))); 170 171 if (UNIVERSAL::isa(SOAP::Deserializer->parser->parser => 'XML::Parser::Lite')) { 172 skip(q!Entity decoding is not supported in XML::Parser::Lite! => undef); 173 } else { 174 ok(SOAP::Deserializer->deserialize($serialized)->root eq $a); 175 } 176 177 $a = <<"EOBASE64"; 178 179qwertyuiop[]asdfghjkl;'zxcvbnm,./ 180QWERTYUIOP{}ASDFGHJKL:"ZXCVBNM<>? 181\x00 182 183EOBASE64 184 185 $serialized = SOAP::Serializer->serialize($a); 186 187 ok($serialized =~ /base64/); 188} 189 190{ # check serialization/deserialization of blessed reference 191 print "Serialization/deserialization of blessed reference test(s)...\n"; 192 193 $serialized = SOAP::Serializer->serialize(bless {a => 1} => 'SOAP::Lite'); 194 $a = SOAP::Deserializer->deserialize($serialized)->root; 195 196 ok(ref $a eq 'SOAP::Lite' && UNIVERSAL::isa($a => 'HASH')); 197 198 $a = SOAP::Deserializer->deserialize( 199 SOAP::Serializer->serialize(bless [a => 1] => 'SOAP::Lite') 200 )->root; 201 202 ok(ref $a eq 'SOAP::Lite' && UNIVERSAL::isa($a => 'ARRAY')); 203} 204 205{ # check serialization/deserialization of undef/empty elements 206 print "Serialization/deserialization of undef/empty elements test(s)...\n"; 207 208 { local $^W; # suppress warnings 209 $a = undef; 210 $serialized = SOAP::Serializer->serialize( 211 SOAP::Data->type(negativeInteger => $a) 212 ); 213 214 ok(! defined SOAP::Deserializer->deserialize($serialized)->root); 215 216 my $type = 'nonstandardtype'; 217 eval { 218 $serialized = SOAP::Serializer->serialize( 219 SOAP::Data->type($type => $a) 220 ); 221 }; 222 ok($@ =~ /for type '$type' is not specified/); 223 224 $serialized = SOAP::Serializer->serialize( 225 SOAP::Data->type($type => {}) 226 ); 227 228 ok(ref SOAP::Deserializer->deserialize($serialized)->root eq $type); 229 } 230} 231 232{ 233 print "Check for unspecified Transport module test(s)...\n"; 234 235 eval { SOAP::Lite->new->abc() }; 236 ok($@ =~ /A service address has not been specified/); 237} 238 239{ 240 print "Deserialization of CDATA test(s)...\n"; 241 242 UNIVERSAL::isa(SOAP::Deserializer->parser->parser => 'XML::Parser::Lite') ? 243 skip(q!CDATA decoding is not supported in XML::Parser::Lite! => undef) : 244 ok(SOAP::Deserializer->deserialize('<root><![CDATA[<123>]]></root>')->root eq '<123>'); 245} 246 247{ 248 print "Test of XML::Parser External Entity vulnerability...\n"; 249 UNIVERSAL::isa(SOAP::Deserializer->parser->parser => 'XML::Parser::Lite') ? 250 skip(q!External entity references are not supported in XML::Parser::Lite! => undef) : 251 ok(!eval { SOAP::Deserializer->deserialize('<?xml version="1.0"?><!DOCTYPE foo [ <!ENTITY ll SYSTEM "foo.txt"> ]><root>≪</root>')->root } and $@ =~ /^External entity/); 252} 253 254{ 255 print "Test SOAP:: prefix with no +autodispatch option...\n"; 256 eval { A->SOAP::b }; 257 ok($@ =~ /^SOAP:: prefix/); 258} 259 260{ 261 # check deserialization of an array of multiple elements 262 # nested within a complex type 263 print "Deserialization of document/literal arrays nested in complex types...\n"; 264 my $input = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"><soap:Body><getFooResponse xmlns="http://example.com/v1"><getFooReturn><id>100</id><complexFoo><arrayFoo>one</arrayFoo><arrayFoo>two</arrayFoo></complexFoo></getFooReturn></getFooResponse></soap:Body></soap:Envelope>'; 265 my $deserializer = SOAP::Deserializer->new; 266 my $ret = $deserializer->deserialize($input); 267 my @arr = @{$ret->result->{'complexFoo'}{'arrayFoo'}}; 268 ok($#arr == 1); 269 ok("one" eq $arr[0]); 270 ok("two" eq $arr[1]); 271 272 ok(100 == $ret->result->{"id"}); 273 274 # If only one araryFoo tag is found, it's deserialized as a scalar. 275 $input = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"><soap:Body><getFooResponse xmlns="http://example.com/v1"><getFooReturn><id>100</id><complexFoo><arrayFoo>one</arrayFoo></complexFoo></getFooReturn></getFooResponse></soap:Body></soap:Envelope>'; 276 $ret = $deserializer->deserialize($input); 277 ok("one" eq $ret->result->{'complexFoo'}{'arrayFoo'}); 278} 279 280 281{ 282 print "Serialization of document/literal arrays\n"; 283 # check array serialization with autotyping disabled 284 my $serializer = SOAP::Serializer->new; 285 $serializer->autotype(0); 286 287 my $hash = { 288 "scalar" => 1, 289 "array" => [ 2, 3], 290 "hash" => { 291 "scalar" => 4, 292 "array" => [ 5, 6], 293 } 294 }; 295 296 my $xml = $serializer->serialize($hash); 297 298 ok($xml =~ m{ 299 <c-gensym\d+\s[^>]*> 300 (:? 301 <hash> 302 (:? 303 <array>5</array><array>6</array> 304 |<scalar>4</scalar> 305 ){2} 306 </hash> 307 | <array>2</array><array>3</array> 308 | <scalar>1</scalar> 309 ){3} 310 </c-gensym\d+> 311 }xms 312 ); 313 314 # deserialize it and check that a similar object is created 315 my $deserializer = SOAP::Deserializer->new; 316 317 my $obj = $deserializer->deserialize($xml)->root; 318 319 ok(1, $obj->{"scalar"}); 320 my @arr= @{$obj->{"array"}}; 321 ok(2, $arr[0]); 322 ok(3, $arr[1]); 323 ok(4, $obj->{"hash"}{"scalar"}); 324 @arr = @{$obj->{"hash"}{"array"}}; 325 ok(5, $arr[0]); 326 ok(6, $arr[1]); 327} 328