File Coverage

blib/lib/Apache2/ASP/Test/UserAgent.pm
Criterion Covered Total %
statement 63 194 32.4
branch 0 24 0.0
condition 0 10 0.0
subroutine 21 32 65.6
pod 5 7 71.4
total 89 267 33.3


line stmt bran cond sub pod time code
1              
2             package Apache2::ASP::Test::UserAgent;
3              
4 23     23   3752 use strict;
  23         34  
  23         729  
5 23     23   103 use warnings 'all';
  23         158  
  23         1040  
6 23     23   11925 use HTTP::Request::Common;
  23         524340  
  23         1806  
7 23     23   11907 use HTTP::Response;
  23         126803  
  23         815  
8 23     23   12717 use HTTP::Request::AsCGI;
  23         323514  
  23         199  
9 23     23   12758 use HTTP::Body;
  23         417848  
  23         731  
10 23     23   10331 use Apache2::ASP::HTTPContext;
  23         159  
  23         817  
11 23     23   10213 use Apache2::ASP::SimpleCGI;
  23         56  
  23         652  
12 23     23   122 use Apache2::ASP::Mock::RequestRec;
  23         31  
  23         488  
13 23     23   95 use Carp 'confess';
  23         35  
  23         1239  
14 23     23   94 use IO::File;
  23         29  
  23         3283  
15 23     23   105 use Scalar::Util 'weaken';
  23         40  
  23         2914  
16              
17             our $ContextClass = 'Apache2::ASP::HTTPContext';
18              
19              
20             #==============================================================================
21             sub new
22             {
23 0     0 0   my ($class, %args) = @_;
24            
25 0           return bless {
26             %args,
27             }, $class;
28             }# end new()
29              
30              
31             #==============================================================================
32 0 0   0 1   sub context { Apache2::ASP::HTTPContext->current || $Apache2::ASP::HTTPContext::ClassName->new }
33              
34              
35             #==============================================================================
36             sub post
37             {
38 0     0 1   my ($s, $uri, $args) = @_;
39            
40 23     23   105 no strict 'refs';
  23         28  
  23         1425  
41 0           undef(${"$ContextClass\::instance"});
  0            
42 0   0       $args ||= [ ];
43 0           my $req = POST $uri, $args;
44             {
45 23     23   94 no warnings 'uninitialized';
  23         31  
  23         3717  
  0            
46 0           %ENV = ( DOCUMENT_ROOT => $ENV{DOCUMENT_ROOT} );
47             }
48 0           $ENV{REQUEST_METHOD} = 'POST';
49 0           my $cgi = $s->_setup_cgi( $req );
50 0           $ENV{CONTENT_TYPE} = 'application/x-www-form-urlencoded';
51            
52 0           my $r = Apache2::ASP::Mock::RequestRec->new();
53 0           $r->uri( $uri );
54 0           $r->args( $cgi->{querystring} );
55 0           $r->{headers_in}->{Cookie} = $ENV{HTTP_COOKIE};
56            
57 0           $s->context->setup_request( $r, $cgi );
58 0           return $s->_setup_response( $s->context->execute() );
59             }# end post()
60              
61              
62             #==============================================================================
63             sub upload
64             {
65 0     0 1   my ($s, $uri, $args) = @_;
66            
67 23     23   109 no strict 'refs';
  23         47  
  23         1166  
68 0           undef(${"$ContextClass\::instance"});
  0            
69             {
70 23     23   90 no warnings 'uninitialized';
  23         28  
  23         8244  
  0            
71 0           %ENV = ( DOCUMENT_ROOT => $ENV{DOCUMENT_ROOT} );
72             }
73 0           my $req = POST $uri, Content_Type => 'form-data', Content => $args;
74 0           $ENV{REQUEST_METHOD} = 'POST';
75 0           $ENV{CONTENT_TYPE} = $req->headers->{'content-type'};
76 0           my $cgi = $s->_setup_cgi( $req );
77 0           $ENV{CONTENT_TYPE} = 'multipart/form-data';
78            
79 0           my $r = Apache2::ASP::Mock::RequestRec->new();
80 0           $r->uri( $uri );
81 0           $r->args( $cgi->{querystring} );
82 0           $r->{headers_in}->{Cookie} = $ENV{HTTP_COOKIE};
83            
84 0           $s->context->setup_request( $r, $cgi );
85            
86 0           require Apache2::ASP::UploadHook;
87 0           my $handler_resolver = $s->context->config->web->handler_resolver;
88 0           $s->context->config->load_class( $handler_resolver );
89 0           my $hook_obj = Apache2::ASP::UploadHook->new(
90             handler_class => $handler_resolver->new()->resolve_request_handler( $uri ),
91             );
92 0     0     my $hook_ref = sub { $hook_obj->hook( @_ ) };
  0            
93            
94             # Now call the upload hook...
95 0           require Apache2::ASP::Test::UploadObject;
96 0           foreach my $uploaded_file ( keys( %{ $cgi->{uploads} } ) )
  0            
97             {
98 0           my $tmpfile = $cgi->upload_info($uploaded_file, 'tempname' );
99 0           my $filename = $cgi->upload_info( $uploaded_file, 'filename' );
100 0           my $ifh = IO::File->new;
101 0 0         $ifh->open($tmpfile, '<')
102             or die "Cannot open temp file '$tmpfile' for reading: $!";
103 0           binmode($ifh);
104 0           while( my $line = <$ifh> )
105             {
106 0           $hook_ref->(
107             Apache2::ASP::Test::UploadObject->new(
108             filename => $filename,
109             upload_filename => $filename
110             ),
111             $line
112             );
113             }# end while()
114 0           close($ifh);
115            
116             # One more *without* any data (this will signify and EOF condition):
117 0           $hook_ref->(
118             Apache2::ASP::Test::UploadObject->new(
119             filename => $filename,
120             upload_filename => $filename
121             ),
122             undef
123             );
124             }# end foreach()
125            
126             # NOW we can execute...
127 0           return $s->_setup_response( $s->context->execute() );
128             }# end upload()
129              
130              
131             #==============================================================================
132             sub submit_form
133             {
134 0     0 1   my ($s, $form) = @_;
135            
136 23     23   104 no strict 'refs';
  23         31  
  23         1421  
137 0           undef(${"$ContextClass\::instance"});
  0            
138              
139 0           my $temp_referrer = $ENV{HTTP_REFERER};
140 0           my $req = $form->click;
141            
142             {
143 23     23   90 no warnings 'uninitialized';
  23         54  
  23         3836  
  0            
144 0           %ENV = ( DOCUMENT_ROOT => $ENV{DOCUMENT_ROOT} );
145             }
146 0           $ENV{REQUEST_METHOD} = uc( $req->method );
147 0           my $cgi = $s->_setup_cgi( $req );
148 0 0         $ENV{CONTENT_TYPE} = $form->enctype ? $form->enctype : 'application/x-www-form-urlencoded';
149 0           $ENV{HTTP_REFERER} = $temp_referrer;
150            
151 0           my $r = Apache2::ASP::Mock::RequestRec->new();
152 0           $r->uri( $req->uri );
153 0           $r->args( $cgi->{querystring} );
154 0           $r->{headers_in}->{Cookie} = $ENV{HTTP_COOKIE};
155            
156 0           $s->context->setup_request( $r, $cgi );
157            
158 0           return $s->_setup_response( $s->context->execute() );
159             }# end submit_form()
160              
161              
162             #==============================================================================
163             sub get
164             {
165 0     0 1   my ($s, $uri) = @_;
166            
167 23     23   104 no strict 'refs';
  23         30  
  23         1242  
168 0           undef(${"$ContextClass\::instance"});
  0            
169            
170 0           my $req = GET $uri;
171             {
172 23     23   96 no warnings 'uninitialized';
  23         33  
  23         11250  
  0            
173 0           %ENV = ( DOCUMENT_ROOT => $ENV{DOCUMENT_ROOT} );
174             }
175 0           $ENV{REQUEST_METHOD} = 'GET';
176 0           my $cgi = $s->_setup_cgi( $req );
177 0           $ENV{CONTENT_TYPE} = 'application/x-www-form-urlencoded';
178            
179 0           my $r = Apache2::ASP::Mock::RequestRec->new();
180 0           $r->uri( $uri );
181 0           $r->args( $cgi->{querystring} );
182 0           $r->{headers_in}->{Cookie} = $ENV{HTTP_COOKIE};
183            
184 0           $s->context->setup_request( $r, $cgi );
185            
186 0           return $s->_setup_response( $s->context->execute() );
187             }# end get()
188            
189            
190             #==============================================================================
191             sub add_cookie
192             {
193 0     0 0   my ($s, $name, $value) = @_;
194            
195 0           $s->{cookies}->{$name} = $value;
196             }# end add_cookie()
197            
198            
199             #==============================================================================
200             sub _setup_response
201             {
202 0     0     my ($s, $response_code) = @_;
203            
204 0 0         $response_code = 200 if $response_code == 0;
205 0           my $response = HTTP::Response->new( $response_code );
206 0           $response->content( $s->context->get_prop('r')->buffer );
207            
208 0           $response->header( 'Content-Type' => $s->context->response->{ContentType} );
209            
210 0           foreach my $header ( $s->context->response->Headers )
211             {
212 0           while( my ($k,$v) = each(%$header) )
213             {
214 0           $response->header( $k => $v );
215 0 0         if( lc($k) eq 'set-cookie' )
216             {
217 0           my ($data) = split /;/, $v;
218 0           my ($name,$val) = map { Apache2::ASP::SimpleCGI->unescape( $_ ) } split /\=/, $data;
  0            
219 0           $s->add_cookie( $name => $val );
220             }# end if()
221             }# end while()
222             }# end foreach()
223            
224 0 0 0       if( $s->context->session && $s->context->session->{SessionID} )
225             {
226             $s->add_cookie(
227             $s->context->config->data_connections->session->cookie_name => $s->context->session->{SessionID}
228 0           );
229             }# end if()
230            
231 0           $s->context->r->pool->call_cleanup_handlers();
232 0           weaken($s->context->{cgi});
233            
234 0           return $response;
235             }# end _setup_response()
236              
237            
238             #==============================================================================
239             sub _setup_cgi
240             {
241 0     0     my ($s, $req) = @_;
242            
243 0           my $docroot = $ENV{DOCUMENT_ROOT};
244             $s->{c}->DESTROY
245 0 0         if $s->{c};
246 0   0       $req->referer( $s->{referer} || '' );
247 0           ($s->{referer}) = $req->uri =~ m/.*?(\/[^\?]+)/;
248              
249 23     23   247 no warnings 'redefine';
  23         36  
  23         7766  
250 0     0     *HTTP::Request::AsCGI::stdout = sub { 0 };
  0            
251            
252 0           $s->{c} = HTTP::Request::AsCGI->new($req)->setup;
253 0           $ENV{SERVER_NAME} = $ENV{HTTP_HOST} = 'localhost';
254            
255 0 0         unless( $req->uri =~ m@^/handlers@ )
256             {
257 0           my ($uri_no_args) = split /\?/, $req->uri;
258 0           $ENV{SCRIPT_FILENAME} = $s->context->config->web->www_root . $uri_no_args;
259 0           $ENV{SCRIPT_NAME} = $uri_no_args;
260             }# end unless()
261            
262             # User-Agent:
263 0           $req->header( 'User-Agent' => 'test-useragent v1.0' );
264 0           $ENV{HTTP_USER_AGENT} = 'test-useragent v1.0';
265            
266             # Cookies:
267 0           my @cookies = ();
268 0           while( my ($name,$val) = each(%{ $s->{cookies} } ) )
  0            
269             {
270 0 0 0       next unless $name && $val;
271 0           push @cookies, "$name=" . Apache2::ASP::SimpleCGI->escape($val);
272             }# end while()
273            
274 0 0         $req->header( 'Cookie' => join ';', @cookies ) if @cookies;
275 0           $ENV{HTTP_COOKIE} = join ';', @cookies;
276 0 0         $ENV{DOCUMENT_ROOT} = $docroot
277             if $docroot;
278            
279 0 0         if( $ENV{REQUEST_METHOD} =~ m/^post$/i )
280             {
281             # Set up the basic params:
282             return Apache2::ASP::SimpleCGI->new(
283             querystring => $ENV{QUERY_STRING},
284             body => $req->content,
285             content_type => $req->headers->{'content-type'},
286 0           content_length => $req->headers->{'content-length'},
287             );
288             }
289             else
290             {
291             # Simple 'GET' request:
292 0           return Apache2::ASP::SimpleCGI->new( querystring => $ENV{QUERY_STRING} );
293             }# end if()
294             }# end _setup_cgi()
295              
296             1;# return true:
297              
298             =pod
299              
300             =head1 NAME
301              
302             Apache2::ASP::Test::UserAgent - Execute ASP scripts without a webserver.
303              
304             =head1 SYNOPSIS
305              
306             Generally you will be accessing this class from wither L
307             or L.
308              
309             my $asp = Apache2::ASP::API->new()
310             -- or --
311             my $asp = Apache2::ASP::Test::Base->new();
312            
313             # Get:
314             my $res = $asp->ua->get("/index.asp");
315             if( $res->is_succes ) {
316             ...
317             }
318            
319             # Post:
320             my $res = $asp->ua->post("/handlers/contact.form", [
321             name => "Fred",
322             email => 'fred@flintstone.org',
323             message => 'This is a test email message.'
324             ]);
325            
326             # Do the same thing, but with HTML::Form:
327             use HTML::Form;
328             my $form = HTML::Form->parse( $asp->ua->get("/contact.asp")->content, '/' );
329             $form->find_input('name')->value('Fred');
330             $form->find_input('email')->value('fred@flintstone.org');
331             $form->find_input('message')->value('This is a test email message');
332             my $res = $asp->ua->submit_form( $form );
333            
334             # Upload:
335             my $res = $asp->ua->upload("/handlers/MM?mode=create&uploadID=12334534", [
336             filename => ['/path/to/file.txt'],
337             ]);
338              
339             =head1 PUBLIC PROPERTIES
340              
341             =head2 context
342              
343             Returns the current L object.
344              
345             =head1 PUBLIC METHODS
346              
347             =head2 get( $url )
348              
349             Makes a "GET" request to C<$url>
350              
351             =head2 post( $url [,\@args] )
352              
353             Makes a "POST" reqest to C<$url>, using C<@args> as the body.
354              
355             =head2 upload( $url, \@args )
356              
357             Makes a "POST" request with a C type, using C<@args> as the body.
358              
359             =head2 submit_form( HTML::Form $form )
360              
361             Submits the form.
362              
363             B - this will not work for "upload" forms (yet).
364            
365             =head1 BUGS
366            
367             It's possible that some bugs have found their way into this release.
368            
369             Use RT L to submit bug reports.
370            
371             =head1 HOMEPAGE
372            
373             Please visit the Apache2::ASP homepage at L to see examples
374             of Apache2::ASP in action.
375            
376             =head1 AUTHOR
377            
378             John Drago L
379            
380             =head1 COPYRIGHT AND LICENSE
381            
382             Copyright 2007 John Drago, All rights reserved.
383            
384             This software is free software. It may be used and distributed under the
385             same terms as Perl itself.
386            
387             =cut
388