Index: /server/trunk/web/t/controller_Chat-Cmd.t
===================================================================
--- /server/trunk/web/t/controller_Chat-Cmd.t	(revision 157)
+++ /server/trunk/web/t/controller_Chat-Cmd.t	(revision 158)
@@ -2,8 +2,16 @@
 use warnings;
 use Test::More;
+use FindBin;
+require "$FindBin::Bin/xml.pl";
 
 BEGIN { use_ok 'Catalyst::Test', 'Sophie' }
 BEGIN { use_ok 'Sophie::Controller::Chat::Cmd' }
 
-#ok( request('/chat/cmd')->is_success, 'Request should succeed' );
+foreach (qw(version v packager p arch a buildfrom)) {
+    ok(
+        xmlrequest_ok("chat.cmd.$_", {}, "rpm"),
+        "XML::RPC chat.cmd.$_"
+    );
+}
+
 done_testing();
Index: /server/trunk/web/t/controller_Chat.t
===================================================================
--- /server/trunk/web/t/controller_Chat.t	(revision 157)
+++ /server/trunk/web/t/controller_Chat.t	(revision 158)
@@ -2,4 +2,6 @@
 use warnings;
 use Test::More;
+use FindBin;
+require "$FindBin::Bin/xml.pl";
 
 BEGIN { use_ok 'Catalyst::Test', 'Sophie' }
@@ -7,3 +9,6 @@
 
 ok( request('/chat')->is_success, 'Request should succeed' );
+
+ok( xmlrequest_ok( 'chat.message', [], "help"), "Can request help");
+
 done_testing();
Index: /server/trunk/web/t/controller_Distrib.t
===================================================================
--- /server/trunk/web/t/controller_Distrib.t	(revision 157)
+++ /server/trunk/web/t/controller_Distrib.t	(revision 158)
@@ -2,6 +2,7 @@
 use warnings;
 use Test::More;
-require RPC::XML;
-use HTTP::Request;
+use Test::More;
+use FindBin;
+require "$FindBin::Bin/xml.pl";
 
 # know existing data:
@@ -16,19 +17,8 @@
 BEGIN { use_ok 'Sophie::Controller::Distrib' }
 
-sub xmlrpcreq {
-    my (@xmlargs) = @_;
-    my $str = RPC::XML::request->new( @xmlargs )->as_string;
-
-    my $req = HTTP::Request->new( POST => 'http://localhost/rpc' );
-    $req->header( 'Content-Length'  => length($str) );
-    $req->header( 'Content-Type'    => 'text/xml' );
-    $req->content( $str );
-    return $req;
-}
-
 ok( request('/distrib')->is_success, 'Request should succeed' );
 ok( request("/distrib/$distribution")->is_success, 'Request should succeed' );
-ok( request( xmlrpcreq('distrib.list') ), "XMLRPC");
-ok( request( xmlrpcreq('distrib.list', $distribution) ), "XMLRPC");
+ok( xmlrequest_ok( 'distrib.list'), "XMLRPC");
+ok( xmlrequest_ok( 'distrib.list', $distribution), "XMLRPC");
 ok( request("/distrib/$distribution/$release")->is_success, 'Request should succeed' );
 ok( request("/distrib/$distribution/$release/$arch")->is_success, 'Request should succeed' );
Index: /server/trunk/web/t/controller_Search.t
===================================================================
--- /server/trunk/web/t/controller_Search.t	(revision 157)
+++ /server/trunk/web/t/controller_Search.t	(revision 158)
@@ -2,4 +2,6 @@
 use warnings;
 use Test::More;
+use FindBin;
+require "$FindBin::Bin/xml.pl";
 
 my $pkgid = '45db73adf5f9ceabc8f9ea1dabccffcc';
@@ -8,51 +10,40 @@
 BEGIN { use_ok 'Sophie::Controller::Search' }
 
-sub xmlrpcreq {
-    my (@xmlargs) = @_;
-    my $str = RPC::XML::request->new( @xmlargs )->as_string;
-
-    my $req = HTTP::Request->new( POST => 'http://localhost/rpc' );
-    $req->header( 'Content-Length'  => length($str) );
-    $req->header( 'Content-Type'    => 'text/xml' );
-    $req->content( $str );
-    return $req;
-}
-
 ok( 
-    request( xmlrpcreq('search.rpms.bydate', {}, time - 3600) ),
+    xmlrequest_ok('search.rpms.bydate', {}, time - 3600),
     "search.rpms.bydate"
 );
 
 ok( 
-    request( xmlrpcreq('search.rpm.bypkgid', {}, $pkgid) ),
+    xmlrequest_ok('search.rpm.bypkgid', {}, $pkgid),
     "search.rpm.bypkgid"
 );
 
 ok( 
-    request( xmlrpcreq('search.rpm.byname', {}, 'rpm', '>', '0') ),
+    xmlrequest_ok('search.rpm.byname', {}, 'rpm', '>', '0'),
     "search.rpm.byname"
 );
 
 ok( 
-    request( xmlrpcreq('search.rpm.bytag', {}, 'name', 'rpm') ),
+    xmlrequest_ok('search.rpm.bytag', {}, 'name', 'rpm'),
     "search.rpm.bytag"
 );
 
 ok( 
-    request( xmlrpcreq('search.rpm.bydep', {}, 'P', 'rpm', '>', '0') ),
+    xmlrequest_ok('search.rpm.bydep', {}, 'P', 'rpm', '>', '0'),
     "search.rpm.bydep"
 );
 
 ok( 
-    request( xmlrpcreq('search.rpm.byfile', {}, '/bin/rpm') ),
+    xmlrequest_ok('search.rpm.byfile', {}, '/bin/rpm'),
     "search.rpm.byfile"
 );
 
 ok( 
-    request( xmlrpcreq('search.rpm.fuzzy', {}, 'rpm-build') ),
+    xmlrequest_ok('search.rpm.fuzzy', {}, 'rpm-build'),
     "search.rpm.fuzzy"
 );
 ok( 
-    request( xmlrpcreq('search.rpm.quick', {}, 'rpm-build') ),
+    xmlrequest_ok('search.rpm.quick', {}, 'rpm-build'),
     "search.rpm.quick"
 );
@@ -60,5 +51,5 @@
 
 ok( 
-    request( xmlrpcreq('search.rpm.description', {}, qw'rpm build') ),
+    xmlrequest_ok('search.rpm.description', {}, qw'rpm build'),
     "search.rpm.description"
 );
Index: /server/trunk/web/t/xml.pl
===================================================================
--- /server/trunk/web/t/xml.pl	(revision 158)
+++ /server/trunk/web/t/xml.pl	(revision 158)
@@ -0,0 +1,39 @@
+use strict;
+use warnings;
+use RPC::XML::Parser;
+use HTTP::Request;
+
+sub xmlrpcreq {
+    my (@xmlargs) = @_;
+    my $str = RPC::XML::request->new( @xmlargs )->as_string;
+
+    my $req = HTTP::Request->new( POST => 'http://localhost/rpc' );
+    $req->header( 'Content-Length'  => length($str) );
+    $req->header( 'Content-Type'    => 'text/xml' );
+    $req->content( $str );
+    return $req;
+}
+
+sub xmlrequest {
+    my @args = @_;
+
+    my $res = request(xmlrpcreq(@args));
+    $res->is_success or return;
+
+    my $data = RPC::XML::Parser->new->parse( $res->content )->value->value;
+
+    return $data;
+}
+
+sub xmlrequest_ok {
+    my (@args) = @_;
+    my $data = xmlrequest(@args) or return;
+
+    if (ref $data eq 'HASH') {
+        exists($data->{faultString}) and return;
+    }
+
+    1;
+}
+
+1;
