Bug 24830: Fix parse_prefetch recursion and +count cases
authorAgustin Moyano <agustinmoyano@theke.io>
Mon, 9 Mar 2020 15:05:03 +0000 (12:05 -0300)
committerMartin Renvoize <martin.renvoize@ptfs-europe.com>
Fri, 20 Mar 2020 15:18:40 +0000 (15:18 +0000)
When a child of a prefetched element wasn't found on element's
prefetch_whitelist, no prefetch element was returned.. including element
it self. Now we return element's name if no child was found.

Also, embeded keys that ended with +count where taken literaly. Now we
search the correct key by stripping _count of embedded element if it was
declared as "is_count"

To test:
1. Apply test patch but not this one
2. prove t/Koha/REST/Plugin/Query.t
CHECK => tests shoul fail
3. Apply this patch
4. prove t/Koha/REST/Plugin/Query.t
SUCCESS => tests pass
5. Sign off

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Koha/REST/Plugin/Query.pm

index 46296e6..ea6695f 100644 (file)
@@ -124,7 +124,7 @@ Generates the DBIC prefetch attribute based on embedded relations, and merges in
             return unless defined $embed;
 
             my @prefetches;
-            foreach my $key (keys %{$embed}) {
+            foreach my $key (sort keys(%{$embed})) {
                 my $parsed = _parse_prefetch($key, $embed, $result_set);
                 push @prefetches, $parsed if defined $parsed;
             }
@@ -353,20 +353,24 @@ sub _merge_embed {
 sub _parse_prefetch {
     my ( $key, $embed, $result_set) = @_;
 
-    return unless exists $result_set->prefetch_whitelist->{$key};
+    my $pref_key = $key;
+    $pref_key =~ s/_count$// if $embed->{$key}->{is_count};
+    return unless exists $result_set->prefetch_whitelist->{$pref_key};
 
-    my $ko_class = $result_set->prefetch_whitelist->{$key};
-    return $key unless defined $embed->{$key}->{children} && defined $ko_class;
+    my $ko_class = $result_set->prefetch_whitelist->{$pref_key};
+    return $pref_key unless defined $embed->{$key}->{children} && defined $ko_class;
 
-    my $prefetch = {};
-    foreach my $child (keys %{$embed->{$key}->{children}}) {
+    my @prefetches;
+    foreach my $child (sort keys(%{$embed->{$key}->{children}})) {
         my $parsed = _parse_prefetch($child, $embed->{$key}->{children}, $ko_class->new);
-        $prefetch->{$key} = $parsed if defined $parsed;
+        push @prefetches, $parsed if defined $parsed;
     }
 
-    return unless scalar(keys %{$prefetch});
+    return $pref_key unless scalar(@prefetches);
 
-    return $prefetch;
+    return {$pref_key => $prefetches[0]} if scalar(@prefetches) eq 1;
+
+    return {$pref_key => \@prefetches};
 }
 
 sub _from_api_param {