From 41355ff97e1ad0651042f19394f630c41a8b2e3c Mon Sep 17 00:00:00 2001
From: Kyle M Hall <kyle@bywatersolutions.com>
Date: Fri, 11 Sep 2020 06:41:47 -0400
Subject: [PATCH] Bug 24857: (QA follow-up) Unit tests

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
---
 t/db_dependent/Koha/Volumes.t   | 151 +++++++++++++++++++
 t/db_dependent/api/v1/volumes.t | 257 ++++++++++++++++++++++++++++++++
 2 files changed, 408 insertions(+)
 create mode 100644 t/db_dependent/Koha/Volumes.t
 create mode 100644 t/db_dependent/api/v1/volumes.t

diff --git a/t/db_dependent/Koha/Volumes.t b/t/db_dependent/Koha/Volumes.t
new file mode 100644
index 0000000000..2930b83530
--- /dev/null
+++ b/t/db_dependent/Koha/Volumes.t
@@ -0,0 +1,151 @@
+#!/usr/bin/perl
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 6;
+
+use Koha::Database;
+
+use t::lib::TestBuilder;
+use t::lib::Mocks;
+
+BEGIN {
+    use_ok('Koha::Biblio::Volume');
+    use_ok('Koha::Biblio::Volumes');
+}
+
+my $schema  = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+t::lib::Mocks::mock_preference('EnableVolumes', 1);
+
+subtest 'Test Koha::Biblio::volumes' => sub {
+
+    plan tests => 6;
+
+    $schema->storage->txn_begin;
+
+    my $biblio = $builder->build_sample_biblio();
+
+    my @volumes = $biblio->volumes->as_list;
+    is( scalar(@volumes), 0, 'Got zero volumes');
+
+    my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store();
+
+    @volumes = $biblio->volumes->as_list;
+    is( scalar(@volumes), 1, 'Got one volume');
+    is( $volumes[0]->id, $volume_1->id, 'Got correct volume');
+
+    my $volume_2 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store();
+
+    @volumes = $biblio->volumes->as_list;
+    is( scalar(@volumes), 2, 'Got two volumes');
+    is( $volumes[0]->id, $volume_1->id, 'Got correct volume 1');
+    is( $volumes[1]->id, $volume_2->id, 'Got correct volume 2');
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'Test Koha::Biblio::Volume::add_item & Koha::Biblio::Volume::items' => sub {
+
+    plan tests => 6;
+
+    $schema->storage->txn_begin;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+
+    my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store();
+
+    my @items = $volume->items;
+    is( scalar(@items), 0, 'Volume has no items');
+
+    $volume->add_item({ item_id => $item_1->id });
+    @items = $volume->items->as_list;
+    is( scalar(@items), 1, 'Volume has one item');
+    is( $items[0]->id, $item_1->id, 'Item 1 is correct' );
+
+    $volume->add_item({ item_id => $item_2->id });
+    @items = $volume->items->as_list;
+    is( scalar(@items), 2, 'Volume has two items');
+    is( $items[0]->id, $item_1->id, 'Item 1 is correct' );
+    is( $items[1]->id, $item_2->id, 'Item 2 is correct' );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'Test Koha::Item::volume' => sub {
+
+    plan tests => 4;
+
+    $schema->storage->txn_begin;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+
+    is( $item_1->volume, undef, 'Item 1 has no volume');
+    is( $item_2->volume, undef, 'Item 2 has no volume');
+
+    my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store();
+    my $volume_2 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store();
+
+    $volume_1->add_item({ item_id => $item_1->id });
+    $volume_2->add_item({ item_id => $item_2->id });
+
+    is( $item_1->volume->id, $volume_1->id, 'Got volume 1 correctly' );
+    is( $item_2->volume->id, $volume_2->id, 'Got volume 2 correctly' );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'Koha::Item::delete should delete volume if no other items are using the volume' => sub {
+
+    plan tests => 8;
+
+    $schema->storage->txn_begin;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+    is( $biblio->items->count, 2, 'Bib has 2 items');
+
+    is( $item_1->volume, undef, 'Item 1 has no volume');
+    is( $item_2->volume, undef, 'Item 2 has no volume');
+
+    my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id } )->store();
+
+    $volume_1->add_item({ item_id => $item_1->id });
+    $volume_1->add_item({ item_id => $item_2->id });
+
+    my $volume = Koha::Biblio::Volumes->find( $volume_1->id );
+    is( $volume->id, $volume_1->id, 'Found the correct volume');
+
+    $item_1->delete();
+    is( $biblio->items->count, 1, 'Bib has 2 item');
+    $volume = Koha::Biblio::Volumes->find( $volume_1->id );
+    is( $volume->id, $volume_1->id, 'Volume still exists after deleting and item, but other items remain');
+
+    $item_2->delete();
+    is( $biblio->items->count, 0, 'Bib has 0 items');
+    $volume = Koha::Biblio::Volumes->find( $volume_1->id );
+    is( $volume, undef, 'Volume was deleted when last item was deleted');
+
+    $schema->storage->txn_rollback;
+};
diff --git a/t/db_dependent/api/v1/volumes.t b/t/db_dependent/api/v1/volumes.t
new file mode 100644
index 0000000000..7bb5e1aca9
--- /dev/null
+++ b/t/db_dependent/api/v1/volumes.t
@@ -0,0 +1,257 @@
+#!/usr/bin/env perl
+
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 5;
+use Test::Mojo;
+use Test::Warn;
+
+use t::lib::TestBuilder;
+use t::lib::Mocks;
+
+use List::Util qw(min);
+
+use Koha::Libraries;
+use Koha::Database;
+
+my $schema  = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
+t::lib::Mocks::mock_preference( 'EnableVolumes', 1 );
+
+my $t = Test::Mojo->new('Koha::REST::V1');
+
+subtest 'volumes list() tests' => sub {
+    plan tests => 9;
+
+    $schema->storage->txn_begin;
+
+    my $patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 4 }
+    });
+    my $password = 'thePassword123';
+    $patron->set_password({ password => $password, skip_validation => 1 });
+    my $userid = $patron->userid;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $biblio_id = $biblio->id;
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes" )
+        ->status_is( 200, 'SWAGGER3.2.2' );
+    my $response_count = scalar @{ $t->tx->res->json };
+    is( $response_count, 0, 'Results count is 2');
+
+    my $volume_1 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store();
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes" )
+        ->status_is( 200, 'SWAGGER3.2.2' );
+    $response_count = scalar @{ $t->tx->res->json };
+    is( $response_count, 1, 'Results count is 2');
+
+    my $volume_2 = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 2, description => "Vol 2" } )->store();
+
+    $t->get_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes" )
+      ->status_is( 200, 'SWAGGER3.2.2' );
+
+    $response_count = scalar @{ $t->tx->res->json };
+    is( $response_count, 2, 'Results count is 2');
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'volumes add() tests' => sub {
+
+    plan tests => 6;
+
+    $schema->storage->txn_begin;
+
+    my $authorized_patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 1 }
+    });
+    my $password = 'thePassword123';
+    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
+    my $auth_userid = $authorized_patron->userid;
+
+    my $unauthorized_patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 0 }
+    });
+    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
+    my $unauth_userid = $unauthorized_patron->userid;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $biblio_id = $biblio->id;
+    my $volume = { description => 'Vol 1', display_order => 1 };
+
+    # Unauthorized attempt
+    $t->post_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/volumes" => json => $volume )
+      ->status_is(403);
+
+    # Authorized attempt
+    $t->post_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes" => json => $volume )
+      ->status_is( 201, 'SWAGGER3.2.1' );
+
+    # Invalid biblio id
+    $t->post_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/volumes" => json => $volume )
+        ->status_is( 409, 'SWAGGER3.2.1' );
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'volumes update() tests' => sub {
+    plan tests => 9;
+
+    $schema->storage->txn_begin;
+
+    my $authorized_patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 1 }
+    });
+    my $password = 'thePassword123';
+    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
+    my $auth_userid = $authorized_patron->userid;
+
+    my $unauthorized_patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 0 }
+    });
+    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
+    my $unauth_userid = $unauthorized_patron->userid;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $biblio_id = $biblio->id;
+    my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store();
+    my $volume_id = $volume->id;
+
+    # Unauthorized attempt
+    $t->put_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id"
+                    => json => { description => 'New unauthorized desc change' } )
+      ->status_is(403);
+
+    # Authorized attempt
+    $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" => json => { description => "Vol A" } )
+      ->status_is(200, 'SWAGGER3.2.1')
+      ->json_has( '/description' => "Vol A", 'SWAGGER3.3.3' );
+
+    # Invalid biblio id
+    $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/volumes/$volume_id" => json => { description => "Vol A" } )
+        ->status_is(404);
+
+    # Invalid volume id
+    $t->put_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/XXX" => json => { description => "Vol A" } )
+        ->status_is(404);
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'volumes delete() tests' => sub {
+    plan tests => 9;
+
+    $schema->storage->txn_begin;
+
+    my $authorized_patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 1 }
+    });
+    my $password = 'thePassword123';
+    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
+    my $auth_userid = $authorized_patron->userid;
+
+    my $unauthorized_patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 0 }
+    });
+    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
+    my $unauth_userid = $unauthorized_patron->userid;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $biblio_id = $biblio->id;
+    my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store();
+    my $volume_id = $volume->id;
+
+    $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" )
+        ->status_is(204, 'SWAGGER3.2.4')
+        ->content_is('', 'SWAGGER3.3.4');
+
+    # Unauthorized attempt to delete
+    $t->delete_ok( "//$unauth_userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id" )
+      ->status_is(403);
+
+    $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/XXX/volumes/$volume_id" )
+        ->status_is(404);
+
+    $t->delete_ok( "//$auth_userid:$password@/api/v1/biblios/$biblio_id/volumes/XXX" )
+        ->status_is(404);
+
+    $schema->storage->txn_rollback;
+};
+
+subtest 'volume items add() + delete() tests' => sub {
+    plan tests => 11;
+
+    $schema->storage->txn_begin;
+
+    my $patron = $builder->build_object({
+        class => 'Koha::Patrons',
+        value => { flags => 4 }
+    });
+    my $password = 'thePassword123';
+    $patron->set_password({ password => $password, skip_validation => 1 });
+    my $userid = $patron->userid;
+
+    my $biblio = $builder->build_sample_biblio();
+    my $biblio_id = $biblio->id;
+
+    my $volume = Koha::Biblio::Volume->new( { biblionumber => $biblio->id, display_order => 1, description => "Vol 1" } )->store();
+    my $volume_id = $volume->id;
+
+    my @items = $volume->items;
+    is( scalar(@items), 0, 'Volume has no items');
+
+    my $item_1 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+    my $item_1_id = $item_1->id;
+
+    $t->post_ok( "//$userid:$password@/api/v1/biblios/{biblio_id}/volumes/$volume_id/items" => json => { item_id => $item_1->id } )
+        ->status_is( 201, 'SWAGGER3.2.1' );
+
+    @items = $volume->items;
+    is( scalar(@items), 1, 'Volume now has one item');
+
+    my $item_2 = $builder->build_sample_item({ biblionumber => $biblio->biblionumber });
+    my $item_2_id = $item_2->id;
+
+    $t->post_ok( "//$userid:$password@/api/v1/biblios/{biblio_id}/volumes/$volume_id/items" => json => { item_id => $item_2->id } )
+        ->status_is( 201, 'SWAGGER3.2.1' );
+
+    @items = $volume->items;
+    is( scalar(@items), 2, 'Volume now has two items');
+
+    warn "A VOLUME ID: $volume_id";
+    warn "A ITEM ID: $item_1_id";
+    $t->delete_ok( "//$userid:$password@/api/v1/biblios/$biblio_id/volumes/$volume_id/items/$item_1_id" )
+        ->status_is(204, 'SWAGGER3.2.4')
+        ->content_is('', 'SWAGGER3.3.4');
+
+    @items = $volume->items;
+    is( scalar(@items), 1, 'Volume now has one item');
+
+    $schema->storage->txn_rollback;
+};
-- 
2.30.2