From 198fcccbb5a578c5794b0dc98bd7a73e4d44616d Mon Sep 17 00:00:00 2001
From: Tomas Cohen Arazi <tomascohen@theke.io>
Date: Mon, 23 Sep 2019 12:48:14 -0300
Subject: [PATCH] Bug 23667: Add route to GET /items

This patchset introduces a route to fetch items. It relies on the
already implemented code/mappings to get a single item.

To test:
- Apply this patches
- Run:
  $ kshell
 k$ prove t/db_dependent/api/v1/items.t
=> SUCCESS: Tests pass!
- Try the endpoint with your favourite API tool (Postman?)
- Sign off :-D

Note: to do exact searching on barcode, you need to build the query like
this:

GET /api/v1/items?external_id=<your_barcode>&_match=exact
---
 Koha/REST/V1/Items.pm         | 53 +++++++++++++++++++++++++++++++
 t/db_dependent/api/v1/items.t | 60 ++++++++++++++++++++++++++++++++++-
 2 files changed, 112 insertions(+), 1 deletion(-)

diff --git a/Koha/REST/V1/Items.pm b/Koha/REST/V1/Items.pm
index d93af2e6bc..1868b1e4a0 100644
--- a/Koha/REST/V1/Items.pm
+++ b/Koha/REST/V1/Items.pm
@@ -27,6 +27,57 @@ use Koha::Items;
 
 use Try::Tiny;
 
+=head1 NAME
+
+Koha::REST::V1::Items - Koha REST API for handling items (V1)
+
+=head1 API
+
+=head2 Methods
+
+=cut
+
+=head3 list
+
+Controller function that handles listing Koha::Item objects
+
+=cut
+
+sub list {
+    my $c = shift->openapi->valid_input or return;
+
+    return try {
+        my $items_set = Koha::Items->new;
+        my $items     = $c->objects->search( $items_set, \&_to_model, \&_to_api );
+        return $c->render(
+            status  => 200,
+            openapi => $items
+        );
+    }
+    catch {
+        unless ( blessed $_ && $_->can('rethrow') ) {
+            return $c->render(
+                status  => 500,
+                openapi => {
+                    error =>
+                      "Something went wrong, check Koha logs for details."
+                }
+            );
+        }
+        return $c->render(
+            status  => 500,
+            openapi => { error => "$_" }
+        );
+    };
+}
+
+
+=head3 get
+
+Controller function that handles retrieving a single Koha::Item
+
+=cut
+
 sub get {
     my $c = shift->openapi->valid_input or return;
 
@@ -51,6 +102,8 @@ sub get {
     };
 }
 
+=head2 Internal methods
+
 =head3 _to_api
 
 Helper function that maps unblessed Koha::Hold objects into REST api
diff --git a/t/db_dependent/api/v1/items.t b/t/db_dependent/api/v1/items.t
index a3724dcdc4..f60f389a9e 100644
--- a/t/db_dependent/api/v1/items.t
+++ b/t/db_dependent/api/v1/items.t
@@ -19,7 +19,7 @@
 
 use Modern::Perl;
 
-use Test::More tests => 1;
+use Test::More tests => 2;
 use Test::Mojo;
 use Test::Warn;
 
@@ -37,6 +37,64 @@ t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
 
 my $t = Test::Mojo->new('Koha::REST::V1');
 
+subtest 'list() tests' => sub {
+
+    plan tests => 12;
+
+    $schema->storage->txn_begin;
+
+    my $item   = $builder->build_object( { class => 'Koha::Items' } );
+    my $patron = $builder->build_object(
+        {
+            class => 'Koha::Patrons',
+            value => { flags => 4 }
+        }
+    );
+
+    my $nonprivilegedpatron = $builder->build_object(
+        {
+            class => 'Koha::Patrons',
+            value => { flags => 0 }
+        }
+    );
+
+    my $password = 'thePassword123';
+
+    $nonprivilegedpatron->set_password(
+        { password => $password, skip_validation => 1 } );
+    my $userid = $nonprivilegedpatron->userid;
+
+    $t->get_ok( "//$userid:$password@/api/v1/items" )
+      ->status_is(403)
+      ->json_is(
+        '/error' => 'Authorization failure. Missing required permission(s).' );
+
+    $patron->set_password( { password => $password, skip_validation => 1 } );
+    $userid = $patron->userid;
+
+    $t->get_ok( "//$userid:$password@/api/v1/items" )
+      ->status_is( 200, 'SWAGGER3.2.2' );
+
+    my $items_count = Koha::Items->search->count;
+    my $response_count = scalar @{ $t->tx->res->json };
+
+    is( $items_count, $response_count, 'The API returns all the items' );
+
+    $t->get_ok( "//$userid:$password@/api/v1/items?external_id=" . $item->barcode )
+      ->status_is(200)
+      ->json_is( '' => [ Koha::REST::V1::Items::_to_api( $item->TO_JSON ) ], 'SWAGGER3.3.2');
+
+    my $barcode = $item->barcode;
+    $item->delete;
+
+    $t->get_ok( "//$userid:$password@/api/v1/items?external_id=" . $item->barcode )
+      ->status_is(200)
+      ->json_is( '' => [] );
+
+    $schema->storage->txn_rollback;
+};
+
+
 subtest 'get() tests' => sub {
 
     plan tests => 9;
-- 
2.23.0