| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Test::HTTP; |
|
2
|
4
|
|
|
4
|
|
65693
|
use warnings; |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
118
|
|
|
3
|
4
|
|
|
4
|
|
22
|
use strict; |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
221
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = 0.18; |
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 NAME |
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
Test::HTTP - Test HTTP interactions. |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use Test::HTTP tests => 9; |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
{ |
|
16
|
|
|
|
|
|
|
my $uri = "$BASE/data/page/Foo_Bar_Baz"; |
|
17
|
|
|
|
|
|
|
my $type = 'text/x.waki-wiki'; |
|
18
|
|
|
|
|
|
|
my $test = Test::HTTP->new('HTTP page creation and deletion'); |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
$test->get($uri, [Accept => $type]); |
|
21
|
|
|
|
|
|
|
$test->status_code_is(404, "Page not yet there."); |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
$test->put($uri, ['Content-type' => $type], 'xyzzy'); |
|
24
|
|
|
|
|
|
|
$test->status_code_is(201, "PUT returns 201."); # Created |
|
25
|
|
|
|
|
|
|
$test->header_is( |
|
26
|
|
|
|
|
|
|
'Content-type' => $type, |
|
27
|
|
|
|
|
|
|
"Content-type matches on PUT."); |
|
28
|
|
|
|
|
|
|
$test->header_like( |
|
29
|
|
|
|
|
|
|
Location => qr{^$BASE/data/page/}, |
|
30
|
|
|
|
|
|
|
"Created page location makes sense."); |
|
31
|
|
|
|
|
|
|
$test->body_is('xyzzy'); |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
$test->get($uri, [Accept => $type]); |
|
34
|
|
|
|
|
|
|
$test->status_code_is(200, "Page is now there."); |
|
35
|
|
|
|
|
|
|
$test->header_is( |
|
36
|
|
|
|
|
|
|
'Content-type' => $type, |
|
37
|
|
|
|
|
|
|
"Content-type matches on GET."); |
|
38
|
|
|
|
|
|
|
$test->body_is('xyzzy'); |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
$test->delete($uri); |
|
41
|
|
|
|
|
|
|
$test->status_code_is(204, "DELETE returns 204."); # No content |
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
L is designed to make it easier to write tests which are mainly |
|
47
|
|
|
|
|
|
|
about HTTP-level things, such as REST-type services. |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
Each C object can contain state about a current request and its |
|
50
|
|
|
|
|
|
|
response. This allows convenient shorthands for sending requests, checking |
|
51
|
|
|
|
|
|
|
status codes, headers, and message bodies. |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
=cut |
|
54
|
|
|
|
|
|
|
|
|
55
|
4
|
|
|
4
|
|
20
|
use base 'Exporter'; |
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
454
|
|
|
56
|
4
|
|
|
4
|
|
20
|
use Carp 'croak'; |
|
|
4
|
|
|
|
|
5
|
|
|
|
4
|
|
|
|
|
279
|
|
|
57
|
4
|
|
|
4
|
|
3261
|
use Class::Field 'field'; |
|
|
4
|
|
|
|
|
104186
|
|
|
|
4
|
|
|
|
|
316
|
|
|
58
|
4
|
|
|
4
|
|
42
|
use Encode qw(encode_utf8 is_utf8); |
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
319
|
|
|
59
|
4
|
|
|
4
|
|
4737
|
use Filter::Util::Call; |
|
|
4
|
|
|
|
|
4759
|
|
|
|
4
|
|
|
|
|
301
|
|
|
60
|
4
|
|
|
4
|
|
3580
|
use HTTP::Request; |
|
|
4
|
|
|
|
|
196059
|
|
|
|
4
|
|
|
|
|
165
|
|
|
61
|
4
|
|
|
4
|
|
3953
|
use Test::Builder; |
|
|
4
|
|
|
|
|
42198
|
|
|
|
4
|
|
|
|
|
9037
|
|
|
62
|
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
our $Builder = Test::Builder->new; |
|
64
|
|
|
|
|
|
|
our $BasicPassword; |
|
65
|
|
|
|
|
|
|
our $BasicUsername; |
|
66
|
|
|
|
|
|
|
our $UaClass = 'LWP::UserAgent'; |
|
67
|
|
|
|
|
|
|
our $TODO = undef; |
|
68
|
|
|
|
|
|
|
our @EXPORT = qw($TODO); |
|
69
|
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub _partition(&@); |
|
71
|
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub import { |
|
73
|
4
|
|
|
4
|
|
41
|
my $class = shift; |
|
74
|
|
|
|
|
|
|
|
|
75
|
4
|
|
|
|
|
36
|
$Builder->exported_to(scalar caller); |
|
76
|
|
|
|
|
|
|
|
|
77
|
4
|
|
|
8
|
|
56
|
my ( $syntax, $nargs ) = _partition { $_ eq '-syntax' } @_; |
|
|
8
|
|
|
|
|
43
|
|
|
78
|
4
|
|
|
|
|
34
|
$Builder->plan(@$nargs); |
|
79
|
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# WARNING: This only exports the stuff in @EXPORT. |
|
81
|
4
|
|
|
|
|
1389
|
$class->export_to_level(1, $class); |
|
82
|
|
|
|
|
|
|
|
|
83
|
4
|
100
|
|
|
|
2758
|
if (@$syntax) { |
|
84
|
2
|
|
|
|
|
7
|
@_ = (); |
|
85
|
2
|
|
|
|
|
1493
|
require Test::HTTP::Syntax; |
|
86
|
2
|
|
|
|
|
20
|
goto &Test::HTTP::Syntax::import; |
|
87
|
|
|
|
|
|
|
} |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=head2 Test::HTTP->new($name); |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
C<$name> is a name for the test, used to help write test descriptions when you |
|
95
|
|
|
|
|
|
|
don't specify them. |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=cut |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub new { |
|
100
|
6
|
|
|
6
|
1
|
3824
|
my $class = shift; |
|
101
|
|
|
|
|
|
|
|
|
102
|
6
|
|
|
|
|
25
|
my $new_object = bless {}, $class; |
|
103
|
6
|
|
|
|
|
40
|
$new_object->_initiliaze(@_); |
|
104
|
6
|
|
|
|
|
117
|
return $new_object; |
|
105
|
|
|
|
|
|
|
} |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
sub _initiliaze { |
|
108
|
6
|
|
|
6
|
|
18
|
my ( $self, $name ) = @_; |
|
109
|
|
|
|
|
|
|
|
|
110
|
6
|
|
|
|
|
583
|
$self->name($name); |
|
111
|
|
|
|
|
|
|
} |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# Given a predicate and a list, return two listrefs. The elements in the |
|
114
|
|
|
|
|
|
|
# first listref satisfy the predicate, and those in the second do not. The |
|
115
|
|
|
|
|
|
|
# predicate acts on a localized value of $_ rather than any arguments to it. |
|
116
|
|
|
|
|
|
|
sub _partition(&@) { |
|
117
|
4
|
|
|
4
|
|
14
|
my ( $pred, @l ) = @_; |
|
118
|
4
|
|
|
|
|
12
|
my ( $tl, $fl ) = ( [], [] ); |
|
119
|
|
|
|
|
|
|
|
|
120
|
4
|
100
|
|
|
|
18
|
push @{ &$pred ? $tl : $fl }, $_ for @l; |
|
|
8
|
|
|
|
|
16
|
|
|
121
|
|
|
|
|
|
|
|
|
122
|
4
|
|
|
|
|
13
|
return ( $tl, $fl ); |
|
123
|
|
|
|
|
|
|
} |
|
124
|
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=head1 OBJECT FIELDS |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
You can get/set any of these by saying C<< $test->foo >> or |
|
128
|
|
|
|
|
|
|
C<< $test->foo(5) >>, respectively. |
|
129
|
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=head2 $test->name |
|
131
|
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
The name for the test. |
|
133
|
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
=head2 $test->request |
|
135
|
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
The current L being constructed or most recently sent. |
|
137
|
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 $test->response |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
The most recently received L. |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=head2 $test->ua |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
The User Agent object (usually an L). |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=head2 $test->username |
|
147
|
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head2 $test->password |
|
149
|
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
A username and password to be used for HTTP basic auth. Default to the values |
|
151
|
|
|
|
|
|
|
of C<$Test::HTTP::BasicUsername> and C<$Test::HTTP::BasicPassword>, |
|
152
|
|
|
|
|
|
|
respectively. If both are undef, then authentication is not attempted. |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=cut |
|
155
|
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
field 'name'; |
|
157
|
|
|
|
|
|
|
field 'request'; |
|
158
|
|
|
|
|
|
|
field 'response'; |
|
159
|
|
|
|
|
|
|
field 'ua', -init => '$self->_ua_class->new'; |
|
160
|
|
|
|
|
|
|
field 'username', -init => '$Test::HTTP::BasicUsername'; |
|
161
|
|
|
|
|
|
|
field 'password', -init => '$Test::HTTP::BasicPassword'; |
|
162
|
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
=head1 REQUEST METHODS |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=head2 head, get, put, post, and delete |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
Any of these methods may be used to do perform the expected HTTP request. |
|
168
|
|
|
|
|
|
|
They are all equivalent to |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
$obj->run_request(METHOD => ARGS); |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=cut |
|
173
|
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub head { |
|
175
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
176
|
0
|
|
|
|
|
0
|
$self->run_request(HEAD => @_); |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub get { |
|
180
|
3
|
|
|
3
|
1
|
20
|
my $self = shift; |
|
181
|
3
|
|
|
|
|
12
|
$self->run_request(GET => @_); |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub put { |
|
185
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
186
|
0
|
|
|
|
|
0
|
$self->run_request(PUT => @_); |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub post { |
|
190
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
191
|
0
|
|
|
|
|
0
|
$self->run_request(POST => @_); |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub delete { |
|
195
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
196
|
0
|
|
|
|
|
0
|
$self->run_request(DELETE => @_); |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=head2 $test->run_request([METHOD => $uri [, $headers [, $content]]]); |
|
200
|
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
If there are any arguments, they are all passed to the L |
|
202
|
|
|
|
|
|
|
constructor to create a new C<< $test->request >>. |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
C<< $test->request >> is then executed, and C<< $test->response >> will hold |
|
205
|
|
|
|
|
|
|
the resulting L. |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=cut |
|
208
|
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
sub run_request { |
|
210
|
6
|
|
|
6
|
1
|
49
|
my ( $self, @request_args ) = @_; |
|
211
|
6
|
100
|
|
|
|
33
|
$self->new_request(@request_args) if @request_args; |
|
212
|
6
|
50
|
|
|
|
168
|
if ($self->request->method ne 'GET') { |
|
213
|
0
|
0
|
|
|
|
0
|
if (is_utf8($self->request->content)) { |
|
214
|
0
|
|
|
|
|
0
|
my $content = $self->request->content; |
|
215
|
0
|
|
|
|
|
0
|
$content = encode_utf8($content); |
|
216
|
0
|
|
|
|
|
0
|
$self->request->content($content); |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
|
|
220
|
6
|
|
|
|
|
253
|
$self->response( $self->ua->simple_request( $self->request ) ); |
|
221
|
6
|
50
|
|
|
|
3156484
|
croak( $self->request->uri . ': ' . $self->response->status_line ) |
|
222
|
|
|
|
|
|
|
if $self->response->status_line =~ /500 Can't connect to /; |
|
223
|
6
|
|
|
|
|
356
|
return $self->response; |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=head2 $test->new_request(METHOD => $uri [, $headers [, $content]]); |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
Set up a new request object as in run_request, but do not execute it yet. |
|
229
|
|
|
|
|
|
|
This is handy if you want to call assorted methods on the request to tweak it |
|
230
|
|
|
|
|
|
|
before running it with C<< $test->run_request >>. |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=cut |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub new_request { |
|
235
|
6
|
|
|
6
|
1
|
30
|
my ( $self, $method, $uri, @args ) = @_; |
|
236
|
6
|
|
|
|
|
57
|
$self->request( |
|
237
|
|
|
|
|
|
|
HTTP::Request->new( $method => $uri, @args ) ); |
|
238
|
6
|
50
|
33
|
|
|
30838
|
$self->request->authorization_basic($self->username, $self->password) |
|
239
|
|
|
|
|
|
|
if (defined $self->username) || (defined $self->password); |
|
240
|
6
|
|
|
|
|
574
|
return $self->request; |
|
241
|
|
|
|
|
|
|
} |
|
242
|
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=head1 TEST METHODS |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head2 $test->status_code_is($code [, $description]); |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
Compares the last response status code with the given code using |
|
248
|
|
|
|
|
|
|
Cis>. |
|
249
|
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
=cut |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
sub status_code_is { |
|
253
|
6
|
|
|
6
|
1
|
104
|
local $Test::Builder::Level = $Test::Builder::Level + 1; |
|
254
|
6
|
|
|
|
|
19
|
my ( $self, $expected_code, $description ) = @_; |
|
255
|
|
|
|
|
|
|
|
|
256
|
6
|
|
33
|
|
|
176
|
$description ||= $self->name . " status is $expected_code."; |
|
257
|
|
|
|
|
|
|
|
|
258
|
6
|
|
|
|
|
395
|
$Builder->is_eq( $self->response->code, $expected_code, $description ); |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=head2 $test->header_is($header_name, $value [, $description]); |
|
262
|
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
Compares the response header C<$header_name> with the value C<$value> using |
|
264
|
|
|
|
|
|
|
Cis>. |
|
265
|
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=cut |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
sub header_is { |
|
269
|
0
|
|
|
0
|
1
|
0
|
local $Test::Builder::Level = $Test::Builder::Level + 1; |
|
270
|
0
|
|
|
|
|
0
|
my ( $self, $header_name, $expected_value, $description ) = @_; |
|
271
|
|
|
|
|
|
|
|
|
272
|
0
|
|
0
|
|
|
0
|
$description ||= $self->name . " $header_name matches '$expected_value'."; |
|
273
|
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
0
|
$Builder->is_eq( |
|
275
|
|
|
|
|
|
|
scalar $self->response->header($header_name), |
|
276
|
|
|
|
|
|
|
$expected_value, |
|
277
|
|
|
|
|
|
|
$description |
|
278
|
|
|
|
|
|
|
); |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=head2 $test->header_like($header_name, $regex, [, $description]); |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
Compares the response header C<$header_name> with the regex C<$regex> using |
|
284
|
|
|
|
|
|
|
Clike>. |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
=cut |
|
287
|
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
sub header_like { |
|
289
|
1
|
|
|
1
|
1
|
894
|
local $Test::Builder::Level = $Test::Builder::Level + 1; |
|
290
|
1
|
|
|
|
|
3
|
my ( $self, $header_name, $regex, $description ) = @_; |
|
291
|
|
|
|
|
|
|
|
|
292
|
1
|
|
33
|
|
|
37
|
$description ||= $self->name . " $header_name matches $regex."; |
|
293
|
|
|
|
|
|
|
|
|
294
|
1
|
|
|
|
|
45
|
$Builder->like( |
|
295
|
|
|
|
|
|
|
scalar $self->response->header($header_name), |
|
296
|
|
|
|
|
|
|
$regex, |
|
297
|
|
|
|
|
|
|
$description |
|
298
|
|
|
|
|
|
|
); |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
=head2 $test->body_is($expected_body [, $description]); |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
Verifies that the HTTP response body is exactly C<$expected_body>. |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=cut |
|
306
|
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
sub body_is { |
|
308
|
0
|
|
|
0
|
1
|
0
|
local $Test::Builder::Level = $Test::Builder::Level + 1; |
|
309
|
0
|
|
|
|
|
0
|
my ( $self, $expected_body, $description ) = @_; |
|
310
|
|
|
|
|
|
|
|
|
311
|
0
|
|
0
|
|
|
0
|
$description ||= $self->name . " body is '$expected_body'."; |
|
312
|
|
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
0
|
$Builder->is_eq( $self->_decoded_content, $expected_body, $description ); |
|
314
|
|
|
|
|
|
|
} |
|
315
|
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
=head2 $test->body_like($regex [, $description]); |
|
317
|
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
Compares the HTTP response body with C<$regex>. |
|
319
|
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=cut |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub body_like { |
|
323
|
0
|
|
|
0
|
1
|
0
|
local $Test::Builder::Level = $Test::Builder::Level + 1; |
|
324
|
0
|
|
|
|
|
0
|
my ( $self, $regex, $description ) = @_; |
|
325
|
|
|
|
|
|
|
|
|
326
|
0
|
|
0
|
|
|
0
|
$description ||= $self->name . " body matches $regex."; |
|
327
|
|
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
0
|
$Builder->like($self->_decoded_content, $regex, $description); |
|
329
|
|
|
|
|
|
|
} |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head1 USER AGENT GENERATION |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
The user agent (UA) is created when the C object is constructed. |
|
334
|
|
|
|
|
|
|
By default, L is used to create this object, but it may be |
|
335
|
|
|
|
|
|
|
handy to test your HTTP handlers without going through an actual HTTP server |
|
336
|
|
|
|
|
|
|
(for speed, e.g.), so there are a couple of ways to override the chosen class. |
|
337
|
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
If the environment variable C is set, this value is used |
|
339
|
|
|
|
|
|
|
instead. If not, then the current value of C<$Test::HTTP::UaClass> |
|
340
|
|
|
|
|
|
|
(C by default) is used. Thus, the incantation below may prove |
|
341
|
|
|
|
|
|
|
useful. |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
{ |
|
344
|
|
|
|
|
|
|
local $Test::HTTP::UaClass = 'MyCorp::REST::FakeUserAgent'; |
|
345
|
|
|
|
|
|
|
my $test = Test::HTTP->new("widget HTTP access"); |
|
346
|
|
|
|
|
|
|
# ... |
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
=cut |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub _ua_class { |
|
352
|
6
|
|
|
6
|
|
73
|
my $self = shift; |
|
353
|
|
|
|
|
|
|
|
|
354
|
6
|
50
|
|
|
|
261
|
my $class = exists $ENV{TEST_HTTP_UA_CLASS} |
|
355
|
|
|
|
|
|
|
? $ENV{TEST_HTTP_UA_CLASS} |
|
356
|
|
|
|
|
|
|
: $UaClass; |
|
357
|
|
|
|
|
|
|
|
|
358
|
6
|
|
|
|
|
394
|
eval "require $class"; |
|
359
|
6
|
50
|
|
|
|
113155
|
die if $@; |
|
360
|
6
|
|
|
|
|
50
|
$class->import; |
|
361
|
|
|
|
|
|
|
|
|
362
|
6
|
|
|
|
|
51
|
return $class; |
|
363
|
|
|
|
|
|
|
} |
|
364
|
|
|
|
|
|
|
|
|
365
|
|
|
|
|
|
|
sub _decoded_content { |
|
366
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
367
|
0
|
|
|
|
|
|
my $content = $self->response->decoded_content; |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# Work around a bug in HTTP::Message where only text or xml content types |
|
370
|
|
|
|
|
|
|
# are decoded |
|
371
|
0
|
|
|
|
|
|
my $response = $self->response; |
|
372
|
0
|
|
|
|
|
|
my $ct = $self->response->header("Content-Type"); |
|
373
|
0
|
0
|
0
|
|
|
|
unless ($response->content_is_text or $response->content_is_xml) { |
|
374
|
0
|
|
|
|
|
|
my ($charset) = $ct =~ m{charset=(\S+)}; |
|
375
|
0
|
|
0
|
|
|
|
$charset ||= "ISO-8859-1"; |
|
376
|
0
|
|
|
|
|
|
require Encode; |
|
377
|
0
|
|
|
|
|
|
$content = Encode::decode($charset, $content); |
|
378
|
|
|
|
|
|
|
} |
|
379
|
|
|
|
|
|
|
|
|
380
|
0
|
|
|
|
|
|
return $content; |
|
381
|
|
|
|
|
|
|
} |
|
382
|
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
384
|
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
L, |
|
386
|
|
|
|
|
|
|
L, |
|
387
|
|
|
|
|
|
|
L, |
|
388
|
|
|
|
|
|
|
L, |
|
389
|
|
|
|
|
|
|
L, |
|
390
|
|
|
|
|
|
|
L |
|
391
|
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=head1 AUTHOR |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
Socialtext, Inc. C<< >> |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
397
|
|
|
|
|
|
|
|
|
398
|
|
|
|
|
|
|
Copyright 2006 Socialtext, Inc., all rights reserved. |
|
399
|
|
|
|
|
|
|
|
|
400
|
|
|
|
|
|
|
Same terms as Perl. |
|
401
|
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
=cut |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
1; |