Add query parameter validation
Change-Id: Ib0fa76faf0c70bb8373bf723f238c9e88b5b890a
diff --git a/lib/Kalamar/Controller/Search.pm b/lib/Kalamar/Controller/Search.pm
index 2359274..e8f3dff 100644
--- a/lib/Kalamar/Controller/Search.pm
+++ b/lib/Kalamar/Controller/Search.pm
@@ -2,6 +2,7 @@
use Mojo::Base 'Mojolicious::Controller';
use Mojo::Collection 'c';
use Mojo::ByteStream 'b';
+use Mojo::Util qw/quote/;
use POSIX 'ceil';
has no_cache => 0;
@@ -32,21 +33,18 @@
$v->optional('q', 'trim');
$v->optional('ql')->in(qw/poliqarp cosmas2 annis cql fcsql/);
$v->optional('collection', 'trim'); # Legacy
- $v->optional('cq', 'trim');
- # $v->optional('action'); # action 'inspect' is no longer valid
- # $v->optional('snippet');
+ $v->optional('cq', 'trim'); # New
$v->optional('cutoff')->in(qw/true false/);
$v->optional('count')->num(1, undef);
$v->optional('p', 'trim')->num(1, undef); # Start page
$v->optional('o', 'trim')->num(1, undef); # Offset
$v->optional('context');
+ # $v->optional('action'); # action 'inspect' is no longer valid
+ # $v->optional('snippet');
# Get query
my $query = $v->param('q');
- # TODO:
- # Check for validation errors!
-
# No query
unless ($query) {
return $c->render($c->loc('Template_intro', 'intro'));
@@ -64,9 +62,22 @@
# Start page
my $page = $v->param('p') // 1;
- $c->stash(query => $query);
+ $c->stash(q => $query);
$c->stash(ql => $query{ql});
+ # Check validation
+ if ($v->has_error) {
+
+ # Create error notifications
+ foreach my $failed_field (@{$v->failed}) {
+ $c->notify(error => 'Parameter ' . quote($failed_field) . ' invalid');
+ };
+ return $c->render(
+ status => 400,
+ template => 'failure'
+ );
+ };
+
my $items_per_page = $c->items_per_page;
# Set count
@@ -205,8 +216,6 @@
# Render result
return $c->render(
- q => $c->stash('query'),
- ql => $c->stash('ql'),
start_page => $page,
start_index => $json->{meta}->{startIndex},
results => _map_matches($json->{matches}),
@@ -227,8 +236,6 @@
# $c->_notify_on_errors(shift);
return $c->render(
- q => $c->stash('query'),
- ql => $c->stash('ql'),
template => 'failure'
);
}
@@ -360,6 +367,19 @@
$v->optional('layer');
$v->optional('spans')->in(qw/true false/);
+ # Check validation
+ if ($v->has_error) {
+
+ # Create error notifications
+ foreach my $failed_field (@{$v->failed}) {
+ $c->notify(error => 'Parameter ' . quote($failed_field) . ' invalid');
+ };
+ return $c->render(
+ status => 400,
+ json => $c->notifications('json')
+ );
+ };
+
# Old API foundry/layer usage
my $foundry = '*';
my %query = (foundry => '*');
diff --git a/t/match_info.t b/t/match_info.t
index 7403d52..5d23887 100644
--- a/t/match_info.t
+++ b/t/match_info.t
@@ -98,6 +98,11 @@
->header_is('X-Kalamar-Cache', 'true')
;
+# Check for validation error
+$t->get_ok('/corpus/WPD15/232/39681/p2133-2134?spans=no')
+ ->status_is(400)
+ ->json_is('/notifications/0/1', 'Parameter "spans" invalid')
+ ;
done_testing;
__END__
diff --git a/t/query.t b/t/query.t
index 933276f..59d8fc9 100644
--- a/t/query.t
+++ b/t/query.t
@@ -157,7 +157,22 @@
->content_like(qr!\"cutOff":true!)
;
-
+# Query with failing parameters
+$t->get_ok('/?q=fantastisch&ql=Fabelsprache')
+ ->status_is(400)
+ ->text_is('noscript div.notify-error', 'Parameter "ql" invalid')
+ ->element_count_is('noscript div.notify-error', 1)
+ ;
+$t->get_ok('/?q=fantastisch&cutoff=no')
+ ->status_is(400)
+ ->text_is('noscript div.notify-error', 'Parameter "cutoff" invalid')
+ ->element_count_is('noscript div.notify-error', 1)
+ ;
+$t->get_ok('/?q=fantastisch&p=hui&o=hui&count=-8')
+ ->status_is(400)
+ ->text_like('noscript div.notify-error', qr!Parameter ".+?" invalid!)
+ ->element_count_is('noscript div.notify-error', 3)
+ ;
done_testing;