From 99b69e47d72688fa2c0d6c1429602ca8d06863f2 Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Tue, 15 Mar 2022 09:42:19 -0300
Subject: [PATCH] Bug 30165: Make q parameter 'multi'

This patch changes the q_param definition so the defined query parameter
is repeatable. This way JSON::Validator will always generate an arrayref
for it and won't skip occurences.

The objects.search helper is updated to always consider the 'q'
parameter as an array, as expected.

To test:
1. Apply the regression tests patch
2. Run:
   $ kshell
  k$ prove t/db_dependent/api/v1/query.t
=> FAIL: Tests fail!
3. Apply this patch
4. Repeat 2
=> SUCCESS: Tests pass!
5. Sign off :-D

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
---
 Koha/REST/Plugin/Objects.pm    | 36 +++++++++++++++++++++++++---------
 api/v1/swagger/parameters.yaml |  5 ++++-
 2 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/Koha/REST/Plugin/Objects.pm b/Koha/REST/Plugin/Objects.pm
index 089b6ba2a6..6a94dac11c 100644
--- a/Koha/REST/Plugin/Objects.pm
+++ b/Koha/REST/Plugin/Objects.pm
@@ -138,18 +138,36 @@ shouldn't be called twice in it.
                 $filtered_params = $c->build_query_params( $filtered_params, $reserved_params );
             }
 
-            if( defined $reserved_params->{q} || defined $reserved_params->{query} || defined $reserved_params->{'x-koha-query'}) {
-                $filtered_params //={};
+            if (   defined $reserved_params->{q}
+                || defined $reserved_params->{query}
+                || defined $reserved_params->{'x-koha-query'} )
+            {
+                $filtered_params //= {};
+
                 my @query_params_array;
-                my $query_params;
-                push @query_params_array, $reserved_params->{query} if defined $reserved_params->{query};
+
+                # query in request body, JSON::Validator already decoded it
+                push @query_params_array, $reserved_params->{query}
+                  if defined $reserved_params->{query};
+
                 my $json = JSON->new;
-                push @query_params_array, $json->decode($reserved_params->{q}) if defined $reserved_params->{q};
-                push @query_params_array, $json->decode($reserved_params->{'x-koha-query'}) if defined $reserved_params->{'x-koha-query'};
 
-                if(scalar(@query_params_array) > 1) {
-                    $query_params = {'-and' => \@query_params_array};
-                } else {
+                # q is defined as multi => JSON::Validator generates an array
+                foreach my $q ( @{ $reserved_params->{q} } ) {
+                    push @query_params_array, $json->decode($q)
+                    if $q; # skip if exists but is empty
+                }
+
+                push @query_params_array,
+                  $json->decode( $reserved_params->{'x-koha-query'} )
+                  if defined $reserved_params->{'x-koha-query'};
+
+                my $query_params;
+
+                if ( scalar(@query_params_array) > 1 ) {
+                    $query_params = { '-and' => \@query_params_array };
+                }
+                else {
                     $query_params = $query_params_array[0];
                 }
 
diff --git a/api/v1/swagger/parameters.yaml b/api/v1/swagger/parameters.yaml
index ec15f2f8f6..10059ce631 100644
--- a/api/v1/swagger/parameters.yaml
+++ b/api/v1/swagger/parameters.yaml
@@ -75,7 +75,10 @@ q_param:
   in: query
   required: false
   description: Query filter sent as a request parameter
-  type: string
+  type: array
+  items:
+    type: string
+  collectionFormat: multi
 q_header:
   name: x-koha-query
   in: header
-- 
2.20.1