File Coverage

blib/lib/ASP4/UserAgent.pm
Criterion Covered Total %
statement 117 121 96.6
branch 11 14 78.5
condition 4 7 57.1
subroutine 23 24 95.8
pod 6 10 60.0
total 161 176 91.4


line stmt bran cond sub pod time code
1              
2             package ASP4::UserAgent;
3              
4 5     5   681 use strict;
  5         6  
  5         134  
5 5     5   17 use warnings 'all';
  5         4  
  5         179  
6 5     5   16 use Carp 'confess';
  5         8  
  5         232  
7 5     5   19 use Cwd 'cwd';
  5         5  
  5         162  
8 5     5   2289 use HTTP::Request::Common;
  5         59696  
  5         298  
9 5     5   2082 use HTTP::Response;
  5         22486  
  5         131  
10              
11 5     5   552 use ASP4::HTTPContext;
  5         7  
  5         94  
12 5     5   18 use ASP4::ConfigLoader;
  5         5  
  5         83  
13 5     5   1901 use ASP4::SimpleCGI;
  5         15  
  5         169  
14 5     5   26 use ASP4::Mock::RequestRec;
  5         11  
  5         4597  
15              
16              
17             sub new
18             {
19 5     5 0 21979 return bless {
20             cwd => cwd(),
21             http_cookie => '',
22             cookies => { },
23             referer => '',
24             }, shift;
25             }# end new()
26              
27 44143     44143 0 73651 sub context { ASP4::HTTPContext->current }
28 11346     11346 0 27631 sub config { ASP4::ConfigLoader->load }
29              
30              
31             sub get
32             {
33 5110     5110 1 12669 my ($s, $uri) = @_;
34            
35 5110         41440 chdir( $s->{cwd} );
36 5110         13385 undef($ASP4::HTTPContext::_instance);
37 5110         10321 my $req = GET $uri;
38 5110         327909 %ENV = (
39             DOCUMENT_ROOT => $s->config->web->www_root,
40             REQUEST_METHOD => 'GET',
41             CONTENT_TYPE => 'application/x-www-form-urlencoded',
42             HTTP_COOKIE => $s->http_cookie,
43             );
44 5110         11945 my $cgi = $s->_setup_cgi( $req );
45 5110         8013 my ($uri_no_args, $querystring) = split /\?/, $uri;
46 5110         13099 my $r = ASP4::Mock::RequestRec->new( uri => $uri_no_args, args => $querystring );
47 5110         8777 $s->context->setup_request( $r, $cgi );
48 5110         9925 return $s->_setup_response( $s->context->execute() );
49             }# end get()
50              
51              
52             sub post
53             {
54 3     3 1 3253 my ($s, $uri, $args) = @_;
55            
56 3         61 chdir( $s->{cwd} );
57 3         19 undef($ASP4::HTTPContext::_instance);
58 3   100     22 $args ||= [ ];
59 3         20 my $req = POST $uri, $args;
60 3         5933 %ENV = (
61             DOCUMENT_ROOT => $s->config->web->www_root,
62             REQUEST_METHOD => 'POST',
63             CONTENT_TYPE => 'application/x-www-form-urlencoded',
64             HTTP_COOKIE => $s->http_cookie,
65             );
66 3         13 my $cgi = $s->_setup_cgi( $req );
67 3         11 my ($uri_no_args, $querystring) = split /\?/, $uri;
68 3         28 my $r = ASP4::Mock::RequestRec->new( uri => $uri_no_args, args => $querystring );
69 3         10 $s->context->setup_request( $r, $cgi );
70 3         14 return $s->_setup_response( $s->context->execute() );
71             }# end post()
72              
73              
74             sub upload
75             {
76 1     1 1 3484 my ($s, $uri, $args) = @_;
77            
78 1         18 chdir( $s->{cwd} );
79 1         9 undef($ASP4::HTTPContext::_instance);
80 1   50     7 $args ||= [ ];
81 1         9 my $req = POST $uri, Content_Type => 'form-data', Content => $args;
82 1         1000 %ENV = (
83             DOCUMENT_ROOT => $s->config->web->www_root,
84             REQUEST_METHOD => 'POST',
85             CONTENT_TYPE => 'multipart/form-data',
86             HTTP_COOKIE => $s->http_cookie,
87             );
88 1         7 my $cgi = $s->_setup_cgi( $req );
89 1         3 my ($uri_no_args, $querystring) = split /\?/, $uri;
90 1         10 my $r = ASP4::Mock::RequestRec->new( uri => $uri_no_args, args => $querystring );
91 1         4 $s->context->setup_request( $r, $cgi );
92 1         4 return $s->_setup_response( $s->context->execute() );
93             }# end upload()
94              
95              
96             sub submit_form
97             {
98 2     2 1 19638 my ($s, $form) = @_;
99            
100 2         48 chdir( $s->{cwd} );
101 2         27 undef($ASP4::HTTPContext::_instance);
102            
103 2         7 my $temp_referrer = $ENV{HTTP_REFERER};
104 2         13 my $req = $form->click;
105 2 50       20875 %ENV = (
106             DOCUMENT_ROOT => $s->config->web->www_root,
107             REQUEST_METHOD => uc( $req->method ),
108             CONTENT_TYPE => $form->enctype ? $form->enctype : 'application/x-www-form-urlencoded',
109             HTTP_COOKIE => $s->http_cookie,
110             );
111 2         14 my $cgi = $s->_setup_cgi( $req );
112 2         13 my ($uri_no_args, $querystring) = split /\?/, $req->uri;
113 2         59 my $r = ASP4::Mock::RequestRec->new( uri => $uri_no_args, args => $querystring );
114 2         10 $s->context->setup_request( $r, $cgi );
115 2         12 return $s->_setup_response( $s->context->execute() );
116             }# end submit_form()
117              
118              
119             sub add_cookie
120             {
121 3120     3120 1 3230 my ($s, $name, $value) = @_;
122            
123 3120         5794 $s->{cookies}->{$name} = $value;
124             }# end add_cookie()
125              
126              
127             sub remove_cookie
128             {
129 0     0 1 0 my ($s, $name) = @_;
130            
131 0         0 delete( $s->{cookies}->{$name} );
132             }# end remove_cookie()
133              
134              
135             sub http_cookie
136             {
137 10232     10232 0 8798 my $s = shift;
138            
139             join '; ',
140 10222         23102 map { ASP4::SimpleCGI->escape($_) . '=' . ASP4::SimpleCGI->escape($s->{cookies}->{$_}) }
141 10232         10635 keys %{$s->{cookies}};
  10232         19820  
142             }# end http_cookie()
143              
144              
145             sub _setup_response
146             {
147 5116     5116   4752 my ($s, $response_code) = @_;
148            
149 5116 50       9575 $response_code = 200 if $response_code eq '0';
150 5116         13772 my $response = HTTP::Response->new( $response_code );
151 5116         134290 $response->content( $s->context->r->buffer );
152            
153 5116         57136 $response->header( 'Content-Type' => $s->context->response->{ContentType} );
154            
155 5116         161786 foreach my $header ( $s->context->response->Headers, $s->context->r->err_headers_out )
156             {
157 10232         24947 while( my ($k,$v) = each(%$header) )
158             {
159 10237         15307 $response->header( $k => $v );
160 10237 100       285693 if( lc($k) eq 'set-cookie' )
161             {
162 5         29 my ($data) = split /;/, $v;
163 5         21 my ($name,$val) = map { ASP4::SimpleCGI->unescape( $_ ) } split /\=/, $data;
  10         90  
164 5         41 $s->add_cookie( $name => $val );
165             }# end if()
166             }# end while()
167             }# end foreach()
168            
169 5116 100 33     11795 if( $s->context->session && $s->context->session->{SessionID} )
170             {
171             $s->add_cookie(
172             $s->config->data_connections->session->cookie_name => $s->context->session->{SessionID}
173 3115         4027 );
174             }# end if()
175            
176 5116         30797 return $response;
177             }# end _setup_response()
178              
179              
180             sub _setup_cgi
181             {
182 5116     5116   4696 my ($s, $req) = @_;
183              
184 5116 50       7838 if( $s->{referer} )
185             {
186 0         0 ($s->{referer}) = $req->uri =~ m/.*?(\/[^\?]+)/;
187 0         0 $req->referer( $s->{referer} );
188             }
189             else
190             {
191 5116         10533 $req->referer('');
192             }# end if()
193            
194 5     5   24 no warnings 'uninitialized';
  5         6  
  5         1114  
195 5116         143214 (my ($uri_no_args), $ENV{QUERY_STRING} ) = split /\?/, $req->uri;
196 5116         62096 $ENV{SERVER_NAME} = $ENV{HTTP_HOST} = 'localhost';
197            
198 5116 100       8997 unless( $req->uri =~ m@^/handlers@ )
199             {
200 3115         21057 $ENV{SCRIPT_FILENAME} = $s->config->web->www_root . $uri_no_args;
201 3115         7883 $ENV{SCRIPT_NAME} = $uri_no_args;
202             }# end unless()
203            
204             # User-Agent:
205 5116         22490 $req->header( 'User-Agent' => 'test-useragent v1.0' );
206 5116         155374 $ENV{HTTP_USER_AGENT} = 'test-useragent v2.0';
207            
208             # Cookies:
209 5116         9071 $req->header( 'Cookie' => $ENV{HTTP_COOKIE} = $s->http_cookie );
210            
211 5116 100       176635 if( $ENV{REQUEST_METHOD} =~ m/^post$/i )
212             {
213             # Set up the basic params:
214             return ASP4::SimpleCGI->new(
215             querystring => $ENV{QUERY_STRING},
216             body => $req->content,
217             content_type => $req->headers->{'content-type'},
218 6         37 content_length => $req->headers->{'content-length'},
219             );
220             }
221             else
222             {
223             # Simple 'GET' request:
224 5110         12752 return ASP4::SimpleCGI->new( querystring => $ENV{QUERY_STRING} );
225             }# end if()
226             }# end _setup_cgi()
227              
228              
229             sub DESTROY
230             {
231 2     2   1066 my $s = shift;
232 2         118 undef(%$s);
233             }# end DESTROY()
234              
235             1;# return true:
236              
237             =pod
238              
239             =head1 NAME
240              
241             ASP4::UserAgent - Execute ASP4 requests without a web server.
242              
243             =head1 SYNOPSIS
244              
245             B 99.99% of the time you will access this via L.
246              
247             my HTTP::Response $res = $api->ua->get('/index.asp?foo=bar');
248            
249             my $res = $api->ua->post('/handlers/user.login', [
250             username => 'willy',
251             password => 'wonka',
252             ]);
253            
254             my $res = $api->ua->upload('/handlers/file.upload', [
255             foo => 'bar',
256             baz => 'bux',
257             file => ['/home/john/avatar.jpg']
258             ]);
259            
260             # Some form testing:
261             my ($form) = HTML::Form->parse( $res->content, '/' );
262             $form->find_input('username')->value('bob');
263             my $res = $api->ua->submit_form( $form );
264            
265             # Add/remove a cookie:
266             $api->ua->add_cookie( "the-boss" => "me" );
267             $api->remove_cookie( "the-boss" );
268              
269             =head1 DESCRIPTION
270              
271             Enables unit-testing ASP4 applications by providing the ability to execuite web
272             pages from your code, without a webserver.
273              
274             =head1 PUBLIC METHODS
275              
276             =head2 get( $url )
277              
278             Calls C<$url> and returns the L result.
279              
280             =head2 post( $url, $args )
281              
282             Calls C<$url> with C<$args> and returns the L result.
283              
284             =head2 upload( $url, $args )
285              
286             Calls C<$url> with C<$args> and returns the L result.
287              
288             =head2 submit_form( HTML::Form $form )
289              
290             Submits the C<$form> and returns the L result.
291              
292             =head2 add_cookie( $name, $value )
293              
294             Adds the cookie to all subsequent requests.
295              
296             =head2 remove_cookie( $name )
297              
298             Removes the cookie (if it exists).
299              
300             =head1 SEE ALSO
301              
302             L and L
303              
304             =cut
305