Bug 32734: Add REST endpoint to list biblios
authorAgustin Moyano <agustinmoyano@theke.io>
Fri, 17 Feb 2023 01:17:43 +0000 (22:17 -0300)
committerTomas Cohen Arazi <tomascohen@theke.io>
Mon, 13 Mar 2023 18:12:04 +0000 (15:12 -0300)
This patch adds an endpoint to list biblios

To test:
1. apply patch
2. enable basic auth
3. call to GET /api/v1/biblios with the following Accept headers:
 * application/json
 * application/marcxml+xml
 * application/marc-in-json
 * application/marc
 * text/plain
4. notice how data changes with each Accept header
5. prove t/db_dependent/Koha/Biblios.t t/db_dependent/api/v1/biblios.t
6. sign off

Signed-off-by: Matt Blenkinsop <matt.blenkinsop@ptfs-europe.com>
Signed-off-by: Hammat Wele <hammat.wele@inlibro.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Koha/Biblios.pm
Koha/REST/V1/Biblios.pm
api/v1/swagger/paths/biblios.yaml
t/db_dependent/api/v1/biblios.t

index cf1cbdb..b41cda6 100644 (file)
@@ -24,6 +24,10 @@ use Koha::Database;
 
 use Koha::Biblio;
 use Koha::Libraries;
+use MARC::File::MiJ;
+use MARC::File::USMARC;
+use MARC::File::XML;
+use MARC::Record;
 
 use base qw(Koha::Objects Koha::Objects::Record::Collections);
 
@@ -35,6 +39,45 @@ Koha::Biblios - Koha Biblio object set class
 
 =head2 Class methods
 
+=head3 print_collection
+    my $collection_text = $result_set->print_collection($format)
+
+Return a text representation of a collection (group of records) in the specified format.
+Allowed formats are marcxml, mij, marc and txt. Defaults to marcxml.
+
+=cut
+
+sub print_collection {
+    my ( $self, $format ) = @_;
+
+    my ($start, $glue, $end, @parts);
+
+    my %serializers = (
+        'mij' => \&MARC::File::MiJ::encode,
+        'marc' => \&MARC::File::USMARC::encode,
+        'txt' => \&MARC::Record::as_formatted,
+        'marcxml' => \&MARC::File::XML::record
+    );
+    if ($format eq 'mij') {
+        $start = '[';
+        $glue = ',';
+        $end = ']';
+    } elsif ($format eq 'marc') {
+        $glue = "\n";
+    } elsif ($format eq 'txt') {
+        $glue = "\n\n";
+    } else {
+        $glue = '';
+        $format = 'marcxml';
+        $start = MARC::File::XML::header();
+        $end = MARC::File::XML::footer();
+    }
+    while (my $biblio = $self->next) {
+        push @parts, $serializers{$format}->($biblio->metadata->record);
+    }
+    return (defined $start ? $start : '').join($glue, @parts).(defined $end ? $end : '');
+}
+
 =head3 pickup_locations
 
     my $biblios = Koha::Biblios->search(...);
index 8546afb..c8d220e 100644 (file)
@@ -597,4 +597,76 @@ sub update {
         $c->unhandled_exception($_);
     };
 }
+
+=head3 list
+
+Controller function that handles retrieving a single biblio object
+
+=cut
+
+sub list {
+    my $c = shift->openapi->valid_input or return;
+
+    my $attributes;
+    $attributes =
+      { prefetch => ['metadata'] }    # don't prefetch metadata if not needed
+      unless $c->req->headers->accept =~ m/application\/json/;
+
+    my $biblios = $c->objects->search_rs( Koha::Biblios->new );
+
+    return try {
+
+        if ( $c->req->headers->accept =~ m/application\/json(;.*)?$/ ) {
+            return $c->render(
+                status => 200,
+                json   => $biblios->to_api
+            );
+        }
+        elsif (
+            $c->req->headers->accept =~ m/application\/marcxml\+xml(;.*)?$/ )
+        {
+            $c->res->headers->add( 'Content-Type', 'application/marcxml+xml' );
+            return $c->render(
+                status => 200,
+                text   => $biblios->print_collection('marcxml')
+            );
+        }
+        elsif (
+            $c->req->headers->accept =~ m/application\/marc-in-json(;.*)?$/ )
+        {
+            $c->res->headers->add( 'Content-Type', 'application/marc-in-json' );
+            return $c->render(
+                status => 200,
+                data   => $biblios->print_collection('mij')
+            );
+        }
+        elsif ( $c->req->headers->accept =~ m/application\/marc(;.*)?$/ ) {
+            $c->res->headers->add( 'Content-Type', 'application/marc' );
+            return $c->render(
+                status => 200,
+                text   => $biblios->print_collection('marc')
+            );
+        }
+        elsif ( $c->req->headers->accept =~ m/text\/plain(;.*)?$/ ) {
+            return $c->render(
+                status => 200,
+                text   => $biblios->print_collection('txt')
+            );
+        }
+        else {
+            return $c->render(
+                status  => 406,
+                openapi => [
+                    "application/json",         "application/marcxml+xml",
+                    "application/marc-in-json", "application/marc",
+                    "text/plain"
+                ]
+            );
+        }
+    }
+    catch {
+        $c->unhandled_exception($_);
+    };
+}
+
 1;
index 2480021..f8cfe00 100644 (file)
     x-koha-authorization:
       permissions:
         editcatalogue: edit_catalogue
+  get:
+    x-mojo-to: Biblios#list
+    operationId: listBiblio
+    tags:
+      - biblios
+    summary: List biblios
+    parameters:
+      - $ref: "../swagger.yaml#/parameters/page"
+      - $ref: "../swagger.yaml#/parameters/per_page"
+      - $ref: "../swagger.yaml#/parameters/match"
+      - $ref: "../swagger.yaml#/parameters/order_by"
+      - $ref: "../swagger.yaml#/parameters/q_param"
+      - $ref: "../swagger.yaml#/parameters/q_body"
+      - $ref: "../swagger.yaml#/parameters/q_header"
+      - $ref: "../swagger.yaml#/parameters/request_id_header"
+    produces:
+      - application/json
+      - application/marcxml+xml
+      - application/marc-in-json
+      - application/marc
+      - text/plain
+    responses:
+      "200":
+        description: A list of biblios
+      "401":
+        description: Authentication required
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "403":
+        description: Access forbidden
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "404":
+        description: Biblio not found
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "406":
+        description: Not acceptable
+        schema:
+          type: array
+          description: Accepted content-types
+          items:
+            type: string
+      "500":
+        description: |
+          Internal server error. Possible `error_code` attribute values:
+
+          * `internal_server_error`
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+      "503":
+        description: Under maintenance
+        schema:
+          $ref: "../swagger.yaml#/definitions/error"
+    x-koha-authorization:
+      permissions:
+        catalogue: "1"
 "/biblios/{biblio_id}":
   get:
     x-mojo-to: Biblios#get
index 5d17ee5..c401b1e 100755 (executable)
@@ -20,7 +20,7 @@ use Modern::Perl;
 use utf8;
 use Encode;
 
-use Test::More tests => 10;
+use Test::More tests => 11;
 use Test::MockModule;
 use Test::Mojo;
 use Test::Warn;
@@ -733,381 +733,381 @@ subtest 'post() tests' => sub {
 
     my $frameworkcode = 'BKS';
     my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
-<record
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
-    xmlns="http://www.loc.gov/MARC21/slim">
-
-  <leader>01102pam a2200289 a 7500</leader>
-  <controlfield tag="001">2504398</controlfield>
-  <controlfield tag="005">20200421093816.0</controlfield>
-  <controlfield tag="008">920610s1993    caub         s001 0 eng  </controlfield>
-  <datafield tag="010" ind1=" " ind2=" ">
-    <subfield code="a">   92021731 </subfield>
-  </datafield>
-  <datafield tag="020" ind1=" " ind2=" ">
-    <subfield code="a">05200784381 (Test marcxml)</subfield>
-  </datafield>
-  <datafield tag="020" ind1=" " ind2=" ">
-    <subfield code="a">05200784461 (Test marcxml)</subfield>
-  </datafield>
-  <datafield tag="040" ind1=" " ind2=" ">
-    <subfield code="a">DLC</subfield>
-    <subfield code="c">DLC</subfield>
-    <subfield code="d">DLC</subfield>
-  </datafield>
-  <datafield tag="041" ind1="0" ind2=" ">
-    <subfield code="a">enggrc</subfield>
-  </datafield>
-  <datafield tag="050" ind1="0" ind2="0">
-    <subfield code="a">PA522</subfield>
-    <subfield code="b">.M38 1993</subfield>
-  </datafield>
-  <datafield tag="082" ind1="0" ind2="0">
-    <subfield code="a">480</subfield>
-    <subfield code="2">20</subfield>
-  </datafield>
-  <datafield tag="100" ind1="1" ind2=" ">
-    <subfield code="a">Mastronarde, Donald J.</subfield>
-    <subfield code="9">389</subfield>
-  </datafield>
-  <datafield tag="245" ind1="1" ind2="0">
-    <subfield code="a">Introduction to Attic Greek (Using marcxml) /</subfield>
-    <subfield code="c">Donald J. Mastronarde.</subfield>
-  </datafield>
-  <datafield tag="260" ind1=" " ind2=" ">
-    <subfield code="a">Berkeley :</subfield>
-    <subfield code="b">University of California Press,</subfield>
-    <subfield code="c">c1993.</subfield>
-  </datafield>
-  <datafield tag="300" ind1=" " ind2=" ">
-    <subfield code="a">ix, 425 p. :</subfield>
-    <subfield code="b">maps ;</subfield>
-    <subfield code="c">26 cm.</subfield>
-  </datafield>
-  <datafield tag="500" ind1=" " ind2=" ">
-    <subfield code="a">Includes index.</subfield>
-  </datafield>
-  <datafield tag="650" ind1=" " ind2="0">
-    <subfield code="a">Attic Greek dialect</subfield>
-    <subfield code="9">7</subfield>
-  </datafield>
-  <datafield tag="856" ind1="4" ind2="2">
-    <subfield code="3">Contributor biographical information</subfield>
-    <subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
-  </datafield>
-  <datafield tag="856" ind1="4" ind2="2">
-    <subfield code="3">Publisher description</subfield>
-    <subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
-  </datafield>
-  <datafield tag="906" ind1=" " ind2=" ">
-    <subfield code="a">7</subfield>
-    <subfield code="b">cbc</subfield>
-    <subfield code="c">orignew</subfield>
-    <subfield code="d">1</subfield>
-    <subfield code="e">ocip</subfield>
-    <subfield code="f">19</subfield>
-    <subfield code="g">y-gencatlg</subfield>
-  </datafield>
-  <datafield tag="942" ind1=" " ind2=" ">
-    <subfield code="2">ddc</subfield>
-    <subfield code="c">BK</subfield>
-  </datafield>
-  <datafield tag="955" ind1=" " ind2=" ">
-    <subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
-  </datafield>
-  <datafield tag="999" ind1=" " ind2=" ">
-    <subfield code="c">3</subfield>
-    <subfield code="d">3</subfield>
-  </datafield>
-</record>|;
+    <record
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
+        xmlns="http://www.loc.gov/MARC21/slim">
+
+      <leader>01102pam a2200289 a 7500</leader>
+      <controlfield tag="001">2504398</controlfield>
+      <controlfield tag="005">20200421093816.0</controlfield>
+      <controlfield tag="008">920610s1993    caub         s001 0 eng  </controlfield>
+      <datafield tag="010" ind1=" " ind2=" ">
+        <subfield code="a">   92021731 </subfield>
+      </datafield>
+      <datafield tag="020" ind1=" " ind2=" ">
+        <subfield code="a">05200784381 (Test marcxml)</subfield>
+      </datafield>
+      <datafield tag="020" ind1=" " ind2=" ">
+        <subfield code="a">05200784461 (Test marcxml)</subfield>
+      </datafield>
+      <datafield tag="040" ind1=" " ind2=" ">
+        <subfield code="a">DLC</subfield>
+        <subfield code="c">DLC</subfield>
+        <subfield code="d">DLC</subfield>
+      </datafield>
+      <datafield tag="041" ind1="0" ind2=" ">
+        <subfield code="a">enggrc</subfield>
+      </datafield>
+      <datafield tag="050" ind1="0" ind2="0">
+        <subfield code="a">PA522</subfield>
+        <subfield code="b">.M38 1993</subfield>
+      </datafield>
+      <datafield tag="082" ind1="0" ind2="0">
+        <subfield code="a">480</subfield>
+        <subfield code="2">20</subfield>
+      </datafield>
+      <datafield tag="100" ind1="1" ind2=" ">
+        <subfield code="a">Mastronarde, Donald J.</subfield>
+        <subfield code="9">389</subfield>
+      </datafield>
+      <datafield tag="245" ind1="1" ind2="0">
+        <subfield code="a">Introduction to Attic Greek (Using marcxml) /</subfield>
+        <subfield code="c">Donald J. Mastronarde.</subfield>
+      </datafield>
+      <datafield tag="260" ind1=" " ind2=" ">
+        <subfield code="a">Berkeley :</subfield>
+        <subfield code="b">University of California Press,</subfield>
+        <subfield code="c">c1993.</subfield>
+      </datafield>
+      <datafield tag="300" ind1=" " ind2=" ">
+        <subfield code="a">ix, 425 p. :</subfield>
+        <subfield code="b">maps ;</subfield>
+        <subfield code="c">26 cm.</subfield>
+      </datafield>
+      <datafield tag="500" ind1=" " ind2=" ">
+        <subfield code="a">Includes index.</subfield>
+      </datafield>
+      <datafield tag="650" ind1=" " ind2="0">
+        <subfield code="a">Attic Greek dialect</subfield>
+        <subfield code="9">7</subfield>
+      </datafield>
+      <datafield tag="856" ind1="4" ind2="2">
+        <subfield code="3">Contributor biographical information</subfield>
+        <subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
+      </datafield>
+      <datafield tag="856" ind1="4" ind2="2">
+        <subfield code="3">Publisher description</subfield>
+        <subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
+      </datafield>
+      <datafield tag="906" ind1=" " ind2=" ">
+        <subfield code="a">7</subfield>
+        <subfield code="b">cbc</subfield>
+        <subfield code="c">orignew</subfield>
+        <subfield code="d">1</subfield>
+        <subfield code="e">ocip</subfield>
+        <subfield code="f">19</subfield>
+        <subfield code="g">y-gencatlg</subfield>
+      </datafield>
+      <datafield tag="942" ind1=" " ind2=" ">
+        <subfield code="2">ddc</subfield>
+        <subfield code="c">BK</subfield>
+      </datafield>
+      <datafield tag="955" ind1=" " ind2=" ">
+        <subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
+      </datafield>
+      <datafield tag="999" ind1=" " ind2=" ">
+        <subfield code="c">3</subfield>
+        <subfield code="d">3</subfield>
+      </datafield>
+    </record>|;
 
     my $mij = q|{
-  "fields": [
-    {
-      "001": "2504398"
-    },
-    {
-      "005": "20200421093816.0"
-    },
-    {
-      "008": "920610s1993    caub         s001 0 eng  "
-    },
-    {
-      "010": {
-        "ind1": " ",
-        "subfields": [
-          {
-            "a": "   92021731 "
+      "fields": [
+        {
+          "001": "2504398"
+        },
+        {
+          "005": "20200421093816.0"
+        },
+        {
+          "008": "920610s1993    caub         s001 0 eng  "
+        },
+        {
+          "010": {
+            "ind1": " ",
+            "subfields": [
+              {
+                "a": "   92021731 "
+              }
+            ],
+            "ind2": " "
           }
-        ],
-        "ind2": " "
-      }
-    },
-    {
-      "020": {
-        "subfields": [
-          {
-            "a": "05200784382 (Test mij)"
+        },
+        {
+          "020": {
+            "subfields": [
+              {
+                "a": "05200784382 (Test mij)"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "020": {
-        "subfields": [
-          {
-            "a": "05200784462 (Test mij)"
+        },
+        {
+          "020": {
+            "subfields": [
+              {
+                "a": "05200784462 (Test mij)"
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    },
-    {
-      "040": {
-        "subfields": [
-          {
-            "a": "DLC"
-          },
-          {
-            "c": "DLC"
-          },
-          {
-            "d": "DLC"
+        },
+        {
+          "040": {
+            "subfields": [
+              {
+                "a": "DLC"
+              },
+              {
+                "c": "DLC"
+              },
+              {
+                "d": "DLC"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "041": {
-        "ind2": " ",
-        "subfields": [
-          {
-            "a": "enggrc"
+        },
+        {
+          "041": {
+            "ind2": " ",
+            "subfields": [
+              {
+                "a": "enggrc"
+              }
+            ],
+            "ind1": "0"
           }
-        ],
-        "ind1": "0"
-      }
-    },
-    {
-      "050": {
-        "subfields": [
-          {
-            "a": "PA522"
-          },
-          {
-            "b": ".M38 1993"
+        },
+        {
+          "050": {
+            "subfields": [
+              {
+                "a": "PA522"
+              },
+              {
+                "b": ".M38 1993"
+              }
+            ],
+            "ind1": "0",
+            "ind2": "0"
           }
-        ],
-        "ind1": "0",
-        "ind2": "0"
-      }
-    },
-    {
-      "082": {
-        "subfields": [
-          {
-            "a": "480"
-          },
-          {
-            "2": "20"
+        },
+        {
+          "082": {
+            "subfields": [
+              {
+                "a": "480"
+              },
+              {
+                "2": "20"
+              }
+            ],
+            "ind2": "0",
+            "ind1": "0"
           }
-        ],
-        "ind2": "0",
-        "ind1": "0"
-      }
-    },
-    {
-      "100": {
-        "ind2": " ",
-        "subfields": [
-          {
-            "a": "Mastronarde, Donald J."
-          },
-          {
-            "9": "389"
+        },
+        {
+          "100": {
+            "ind2": " ",
+            "subfields": [
+              {
+                "a": "Mastronarde, Donald J."
+              },
+              {
+                "9": "389"
+              }
+            ],
+            "ind1": "1"
           }
-        ],
-        "ind1": "1"
-      }
-    },
-    {
-      "245": {
-        "ind1": "1",
-        "subfields": [
-          {
-            "a": "Introduction to Attic Greek  (Using mij) /"
-          },
-          {
-            "c": "Donald J. Mastronarde."
+        },
+        {
+          "245": {
+            "ind1": "1",
+            "subfields": [
+              {
+                "a": "Introduction to Attic Greek  (Using mij) /"
+              },
+              {
+                "c": "Donald J. Mastronarde."
+              }
+            ],
+            "ind2": "0"
           }
-        ],
-        "ind2": "0"
-      }
-    },
-    {
-      "260": {
-        "subfields": [
-          {
-            "a": "Berkeley :"
-          },
-          {
-            "b": "University of California Press,"
-          },
-          {
-            "c": "c1993."
+        },
+        {
+          "260": {
+            "subfields": [
+              {
+                "a": "Berkeley :"
+              },
+              {
+                "b": "University of California Press,"
+              },
+              {
+                "c": "c1993."
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "300": {
-        "ind1": " ",
-        "subfields": [
-          {
-            "a": "ix, 425 p. :"
-          },
-          {
-            "b": "maps ;"
-          },
-          {
-            "c": "26 cm."
+        },
+        {
+          "300": {
+            "ind1": " ",
+            "subfields": [
+              {
+                "a": "ix, 425 p. :"
+              },
+              {
+                "b": "maps ;"
+              },
+              {
+                "c": "26 cm."
+              }
+            ],
+            "ind2": " "
           }
-        ],
-        "ind2": " "
-      }
-    },
-    {
-      "500": {
-        "subfields": [
-          {
-            "a": "Includes index."
+        },
+        {
+          "500": {
+            "subfields": [
+              {
+                "a": "Includes index."
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    },
-    {
-      "650": {
-        "subfields": [
-          {
-            "a": "Attic Greek dialect"
-          },
-          {
-            "9": "7"
+        },
+        {
+          "650": {
+            "subfields": [
+              {
+                "a": "Attic Greek dialect"
+              },
+              {
+                "9": "7"
+              }
+            ],
+            "ind2": "0",
+            "ind1": " "
           }
-        ],
-        "ind2": "0",
-        "ind1": " "
-      }
-    },
-    {
-      "856": {
-        "subfields": [
-          {
-            "3": "Contributor biographical information"
-          },
-          {
-            "u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
+        },
+        {
+          "856": {
+            "subfields": [
+              {
+                "3": "Contributor biographical information"
+              },
+              {
+                "u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
+              }
+            ],
+            "ind2": "2",
+            "ind1": "4"
           }
-        ],
-        "ind2": "2",
-        "ind1": "4"
-      }
-    },
-    {
-      "856": {
-        "ind1": "4",
-        "subfields": [
-          {
-            "3": "Publisher description"
-          },
-          {
-            "u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
+        },
+        {
+          "856": {
+            "ind1": "4",
+            "subfields": [
+              {
+                "3": "Publisher description"
+              },
+              {
+                "u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
+              }
+            ],
+            "ind2": "2"
           }
-        ],
-        "ind2": "2"
-      }
-    },
-    {
-      "906": {
-        "subfields": [
-          {
-            "a": "7"
-          },
-          {
-            "b": "cbc"
-          },
-          {
-            "c": "orignew"
-          },
-          {
-            "d": "1"
-          },
-          {
-            "e": "ocip"
-          },
-          {
-            "f": "19"
-          },
-          {
-            "g": "y-gencatlg"
+        },
+        {
+          "906": {
+            "subfields": [
+              {
+                "a": "7"
+              },
+              {
+                "b": "cbc"
+              },
+              {
+                "c": "orignew"
+              },
+              {
+                "d": "1"
+              },
+              {
+                "e": "ocip"
+              },
+              {
+                "f": "19"
+              },
+              {
+                "g": "y-gencatlg"
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    },
-    {
-      "942": {
-        "subfields": [
-          {
-            "2": "ddc"
-          },
-          {
-            "c": "BK"
+        },
+        {
+          "942": {
+            "subfields": [
+              {
+                "2": "ddc"
+              },
+              {
+                "c": "BK"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "955": {
-        "subfields": [
-          {
-            "a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
+        },
+        {
+          "955": {
+            "subfields": [
+              {
+                "a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "999": {
-        "subfields": [
-          {
-            "c": "3"
-          },
-          {
-            "d": "3"
+        },
+        {
+          "999": {
+            "subfields": [
+              {
+                "c": "3"
+              },
+              {
+                "d": "3"
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    }
-  ],
-  "leader": "01102pam a2200289 a 8500"
-}|;
+        }
+      ],
+      "leader": "01102pam a2200289 a 8500"
+    }|;
     my $marc = q|01102pam a2200289 a 9500001000800000005001700008008004100025010001700066020002800083020003500111040001800146041001100164050002100175082001200196100003200208245005800240260005600298300003300354500002000387650002700407856009500434856008700529906004500616942001200661955013000673999000900803\1e2504398\1e20200421093816.0\1e920610s1993    caub         s001 0 eng  \1e  \1fa   92021731 \1e  \1fa05200784383 (Test usmarc)\1e  \1fa05200784463 (Test usmarc)\1e  \1faDLC\1fcDLC\1fdDLC\1e\1faenggrc\1e00\1faPA522\1fb.M38 1993\1e00\1fa480\1f220\1e\1faMastronarde, Donald J.\1f9389\1e10\1faIntroduction to Attic Greek  (Using usmarc) /\1fcDonald J. Mastronarde.\1e  \1faBerkeley :\1fbUniversity of California Press,\1fcc1993.\1e  \1faix, 425 p. :\1fbmaps ;\1fc26 cm.\1e  \1faIncludes index.\1e 0\1faAttic Greek dialect\1f97\1e42\1f3Contributor biographical information\1fuhttp://www.loc.gov/catdir/bios/ucal051/92021731.html\1e42\1f3Publisher description\1fuhttp://www.loc.gov/catdir/description/ucal041/92021731.html\1e  \1fa7\1fbcbc\1fcorignew\1fd1\1feocip\1ff19\1fgy-gencatlg\1e  \1f2ddc\1fcBK\1e  \1fapc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93\1e  \1fc3\1fd3\1e\1d|;
 
     $t->post_ok("//$userid:$password@/api/v1/biblios")
@@ -1165,381 +1165,381 @@ subtest 'put() tests' => sub {
     my $biblionumber = $biblio->biblionumber;
 
     my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
-<record
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
-    xmlns="http://www.loc.gov/MARC21/slim">
-
-  <leader>01102pam a2200289 a 6500</leader>
-  <controlfield tag="001">2504398</controlfield>
-  <controlfield tag="005">20200421093816.0</controlfield>
-  <controlfield tag="008">920610s1993    caub         s001 0 eng  </controlfield>
-  <datafield tag="010" ind1=" " ind2=" ">
-    <subfield code="a">   92021731 </subfield>
-  </datafield>
-  <datafield tag="020" ind1=" " ind2=" ">
-    <subfield code="a">05200784384 (Test json)</subfield>
-  </datafield>
-  <datafield tag="020" ind1=" " ind2=" ">
-    <subfield code="a">05200784464 (Test json)</subfield>
-  </datafield>
-  <datafield tag="040" ind1=" " ind2=" ">
-    <subfield code="a">DLC</subfield>
-    <subfield code="c">DLC</subfield>
-    <subfield code="d">DLC</subfield>
-  </datafield>
-  <datafield tag="041" ind1="0" ind2=" ">
-    <subfield code="a">enggrc</subfield>
-  </datafield>
-  <datafield tag="050" ind1="0" ind2="0">
-    <subfield code="a">PA522</subfield>
-    <subfield code="b">.M38 1993</subfield>
-  </datafield>
-  <datafield tag="082" ind1="0" ind2="0">
-    <subfield code="a">480</subfield>
-    <subfield code="2">20</subfield>
-  </datafield>
-  <datafield tag="100" ind1="1" ind2=" ">
-    <subfield code="a">Mastronarde, Donald J.</subfield>
-    <subfield code="9">389</subfield>
-  </datafield>
-  <datafield tag="245" ind1="1" ind2="0">
-    <subfield code="a">Introduction to Attic Greek  (Using marcxml) /</subfield>
-    <subfield code="c">Donald J. Mastronarde.</subfield>
-  </datafield>
-  <datafield tag="260" ind1=" " ind2=" ">
-    <subfield code="a">Berkeley :</subfield>
-    <subfield code="b">University of California Press,</subfield>
-    <subfield code="c">c1993.</subfield>
-  </datafield>
-  <datafield tag="300" ind1=" " ind2=" ">
-    <subfield code="a">ix, 425 p. :</subfield>
-    <subfield code="b">maps ;</subfield>
-    <subfield code="c">26 cm.</subfield>
-  </datafield>
-  <datafield tag="500" ind1=" " ind2=" ">
-    <subfield code="a">Includes index.</subfield>
-  </datafield>
-  <datafield tag="650" ind1=" " ind2="0">
-    <subfield code="a">Attic Greek dialect</subfield>
-    <subfield code="9">7</subfield>
-  </datafield>
-  <datafield tag="856" ind1="4" ind2="2">
-    <subfield code="3">Contributor biographical information</subfield>
-    <subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
-  </datafield>
-  <datafield tag="856" ind1="4" ind2="2">
-    <subfield code="3">Publisher description</subfield>
-    <subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
-  </datafield>
-  <datafield tag="906" ind1=" " ind2=" ">
-    <subfield code="a">7</subfield>
-    <subfield code="b">cbc</subfield>
-    <subfield code="c">orignew</subfield>
-    <subfield code="d">1</subfield>
-    <subfield code="e">ocip</subfield>
-    <subfield code="f">19</subfield>
-    <subfield code="g">y-gencatlg</subfield>
-  </datafield>
-  <datafield tag="942" ind1=" " ind2=" ">
-    <subfield code="2">ddc</subfield>
-    <subfield code="c">BK</subfield>
-  </datafield>
-  <datafield tag="955" ind1=" " ind2=" ">
-    <subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
-  </datafield>
-  <datafield tag="999" ind1=" " ind2=" ">
-    <subfield code="c">3</subfield>
-    <subfield code="d">3</subfield>
-  </datafield>
-</record>|;
+    <record
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
+        xmlns="http://www.loc.gov/MARC21/slim">
+
+      <leader>01102pam a2200289 a 6500</leader>
+      <controlfield tag="001">2504398</controlfield>
+      <controlfield tag="005">20200421093816.0</controlfield>
+      <controlfield tag="008">920610s1993    caub         s001 0 eng  </controlfield>
+      <datafield tag="010" ind1=" " ind2=" ">
+        <subfield code="a">   92021731 </subfield>
+      </datafield>
+      <datafield tag="020" ind1=" " ind2=" ">
+        <subfield code="a">05200784384 (Test json)</subfield>
+      </datafield>
+      <datafield tag="020" ind1=" " ind2=" ">
+        <subfield code="a">05200784464 (Test json)</subfield>
+      </datafield>
+      <datafield tag="040" ind1=" " ind2=" ">
+        <subfield code="a">DLC</subfield>
+        <subfield code="c">DLC</subfield>
+        <subfield code="d">DLC</subfield>
+      </datafield>
+      <datafield tag="041" ind1="0" ind2=" ">
+        <subfield code="a">enggrc</subfield>
+      </datafield>
+      <datafield tag="050" ind1="0" ind2="0">
+        <subfield code="a">PA522</subfield>
+        <subfield code="b">.M38 1993</subfield>
+      </datafield>
+      <datafield tag="082" ind1="0" ind2="0">
+        <subfield code="a">480</subfield>
+        <subfield code="2">20</subfield>
+      </datafield>
+      <datafield tag="100" ind1="1" ind2=" ">
+        <subfield code="a">Mastronarde, Donald J.</subfield>
+        <subfield code="9">389</subfield>
+      </datafield>
+      <datafield tag="245" ind1="1" ind2="0">
+        <subfield code="a">Introduction to Attic Greek  (Using marcxml) /</subfield>
+        <subfield code="c">Donald J. Mastronarde.</subfield>
+      </datafield>
+      <datafield tag="260" ind1=" " ind2=" ">
+        <subfield code="a">Berkeley :</subfield>
+        <subfield code="b">University of California Press,</subfield>
+        <subfield code="c">c1993.</subfield>
+      </datafield>
+      <datafield tag="300" ind1=" " ind2=" ">
+        <subfield code="a">ix, 425 p. :</subfield>
+        <subfield code="b">maps ;</subfield>
+        <subfield code="c">26 cm.</subfield>
+      </datafield>
+      <datafield tag="500" ind1=" " ind2=" ">
+        <subfield code="a">Includes index.</subfield>
+      </datafield>
+      <datafield tag="650" ind1=" " ind2="0">
+        <subfield code="a">Attic Greek dialect</subfield>
+        <subfield code="9">7</subfield>
+      </datafield>
+      <datafield tag="856" ind1="4" ind2="2">
+        <subfield code="3">Contributor biographical information</subfield>
+        <subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
+      </datafield>
+      <datafield tag="856" ind1="4" ind2="2">
+        <subfield code="3">Publisher description</subfield>
+        <subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
+      </datafield>
+      <datafield tag="906" ind1=" " ind2=" ">
+        <subfield code="a">7</subfield>
+        <subfield code="b">cbc</subfield>
+        <subfield code="c">orignew</subfield>
+        <subfield code="d">1</subfield>
+        <subfield code="e">ocip</subfield>
+        <subfield code="f">19</subfield>
+        <subfield code="g">y-gencatlg</subfield>
+      </datafield>
+      <datafield tag="942" ind1=" " ind2=" ">
+        <subfield code="2">ddc</subfield>
+        <subfield code="c">BK</subfield>
+      </datafield>
+      <datafield tag="955" ind1=" " ind2=" ">
+        <subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
+      </datafield>
+      <datafield tag="999" ind1=" " ind2=" ">
+        <subfield code="c">3</subfield>
+        <subfield code="d">3</subfield>
+      </datafield>
+    </record>|;
 
     my $mij = q|{
-  "fields": [
-    {
-      "001": "2504398"
-    },
-    {
-      "005": "20200421093816.0"
-    },
-    {
-      "008": "920610s1993    caub         s001 0 eng  "
-    },
-    {
-      "010": {
-        "ind1": " ",
-        "subfields": [
-          {
-            "a": "   92021731 "
+      "fields": [
+        {
+          "001": "2504398"
+        },
+        {
+          "005": "20200421093816.0"
+        },
+        {
+          "008": "920610s1993    caub         s001 0 eng  "
+        },
+        {
+          "010": {
+            "ind1": " ",
+            "subfields": [
+              {
+                "a": "   92021731 "
+              }
+            ],
+            "ind2": " "
           }
-        ],
-        "ind2": " "
-      }
-    },
-    {
-      "020": {
-        "subfields": [
-          {
-            "a": "05200784382 (Test mij)"
+        },
+        {
+          "020": {
+            "subfields": [
+              {
+                "a": "05200784382 (Test mij)"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "020": {
-        "subfields": [
-          {
-            "a": "05200784462 (Test mij)"
+        },
+        {
+          "020": {
+            "subfields": [
+              {
+                "a": "05200784462 (Test mij)"
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    },
-    {
-      "040": {
-        "subfields": [
-          {
-            "a": "DLC"
-          },
-          {
-            "c": "DLC"
-          },
-          {
-            "d": "DLC"
+        },
+        {
+          "040": {
+            "subfields": [
+              {
+                "a": "DLC"
+              },
+              {
+                "c": "DLC"
+              },
+              {
+                "d": "DLC"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "041": {
-        "ind2": " ",
-        "subfields": [
-          {
-            "a": "enggrc"
+        },
+        {
+          "041": {
+            "ind2": " ",
+            "subfields": [
+              {
+                "a": "enggrc"
+              }
+            ],
+            "ind1": "0"
           }
-        ],
-        "ind1": "0"
-      }
-    },
-    {
-      "050": {
-        "subfields": [
-          {
-            "a": "PA522"
-          },
-          {
-            "b": ".M38 1993"
+        },
+        {
+          "050": {
+            "subfields": [
+              {
+                "a": "PA522"
+              },
+              {
+                "b": ".M38 1993"
+              }
+            ],
+            "ind1": "0",
+            "ind2": "0"
           }
-        ],
-        "ind1": "0",
-        "ind2": "0"
-      }
-    },
-    {
-      "082": {
-        "subfields": [
-          {
-            "a": "480"
-          },
-          {
-            "2": "20"
+        },
+        {
+          "082": {
+            "subfields": [
+              {
+                "a": "480"
+              },
+              {
+                "2": "20"
+              }
+            ],
+            "ind2": "0",
+            "ind1": "0"
           }
-        ],
-        "ind2": "0",
-        "ind1": "0"
-      }
-    },
-    {
-      "100": {
-        "ind2": " ",
-        "subfields": [
-          {
-            "a": "Mastronarde, Donald J."
-          },
-          {
-            "9": "389"
+        },
+        {
+          "100": {
+            "ind2": " ",
+            "subfields": [
+              {
+                "a": "Mastronarde, Donald J."
+              },
+              {
+                "9": "389"
+              }
+            ],
+            "ind1": "1"
           }
-        ],
-        "ind1": "1"
-      }
-    },
-    {
-      "245": {
-        "ind1": "1",
-        "subfields": [
-          {
-            "a": "Introduction to Attic Greek  (Using mij) /"
-          },
-          {
-            "c": "Donald J. Mastronarde."
+        },
+        {
+          "245": {
+            "ind1": "1",
+            "subfields": [
+              {
+                "a": "Introduction to Attic Greek  (Using mij) /"
+              },
+              {
+                "c": "Donald J. Mastronarde."
+              }
+            ],
+            "ind2": "0"
           }
-        ],
-        "ind2": "0"
-      }
-    },
-    {
-      "260": {
-        "subfields": [
-          {
-            "a": "Berkeley :"
-          },
-          {
-            "b": "University of California Press,"
-          },
-          {
-            "c": "c1993."
+        },
+        {
+          "260": {
+            "subfields": [
+              {
+                "a": "Berkeley :"
+              },
+              {
+                "b": "University of California Press,"
+              },
+              {
+                "c": "c1993."
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "300": {
-        "ind1": " ",
-        "subfields": [
-          {
-            "a": "ix, 425 p. :"
-          },
-          {
-            "b": "maps ;"
-          },
-          {
-            "c": "26 cm."
+        },
+        {
+          "300": {
+            "ind1": " ",
+            "subfields": [
+              {
+                "a": "ix, 425 p. :"
+              },
+              {
+                "b": "maps ;"
+              },
+              {
+                "c": "26 cm."
+              }
+            ],
+            "ind2": " "
           }
-        ],
-        "ind2": " "
-      }
-    },
-    {
-      "500": {
-        "subfields": [
-          {
-            "a": "Includes index."
+        },
+        {
+          "500": {
+            "subfields": [
+              {
+                "a": "Includes index."
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    },
-    {
-      "650": {
-        "subfields": [
-          {
-            "a": "Attic Greek dialect"
-          },
-          {
-            "9": "7"
+        },
+        {
+          "650": {
+            "subfields": [
+              {
+                "a": "Attic Greek dialect"
+              },
+              {
+                "9": "7"
+              }
+            ],
+            "ind2": "0",
+            "ind1": " "
           }
-        ],
-        "ind2": "0",
-        "ind1": " "
-      }
-    },
-    {
-      "856": {
-        "subfields": [
-          {
-            "3": "Contributor biographical information"
-          },
-          {
-            "u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
+        },
+        {
+          "856": {
+            "subfields": [
+              {
+                "3": "Contributor biographical information"
+              },
+              {
+                "u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
+              }
+            ],
+            "ind2": "2",
+            "ind1": "4"
           }
-        ],
-        "ind2": "2",
-        "ind1": "4"
-      }
-    },
-    {
-      "856": {
-        "ind1": "4",
-        "subfields": [
-          {
-            "3": "Publisher description"
-          },
-          {
-            "u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
+        },
+        {
+          "856": {
+            "ind1": "4",
+            "subfields": [
+              {
+                "3": "Publisher description"
+              },
+              {
+                "u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
+              }
+            ],
+            "ind2": "2"
           }
-        ],
-        "ind2": "2"
-      }
-    },
-    {
-      "906": {
-        "subfields": [
-          {
-            "a": "7"
-          },
-          {
-            "b": "cbc"
-          },
-          {
-            "c": "orignew"
-          },
-          {
-            "d": "1"
-          },
-          {
-            "e": "ocip"
-          },
-          {
-            "f": "19"
-          },
-          {
-            "g": "y-gencatlg"
+        },
+        {
+          "906": {
+            "subfields": [
+              {
+                "a": "7"
+              },
+              {
+                "b": "cbc"
+              },
+              {
+                "c": "orignew"
+              },
+              {
+                "d": "1"
+              },
+              {
+                "e": "ocip"
+              },
+              {
+                "f": "19"
+              },
+              {
+                "g": "y-gencatlg"
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    },
-    {
-      "942": {
-        "subfields": [
-          {
-            "2": "ddc"
-          },
-          {
-            "c": "BK"
+        },
+        {
+          "942": {
+            "subfields": [
+              {
+                "2": "ddc"
+              },
+              {
+                "c": "BK"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "955": {
-        "subfields": [
-          {
-            "a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
+        },
+        {
+          "955": {
+            "subfields": [
+              {
+                "a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
+              }
+            ],
+            "ind2": " ",
+            "ind1": " "
           }
-        ],
-        "ind2": " ",
-        "ind1": " "
-      }
-    },
-    {
-      "999": {
-        "subfields": [
-          {
-            "c": "3"
-          },
-          {
-            "d": "3"
+        },
+        {
+          "999": {
+            "subfields": [
+              {
+                "c": "3"
+              },
+              {
+                "d": "3"
+              }
+            ],
+            "ind1": " ",
+            "ind2": " "
           }
-        ],
-        "ind1": " ",
-        "ind2": " "
-      }
-    }
-  ],
-  "leader": "01102pam a2200289 a 8500"
-}|;
+        }
+      ],
+      "leader": "01102pam a2200289 a 8500"
+    }|;
     my $marc = q|01116pam a2200289 a 4500001000800000005001700008008004100025010001700066020002800083020002800111040001800139041001100157050002100168082001200189100003200201245007500233260005600308300003300364500002000397650002700417856009500444856008700539906004500626942001200671955013000683999001300813\1e2504398\1e20221223213433.0\1e920610s1993    caub         s001 0 eng  \1e  \1fa   92021731 \1e  \1fa05200784384 (Test json)\1e  \1fa05200784464 (Test json)\1e  \1faDLC\1fcDLC\1fdDLC\1e\1faenggrc\1e00\1faPA522\1fb.M38 1993\1e00\1fa480\1f220\1e\1faMastronarde, Donald J.\1f9389\1e10\1faIntroduction to Attic Greek  (Using usmarc) /\1fcDonald J. Mastronarde.\1e  \1faBerkeley :\1fbUniversity of California Press,\1fcc1993.\1e  \1faix, 425 p. :\1fbmaps ;\1fc26 cm.\1e  \1faIncludes index.\1e 0\1faAttic Greek dialect\1f97\1e42\1f3Contributor biographical information\1fuhttp://www.loc.gov/catdir/bios/ucal051/92021731.html\1e42\1f3Publisher description\1fuhttp://www.loc.gov/catdir/description/ucal041/92021731.html\1e  \1fa7\1fbcbc\1fcorignew\1fd1\1feocip\1ff19\1fgy-gencatlg\1e  \1f2ddc\1fcBK\1e  \1fapc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93\1e  \1fc715\1fd715\1e\1d|;
 
     $t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber")
@@ -1582,4 +1582,58 @@ subtest 'put() tests' => sub {
     is($biblio->title, 'Introduction to Attic Greek  (Using usmarc) /');
 
     $schema->storage->txn_rollback;
-};
\ No newline at end of file
+};
+
+subtest 'list() tests' => sub {
+    plan tests => 14;
+
+    $schema->storage->txn_begin;
+
+    my $patron = $builder->build_object(
+        {
+            class => 'Koha::Patrons',
+            value => { flags => 0 }
+        }
+    );
+    my $password = 'thePassword123';
+    $patron->set_password( { password => $password, skip_validation => 1 } );
+    $patron->discard_changes;
+    my $userid = $patron->userid;
+
+    my $biblionumber1 = $builder->build_sample_biblio->biblionumber;
+    my $biblionumber2 = $builder->build_sample_biblio->biblionumber;
+
+    my $search =
+"[{\"biblionumber\": \"$biblionumber1\"}, {\"biblionumber\": \"$biblionumber2\"}]";
+    $t->get_ok(
+        "//$userid:$password@/api/v1/biblios/" => { 'x-koha-query' => $search }
+    )->status_is(403);
+
+    $patron->flags(4)->store;
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/" =>
+          { Accept => 'application/weird+format', 'x-koha-query' => $search } )
+      ->status_is(400);
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/" =>
+          { Accept => 'application/json', 'x-koha-query' => $search } )
+      ->status_is(200);
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/" =>
+          { Accept => 'application/marcxml+xml', 'x-koha-query' => $search } )
+      ->status_is(200);
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/" =>
+          { Accept => 'application/marc-in-json', 'x-koha-query' => $search } )
+      ->status_is(200);
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/" =>
+          { Accept => 'application/marc', 'x-koha-query' => $search } )
+      ->status_is(200);
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/" =>
+          { Accept => 'text/plain', 'x-koha-query' => $search } )
+      ->status_is(200);
+
+    $schema->storage->txn_rollback;
+};