Skip to content

Commit

Permalink
Accept scroll_id in url, querystring, or post body
Browse files Browse the repository at this point in the history
and test it!
  • Loading branch information
rwstauner committed Apr 2, 2014
1 parent 2aba91d commit 45c0241
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 6 deletions.
19 changes: 13 additions & 6 deletions lib/MetaCPAN/Server/Controller/Scroll.pm
Expand Up @@ -15,17 +15,23 @@ sub index : Path('/_search/scroll') : Args {
my ( $self, $c, $scroll_id ) = @_;
my $req = $c->req;

# There must be a better way to do this.
if ( !defined($scroll_id) ) {
try {
$scroll_id = do { local $/; $req->body->getline() };
if ( my $qs_id = $req->param('scroll_id') ) {
$scroll_id = $qs_id;
}
else {
# Is this the best way to get the body content?
my $body = $req->body;
$scroll_id = do { local $/; $body->getline }
if ref $body;
}
die "Scroll Id required\n" unless defined($scroll_id);
}
catch {
print STDERR $_[0];
chomp( my $e = $_[0] );
$self->internal_error( $c, $e );
};

$scroll_id = ''
unless defined $scroll_id;
}

my $res = eval {
Expand All @@ -42,6 +48,7 @@ sub index : Path('/_search/scroll') : Args {
}
);
} or do { $self->internal_error( $c, $@ ); };

$c->stash($res);
}

Expand Down
117 changes: 117 additions & 0 deletions t/server/controller/scroll.t
@@ -0,0 +1,117 @@
use strict;
use warnings;

use MetaCPAN::Server::Test;
use Test::More;

test_psgi app, sub {
my $cb = shift;

test_scroll_methods($cb);
test_missing_scroll_id($cb);
};

sub test_missing_scroll_id {
my $cb = shift;
foreach my $req (
[ scroll_url_param(), 'url param' ],
[ scroll_post_body(), 'post body' ],
[ scroll_query_string(), 'query string' ],
)
{
is_deeply(
req_json( $cb, @$req, 500 ),
{ message => 'Scroll Id required' },
"error without scroll_id in $req->[-1]",
);
}
}

sub scroll_start {
return GET '/release/_search?size=1&scroll=5m';
}

sub scroll_url_param {
my $scroll_id = shift || '';
return GET "/_search/scroll/$scroll_id?scroll=5m";
}

sub scroll_post_body {
my $scroll_id = shift || '';

# Use text/plain to avoid Catalyst trying to process the body.
return POST "/_search/scroll?scroll=5m",
Content_type => 'text/plain',
Content => $scroll_id;
}

sub scroll_query_string {
my $scroll_id = shift || '';
return GET "/_search/scroll/?scroll_id=$scroll_id&scroll=5m";
}

sub req_json {
my ( $cb, $req, $desc, $code ) = @_;
ok( my $res = $cb->($req), $desc );

$code ||= 200;
is( $res->code, $code, "HTTP $code" )
or diag Test::More::explain($res);

ok( my $json = eval { decode_json( $res->content ) }, 'valid json' );
return $json;
}

sub test_scroll_methods {
my $cb = shift;

my $steps = [
sub {
req_json( $cb, scroll_start(), 'start scroll' );
},
sub {
req_json(
$cb,
scroll_url_param( $_[0] ),
'continue scroll with scroll_id in GET url'
);
},
sub {
req_json(
$cb,
scroll_post_body( $_[0] ),
'continue scroll with scroll_id in POST body'
);
},
sub {
req_json(
$cb,
scroll_query_string( $_[0] ),
'continue scroll with scroll_id in query string'
);
},
];

my $scroll_id;
my @docs;

# Repeat each type just to be sure.
foreach my $step ( shift(@$steps), (@$steps) x 2 ) {

# Pass in previous scroll_id.
my $json = $step->($scroll_id);

# Cache scroll_id for next call.
$scroll_id = $json->{_scroll_id};

# Save docs.
push @docs, $json->{hits}{hits}[0];
note $docs[-1]->{_source}{name};
}

my %ids = map { ( $_->{_id} => $_ ) } @docs;

is scalar( keys(%ids) ), scalar(@docs), 'got a new doc each time';
}

done_testing;

0 comments on commit 45c0241

Please sign in to comment.