Skip to content

Commit c4fbadf

Browse files
committed
Add UserAgent role to help testing external http
1 parent 867eb32 commit c4fbadf

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

cpanfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ test_requires 'Module::Faker::Dist', '0.010';
159159
test_requires 'Config::General';
160160
test_requires 'ElasticSearch::TestServer';
161161
test_requires 'File::Copy';
162+
test_requires 'HTTP::Cookies';
162163
test_requires 'Test::Aggregate::Nested', '0.371';
163164
test_requires 'Test::Code::TidyAll';
164165
test_requires 'Test::More', '0.99';

t/lib/MetaCPAN/Tests/UserAgent.pm

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use strict;
2+
use warnings;
3+
4+
package MetaCPAN::Tests::UserAgent;
5+
6+
use Test::Routine;
7+
use Test::More;
8+
9+
use LWP::UserAgent;
10+
use HTTP::Cookies;
11+
use HTTP::Request;
12+
13+
has cb => (
14+
is => 'ro',
15+
required => 1,
16+
);
17+
18+
has responses => (
19+
is => 'ro',
20+
init_arg => undef,
21+
default => sub { [] },
22+
);
23+
24+
has ua => (
25+
is => 'ro',
26+
lazy => 1,
27+
default => sub {
28+
LWP::UserAgent->new(
29+
30+
# Don't follow redirect since we're not actually listening on
31+
# localhost:80 (we need to pass to $cb).
32+
max_redirect => 0,
33+
);
34+
},
35+
);
36+
37+
has cookie_jar => (
38+
is => 'ro',
39+
default => sub {
40+
HTTP::Cookies->new();
41+
},
42+
);
43+
44+
sub last_response {
45+
my ($self) = @_;
46+
$self->responses->[-1];
47+
}
48+
49+
sub redirect_uri {
50+
my ( $self, $response ) = @_;
51+
$response ||= $self->last_response;
52+
return URI->new( $response->header('location') );
53+
}
54+
55+
sub follow_redirect {
56+
my ( $self, $response ) = @_;
57+
$response ||= $self->last_response;
58+
59+
return $self->request( $self->request_from_redirect($response) );
60+
}
61+
62+
sub request_from_redirect {
63+
my ( $self, $response ) = @_;
64+
return HTTP::Request->new( GET => $self->redirect_uri($response) );
65+
}
66+
67+
# This can be overridden if tests have better criteria.
68+
sub request_is_external {
69+
my ( $self, $request ) = @_;
70+
71+
# If it's a generic URI (no scheme) it was probably "/controller/action".
72+
return 0 if !$request->uri->scheme;
73+
74+
# The tests shouldn't interact with a webserver on localhost:80
75+
# so assume that the request was built without host/port
76+
# and it was intended for the plack cb.
77+
return $request->uri->host_port ne 'localhost:80';
78+
}
79+
80+
sub request {
81+
my ( $self, $request ) = @_;
82+
my $response;
83+
84+
# Use UA to request against external servers.
85+
if ( $self->request_is_external($request) ) {
86+
$response = $self->ua->request($request);
87+
}
88+
89+
# Use the plack test cb for requests against our app.
90+
else {
91+
# We need to preserve the cookies so the API knows who we are.
92+
$self->cookie_jar->add_cookie_header($request);
93+
$response = $self->cb->($request);
94+
$self->cookie_jar->extract_cookies($response);
95+
}
96+
97+
push @{ $self->responses }, $response;
98+
99+
return $response;
100+
}
101+
102+
1;

0 commit comments

Comments
 (0)