#!/usr/bin/perl
# Test SOAP
use warnings;
use strict;
use lib 'lib','t';
use TestTools;
use Test::Deep qw/cmp_deeply/;
#use Log::Report mode => 3; # debugging
use Data::Dumper;
$Data::Dumper::Indent = 1;
use XML::Compile::WSDL11;
use XML::Compile::Tester;
use Test::More tests => 24;
use XML::LibXML;
use XML::Compile::SOAP::Util ':soap11';
use XML::Compile::SOAP11;
use XML::Compile::Transport::SOAPHTTP;
my $NS = 'urn:example:wsdl';
my $NSEXP = 'urn:sonae:elegibilidade:exp';
my $soapenv = SOAP11ENV;
my $schema = <<_SCHEMA;
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:exp="$NS"
targetNamespace="$NS">
<wsdl:types>
<xsd:schema targetNamespace="$NS">
<xsd:complexType name="list_part_type">
<xsd:all>
<xsd:element name="list" type="exp:listType" />
</xsd:all>
</xsd:complexType>
<xsd:element name="list" type="exp:listType" />
<xsd:complexType name="listType">
<xsd:sequence>
<xsd:element minOccurs="0" maxOccurs="unbounded" name="item">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:int"/>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="result" type="xsd:int"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="request_via_element">
<wsdl:part name="list" element="exp:list"/>
</wsdl:message>
<wsdl:message name="request_via_type">
<wsdl:part name="list" type="exp:listType"/>
</wsdl:message>
<wsdl:message name="answer_via_element">
<wsdl:part name="result" element="exp:result"/>
</wsdl:message>
<wsdl:message name="answer_via_type">
<wsdl:part name="result" type="xsd:int"/>
</wsdl:message>
<wsdl:portType name="query">
<wsdl:operation name="usingElement">
<wsdl:input message="exp:request_via_element"/>
<wsdl:output message="exp:answer_via_element"/>
</wsdl:operation>
<wsdl:operation name="usingType">
<wsdl:input message="exp:request_via_type"/>
<wsdl:output message="exp:answer_via_type"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="query_SOAPHTTP" type="exp:query">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="usingElement">
<soap:operation style="rpc"/>
<wsdl:input>
<soap:body use="literal" namespace="$NSEXP"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" namespace="$NSEXP"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="usingType">
<soap:operation style="rpc"/>
<wsdl:input>
<soap:body use="literal" namespace="$NSEXP"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" namespace="$NSEXP"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="service">
<wsdl:port binding="exp:query_SOAPHTTP" name="query">
<soap:address location="http://localhost:3000/ws/exp/soap"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
_SCHEMA
### HELPER
my ($server_expects, $server_answers);
sub fake_server($$)
{ my ($request, $trace) = @_;
my $content = $request->decoded_content;
compare_xml($content, $server_expects, 'fake server received');
#warn "CONTENT=$content###";
HTTP::Response->new(200, 'answer manually created'
, [ 'Content-Type' => 'text/xml' ], $server_answers);
}
#
# Create and interpret a message
#
my $soap = XML::Compile::SOAP11::Client->new;
isa_ok($soap, 'XML::Compile::SOAP11::Client');
isa_ok($soap, 'XML::Compile::SOAP11');
my $wsdl = XML::Compile::WSDL11->new($schema);
ok(defined $wsdl, "created object");
isa_ok($wsdl, 'XML::Compile::WSDL11');
$wsdl->prefixes(sonae => $NSEXP);
#
# Element part
#
ok(1, "** using element");
my $eop = $wsdl->operation('usingElement');
isa_ok($eop, 'XML::Compile::SOAP11::Operation');
is($eop->name, 'usingElement');
is($eop->style, 'rpc');
my $er = $eop->compileClient(transport_hook => \&fake_server);
isa_ok($er, 'CODE');
$server_expects = <<_EXPECTS;
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="$soapenv" xmlns:sonae="$NSEXP">
<SOAP-ENV:Body>
<sonae:usingElement>
<exp:list xmlns:exp="$NS">
<item><id>1</id><name>aap</name></item>
<item><id>2</id><name>noot</name></item>
<item><id>3</id><name>mies</name></item>
</exp:list>
</sonae:usingElement>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
_EXPECTS
$server_answers = <<_ANSWER;
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="$soapenv">
<SOAP-ENV:Body>
<sonae:usingElementResponse xmlns:sonae="$NSEXP">
<exp:result xmlns:exp="$NS">3</exp:result>
</sonae:usingElementResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
_ANSWER
my %data = ( item =>
[ { id => 1, name => 'aap' }
, { id => 2, name => 'noot' }
, { id => 3, name => 'mies' } ] );
my $ea = $er->(\%data);
ok(defined $ea, 'got element answer');
my $u = $ea->{usingElementResponse};
isa_ok($u, 'HASH');
cmp_ok(keys %$u, '==', 1);
is($u->{result}, '3');
#
# Type part
#
ok(1, "** using type");
my $top = $wsdl->operation('usingType');
isa_ok($top, 'XML::Compile::SOAP11::Operation', 'using type');
is($top->name, 'usingType');
is($top->style, 'rpc');
my $tr = $top->compileClient(transport_hook => \&fake_server);
isa_ok($tr, 'CODE');
$server_expects = <<_REQUEST;
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="$soapenv" xmlns:sonae="$NSEXP">
<SOAP-ENV:Body>
<sonae:usingType>
<list>
<item><id>1</id><name>aap</name></item>
<item><id>2</id><name>noot</name></item>
<item><id>3</id><name>mies</name></item>
</list>
</sonae:usingType>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
_REQUEST
$server_answers = <<_ANSWER;
<SOAP-ENV:Envelope xmlns:SOAP-ENV="$soapenv">
<SOAP-ENV:Body>
<sonae:usingTypeResponse xmlns:sonae="$NSEXP">
<result>5</result>
</sonae:usingTypeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
_ANSWER
my $ta = $tr->(%data);
ok(defined $ta, 'got type answer');
my $r = $ta->{usingTypeResponse};
isa_ok($r, 'HASH');
cmp_ok(keys %$r, '==', 1);
is($r->{result}, '5');