[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cgiapp] Re: [dfv] Testing DFV (opportunity for a Test::DFV module?)


On 10/9/05, Ron Savage <suppressed> wrote:
> On Sat, 8 Oct 2005 22:12:38 -0500, Mark Stosberg wrote:
> > Simulating a file upload this way might be hard-- I don't think
> > there's an easy way to get of those into a CGI query object.
>
> It's easy using HTTP::Request::Common via LWP::UserAgent. Graft that in somehow.

For a quick example of how easy this really is, have a look at the
test suite for Data::FormValidator::Filters::Image.  There I don't
even bother with LWP::UserAgent, and just use HTTP::Request::Common
directly to create a valid POST request with a file upload, and then
write that to a forked process which cleanly simulates a CGI request.

http://search.cpan.org/src/CEESHEK/Data-FormValidator-Filters-Image-0.2/t/01_basic.t

Here is the meat of the code that does this:

---------------------

# Fake a web server CGI request by building a proper
# POST request, setting some ENV variables and
# forking a child process that gets the POST
# content from STDIN
my $req = &HTTP::Request::Common::POST(
    '/dummy_location',
    Content_Type => 'form-data',
    Content      => [
        name   => 'name1',
        test   => 'name2',
        image1 => ["t/image.jpg"],
        image7 => ["t/image.jpg", 'C:/Program
Files/dumb/filename/IE/passes.jpg'],
    ]
);
$ENV{REQUEST_METHOD} = 'POST';
$ENV{CONTENT_TYPE}   = 'multipart/form-data';
$ENV{CONTENT_LENGTH} = $req->content_length;
if ( open( CHILD, "|-" ) ) {    # cparent
    print CHILD $req->content;
    close CHILD;
    exit 0;
}

# at this point, we're in a new (child) process
# and CGI.pm can read the POST params from STDIN
# as in a real request (ie it doesn't know that it isn't dealing
# with a real webserver)
my $q = CGI->new;

--------------------------

To use this for testing CGI::Application modules, just replace the
CGI->new call with a CGI::Application instance script:

use My::CGIApp::Module;
$ENV{CGI_APP_RETURN_ONLY} = 1;
my $app = My::CGIApp::Module->new;
my $response = $app->run;

--------------------------

You can then use the standard Test methods to analyse $response for
valid headers and content.  You could send the content to HTML::Form
and make sure that the correct form elements are present, etc...


I like this method, because it doesn't require a webserver to be
running, which can sometimes be a pain to deal with.  It effectively
takes the place of a webserver by (mostly) following the CGI spec by
setting some ENV vars, forking a process to execute the CGI script,
and printing the HTTP request to the forked child (maybe there is
already a module that does all this - besides HTTP::Server::Simple
which is still an HTTP server that listens on a port).


Cheers,

Cees

---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/suppressed/
              http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed


Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.