Stub XMLRPC::Client call in rails test with rspec - ruby-on-rails-3

I'm trying to stub XMLRPC::Client.call in my rspec tests in rails.
Here is my method:
def xmlrpc_call(location, repeat, func, *args)
Rails.logger.debug("XML_RPC: calling #{func}(#{args.inspect})")
timeout = XMLRPC_TIMEOUT ? XMLRPC_TIMEOUT : 90
begin
server = XMLRPC::Client.new2(location, nil, timeout)
result = server.call(func, *args)
rescue XMLRPC::FaultException => e
Rails.logger.error "XMLRPC FaultException: #{e.faultCode}, Exception: #{e.faultString}"
log_abp_error("#{func}: #{e.faultCode} (wrapper, rescue 1, try: #{(repeat ? "1":"2")})")
#xmlrpc_exception = e
false
end
result
end#xmlrpc_call
Here is my tests:
describe "#xmlrpc_call" do
it 'should return success' do
stub_request(:post, "http://google.com/RPC2").
with(:body => "<?xml version=\"1.0\" ?><methodCall> <methodName>CallGoogle</methodName><params><param><value><string>foo</string></value></param><param><value><string>bar</string></value></param></params></methodCall>\n",
:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Connection'=>'keep-alive', 'Content-Length'=>'200', 'Content-Type'=>'text/xml; charset=utf-8', 'User-Agent'=>'XMLRPC::Client (Ruby 2.1.1)'}).
to_return(:status => 200, :body => "success", :headers => {})
XmlRpcCallHelper.xmlrpc_call("http://google.com", true, "CallGoogle", "foo", "bar")
end#success
end#xmlrpc_call
I'm getting this error:
Failure/Error: XmlRpcCallHelper.xmlrpc_call("http://google.com", true, "CallGoogle", "foo", "bar")
RuntimeError:
Missing return value!
If I use empty response body in stub, I'm getting:
Failure/Error: XmlRpcCallHelper.xmlrpc_call("http://google.com", true, "CallGoogle", "foo", "bar")
NoMethodError:
undefined method `bytesize' for nil:NilClass
This Using webmock to mock XMLRPC client in rspec-rails didn't works for me too.
Any help is much appreciated.
Thanks!

create response using this code.
before do
stub_request(:post, "http://api-test.com/host_add").to_return(
{ :body => XMLRPC::Create.new.methodResponse(true, { hoge: "test"} ), :status => 200 }
)
end
XMLRPC::Create.new.methodResponse is hash to xml

That code worked for me:
context "success" do
before do
stub_request(:post, "http://srv476.offsidebet.com:8080/abp/webApiXmlRpcServlet").
with(:body => "<?xml version=\"1.0\" ?><methodCall><methodName>func</methodName><params><param><value><string>a</string></value></param><param><value><string>b</string></value></param><param><value><string>c</string></value></param></params></methodCall>\n",
:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Connection'=>'keep-alive', 'Content-Length'=>'238', 'Content-Type'=>'text/xml; charset=utf-8', 'User-Agent'=>'XMLRPC::Client (Ruby 2.1.1)'}).
to_return(:status => 200, :body => File.read("#{Rails.root}/spec/fixtures/xml_rpc_call_helper/response_ok.xml"), :headers => {})
end
let(:response){ {"wm_description"=>"manual create", "wm_ticket_number"=>"1408171142773", "ABPBuildNumber"=>"436 r${svn.Revision}", "wm_payment_number"=>"41902112", "wm_sim_mode"=>"0", "wm_redirect_url"=>"https://exmaple.com/entrypoint", "WEBAPIVersionNumber"=>"0.57", "wm_purse"=>"12345"} }
it {XmlRpcCallHelper.xmlrpc_call(XML_RPC_LOCATION, true, 'func', 'a','b','c').should eq(response)}
end#success
Fixture:
<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>wm_description</name>
<value>manual create</value>
</member>
<member>
<name>wm_ticket_number</name>
<value>1408171142773</value>
</member>
<member>
<name>ABPBuildNumber</name>
<value>436 r${svn.Revision}</value>
</member>
<member>
<name>wm_payment_number</name>
<value>41902112</value>
</member>
<member>
<name>wm_sim_mode</name>
<value>0</value>
</member>
<member>
<name>wm_redirect_url</name>
<value>https://exmaple.com/entrypoint</value>
</member>
<member>
<name>WEBAPIVersionNumber</name>
<value>0.57</value>
</member>
<member>
<name>wm_purse</name>
<value>12345</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>

Related

Mobilefirst-8.0 JavaScript Adapter for SOAP service

I have created MobileFirstPlatform-v8.0 Javascript Adapter which invokes a SOAP web service. But I am unable to get a response from my swagger tool and WLRequest invoke procedure also. Kindly assist me.
My project environment : Mfp 8.0 with IONIC2 and AngularJS2
currently my SOAP service running in local tomcat server.
code :
<connectivity>
<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
<protocol>http</protocol>
<domain>localhost</domain>
<port>8080</port>
<connectionTimeoutInMilliseconds>30000</connectionTimeoutInMilliseconds>
<socketTimeoutInMilliseconds>30000</socketTimeoutInMilliseconds>
<maxConcurrentConnectionsPerNode>50</maxConcurrentConnectionsPerNode>
</connectionPolicy>
</connectivity>
<procedure name="getFeed" secured="false"/>
adapter-impl.js file
function getFeed(type) {
MFP.Logger.error("----------------"+type);
var request =
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://jee.javapapers.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<q0:animalType>
<q0:animal>{type}</q0:animal>
</q0:animalType>
</soapenv:Body>
</soapenv:Envelope>;
MFP.Logger.error("-----request ----"+request);
var input = {
method: 'post',
returnedContentType: 'xml',
path: '/animalType.asmx',
body: {
content: request.toString(),
contentType: 'text/xml; charset=utf-8'
}
};
var result = MFP.Server.invokeHttp(input);
return result.Envelope.Body;
};
invokeAdapter(){
var resourceRequest = new WLResourceRequest("/adapters/HTTPSOAP/getFeed/",WLResourceRequest.POST);
resourceRequest.setQueryParameter("params", "['world']");
resourceRequest.send().then((response) => {
console.log("success"+JSON.stringify(response));
},
function(error){
console.log("---failed--->"+JSON.stringify(error));
});
}
Error mfp message logs:
FWLST0904E: Exception was thrown while invoking procedure: {0} in
adapter: {1} Http request failed: java.net.SocketException: Connection
reset
Thanks advance...

Consuming SOAP web service in SENCHA TOUCH?

I have found this post that worked for me but I recieved a HTML response instead of a XML one which is what I need for my app.
How to consume SOAP web service in SENCHA TOUCH?
This is my request to my server... I know I should be doing a POST action as this guy was told, but I still get a root node error.
Is this the proper way to consume a WebService, or there is another way to consume in Sencha using data models and stores? I have already saw an example using CFC but I am using IIS 7.5
POST /url/mobilews.asmx HTTP/1.1
Host: 10.0.1.182
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/" />
</soap:Body>
</soap:Envelope>
Ext.Ajax.request({
method: 'GET',
url: 'http://url/mobileservice/mobilews.asmx?op=HelloWorld',
params: { method: 'HelloWorld', format: 'json' },
success: function (response, request) {
alert('Working!');
alert(response.responseText);
},
failure: function (response, request) {
alert('Not working!');
}
});
Here goes the error message:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Xml.XmlException: Data at the root level is invalid. Line 1, position 1.

WCF Soap Service Deserialization failed (unrecognized element was encountered)

I build a WCF selfhosted WS (basichttp-binding) with 2 methods. Then created a WSDL and delivered it to a customer. Now they are sending SOAP-requests to the service but one of my methods (PostSendeplatz) fails everytime with a null parameter. In the trace I see the following:
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Verbose">
<TraceIdentifier>http://msdn.microsoft.com/de-DE/library/System.Runtime.Serialization..aspx</TraceIdentifier>
<Description>An unrecognized element was encountered in the XML during deserialization which was ignored.</Description>
<AppDomain>RabbitServerTopSelf.vshost.exe</AppDomain>
<ExtendedData xmlns="http://schemas.microsoft.com/2006/08/ServiceModel/StringTraceRecord">
<Element>http://plantri.de:sendeplatz</Element>
</ExtendedData>
</TraceRecord>
I checked my namespaces in DataContracts, ServiceContract and ServiceImplementation:
[ServiceContract(Namespace = "http://plantri.de")]
public interface IRabbitImportService {
[OperationContract]
bool PostSendung(Sendung sendung, out string errorMsg);
[OperationContract]
bool PostSendeplatz(Sendeplatz sendePlatz, out string errorMsg);
}
...
[DataContract(Namespace = "http://plantri.de")]
public class Sendeplatz : RabbitIdBase { ...
...
[DataContract(Namespace = "http://plantri.de")]
public class Sendung : RabbitIdBase { ...
...
[ServiceBehavior(Namespace="http://plantri.de")]
public class RabbitImportService : Log4NetLogWriter, IRabbitImportService {
...
public bool PostSendung(Sendung sendung, out string errorMsg) {
... do something and return success
}
public bool PostSendeplatz(Sendeplatz sendePlatz, out string errorMsg) {
errorMsg = String.Empty;
if (sendePlatz == null) {
Error("no Sendeplatz send!");
return false;
}
... never came until this point!!!!
}
Here is a part of the soap-envelope which isn't deserialized (from the trace):
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://192.168.40.64:8800/RabbitImportService</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://plantri.de/IRabbitImportService/PostSendeplatz</Action>
</s:Header>
<soapenv:Body>
<PostSendeplatz xmlns="http://plantri.de">
<sendeplatz>
<Id>1258878</Id>
...
But the working envelope looks quite the same:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://192.168.40.64:8800/RabbitImportService</To>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://plantri.de/IRabbitImportService/PostSendung</Action>
</s:Header>
<soapenv:Body>
<PostSendung xmlns="http://plantri.de">
<sendung>
<Id>564589</Id>
...
I don't have a chance to change the client proxy which was writen by a customer (JAVA).
Did anyone have an idea to solve the problem?
But the working envelope looks quite the same: How?
<PostSendeplatz xmlns="http://plantri.de">
<sendeplatz>
<PostSendung xmlns="http://plantri.de">
<sendung>
I see these tag names differs.

RoR: Error when connecting affilinet web services (logon function) using savon (ruby on rails) -> Deserialization Failed

I try to logon at the affilinet web services via the provided logon function. I'm working in a Rails 3 environment (3.0.x). I utilize the ruby on rails gem Savon in version 2 which in turn uses soap to connect to affilinet.
The most current wsdl can be found here https://api.affili.net/V2.0/Logon.svc?wsdl.
My code looks like this:
client = Savon.client do
wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
message = {'Username' => 'username', 'Password' => 'password', 'WebServiceType' => 'Publisher'}
response = client.call(:logon, :message => message)
The request generated by Savon:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://affilinet.framework.webservices/Svc" xmlns:ins3="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:ins2="http://affilinet.framework.webservices/types" xmlns:ins1="http://schemas.datacontract.org/2004/07/Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF" xmlns:ins0="http://www.microsoft.com/practices/EnterpriseLibrary/2007/01/wcf/validation" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<tns:LogonRequestMsg>
<tns:Password>password</tns:Password>
<tns:WebServiceType>Publisher</tns:WebServiceType>
<tns:Username>username</tns:Username>
</tns:LogonRequestMsg>
</env:Body>
</env:Envelope>
When sending this request to the web service I get this (error) response:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:DeserializationFailed</faultcode>
<faultstring xml:lang="en-US">The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://affilinet.framework.webservices/Svc:LogonRequestMsg. The InnerException message was 'Error in line 1 position 775. 'EndElement' 'LogonRequestMsg' from namespace 'http://affilinet.framework.webservices/Svc' is not expected. Expecting element 'Username | Password | WebServiceType'.'. Please see InnerException for more details.</faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException>
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message>Error in line 1 position 775. 'EndElement' 'LogonRequestMsg' from namespace 'http://affilinet.framework.webservices/Svc' is not expected. Expecting element 'Username | Password | WebServiceType'.</Message>
<StackTrace> at System.Runtime.Serialization.XmlObjectSerializerReadContext.ThrowRequiredMemberMissingException(XmlReaderDelegator xmlReader, Int32 memberIndex, Int32 requiredIndex, XmlDictionaryString[] memberNames)
 ... (loads more) ...
</StackTrace>
<Type>System.ServiceModel.Dispatcher.NetDispatcherFaultException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
Any ideas what's wrong?
EDIT:
The request in soapUI looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:svc="http://affilinet.framework.webservices/Svc" xmlns:typ="http://affilinet.framework.webservices/types">
<soapenv:Header/>
<soapenv:Body>
<svc:LogonRequestMsg>
<!--Optional:-->
<typ:Username>username</typ:Username>
<!--Optional:-->
<typ:Password>password</typ:Password>
<typ:WebServiceType>Publisher</typ:WebServiceType>
<!--Optional:-->
<typ:DeveloperSettings>
<!--Optional:-->
<typ:SandboxPublisherID>?</typ:SandboxPublisherID>
</typ:DeveloperSettings>
<!--Optional:-->
<typ:ApplicationSettings>
<!--Optional:-->
<typ:ApplicationID>?</typ:ApplicationID>
<!--Optional:-->
<typ:DeveloperID>?</typ:DeveloperID>
</typ:ApplicationSettings>
</svc:LogonRequestMsg>
</soapenv:Body>
</soapenv:Envelope>
Maybe the differences in the requests (generated by Savon and by soapUI) are the key!? Especially the different namespaces: svc/typ vs. env/tns. Any ideas? How can I tell Savon to use the svc namespace for the LogonRequestMsg?
Looking into the WSDL of Affili.net it shows that username, password, WebserviceType etc have the wrong namespace.
EDITED for the namespace after another look into your example. Username, Password and WebServiceType are defined in the namespace ins2="http://affilinet.framework.webservices/types" which is tagged by "ins2" in your case.
The quick and dirty way to get over it is
client = Savon.client do
wsdl "https://api.affili.net/V2.0/Logon.svc?wsdl"
end
message = {'ins2:Username' => 'username',
'ins2:Password' => 'password',
'ins2:WebServiceType' => 'Publisher'}
response = client.call(:logon, :message => message)
i think the problem is with namespace order, after several request saw different order in namespace.
This code works for me (savod version 1), overwrite namespaces:
message = {
'ins0:Username' => 'XXXXXXX',
'ins0:Password' => 'XXXXXXX',
'ins0:WebServiceType' => 'XXXXXX',
:order! => ['ins0:Username', 'ins0:Password', 'ins0:WebServiceType']
}
#client.wsdl.document = 'https://api.affili.net/V2.0/Logon.svc?wsdl'
response = #client.request :logon do
soap.body = message
soap.namespaces["xmlns:ins0"] = "http://affilinet.framework.webservices/types"
soap.namespaces["xmlns:ins1"] = "http://schemas.microsoft.com/2003/10/Serialization/Arrays"
soap.namespaces["xmlns:ins2"] = "http://www.microsoft.com/practices/EnterpriseLibrary/2007/01/wcf/validation"
soap.namespaces["xmlns:ins3"] = "http://schemas.datacontract.org/2004/07/Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF"
end

Objective C, A Question about xpath

<methodResponse>
<params>
<param>
<value>
<struct>
<member>
<name>topic_id</name>
<value>
<string>102</string>
</value>
</member>
<member>
<name>topic_title</name>
<value>
<string>Login test</string>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodResponse>
I have this xml.. How to get the value of topic_title using xpath?
/methodResponse
/params
/param
/value
/struct
/member[name='topic_title']
/value
/string