Bugzilla – Attachment 190232 Details for
Bug 14962
Temp Shelving Location
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
reword! test suite for bug_14962
reword-test-suite-for-bug14962.patch (text/plain), 58.41 KB, created by
Jake Deery
on 2025-12-05 14:52:02 UTC
(
hide
)
Description:
reword! test suite for bug_14962
Filename:
MIME Type:
Creator:
Jake Deery
Created:
2025-12-05 14:52:02 UTC
Size:
58.41 KB
patch
obsolete
>From bc5fc3c593efa7ef7b506dd1ccc72a641d40faa5 Mon Sep 17 00:00:00 2001 >From: Jake Deery <jake.deery@openfifth.co.uk> >Date: Tue, 2 Dec 2025 09:16:05 +0000 >Subject: [PATCH] reword! test suite for bug_14962 > >--- > t/db_dependent/Circulation/Displays.t | 198 +++++++++++ > t/db_dependent/Koha/DisplayItems.t | 262 ++++++++++++++ > t/db_dependent/Koha/Displays.t | 174 ++++++++++ > t/db_dependent/api/v1/displayitems.t | 477 ++++++++++++++++++++++++++ > t/db_dependent/api/v1/displays.t | 411 ++++++++++++++++++++++ > t/db_dependent/api/v1/items.t | 83 ++++- > 6 files changed, 1604 insertions(+), 1 deletion(-) > create mode 100644 t/db_dependent/Circulation/Displays.t > create mode 100644 t/db_dependent/Koha/DisplayItems.t > create mode 100644 t/db_dependent/Koha/Displays.t > create mode 100644 t/db_dependent/api/v1/displayitems.t > create mode 100644 t/db_dependent/api/v1/displays.t > >diff --git a/t/db_dependent/Circulation/Displays.t b/t/db_dependent/Circulation/Displays.t >new file mode 100644 >index 00000000000..5ac09bc08b1 >--- /dev/null >+++ b/t/db_dependent/Circulation/Displays.t >@@ -0,0 +1,198 @@ >+#!/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 => 3; >+use Test::NoWarnings; >+ >+use C4::Circulation qw( AddIssue AddReturn ); >+use Koha::Database; >+use Koha::DateUtils qw( dt_from_string ); >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+ >+t::lib::Mocks::mock_preference( 'UseDisplayModule', 1 ); >+ >+subtest 'display_return_over - yes - any library' => sub { >+ plan tests => 5; >+ >+ # Create test data >+ my $library1 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $library2 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $patron = >+ $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library1->branchcode } } ); >+ my $item = >+ $builder->build_sample_item( { homebranch => $library1->branchcode, holdingbranch => $library1->branchcode } ); >+ >+ # Mock userenv >+ t::lib::Mocks::mock_userenv( { branchcode => $library1->branchcode } ); >+ >+ # Create a display with 'yes - any library' return_over setting >+ my $display = $builder->build_object( >+ { >+ class => 'Koha::Displays', >+ value => { >+ display_return_over => 'yes - any library', >+ enabled => 1, >+ start_date => undef, >+ end_date => undef, >+ } >+ } >+ ); >+ >+ # Add item to display >+ my $display_item = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $item->biblionumber, >+ } >+ } >+ ); >+ >+ # Verify item is in display >+ my $active_display = $item->active_display_item; >+ ok( defined $active_display, 'Item should have an active display item' ); >+ is( $active_display->display_id, $display->display_id, 'Display item should be linked to the correct display' ); >+ >+ # Issue the item >+ AddIssue( $patron, $item->barcode ); >+ >+ # Return the item at the home library >+ my ( $doreturn, $messages, $issue, $borrower ) = AddReturn( $item->barcode, $library1->branchcode ); >+ is( $doreturn, 1, 'Item should be returned successfully' ); >+ ok( exists $messages->{RemovedFromDisplay}, 'RemovedFromDisplay message should be present' ); >+ >+ # Verify item was removed from display >+ $active_display = $item->active_display_item; >+ is( $active_display, undef, 'Item should no longer have an active display item after return' ); >+}; >+ >+subtest 'display_return_over - yes - except at home library' => sub { >+ plan tests => 9; >+ >+ # Create test data >+ my $library1 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $library2 = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $patron = >+ $builder->build_object( { class => 'Koha::Patrons', value => { branchcode => $library1->branchcode } } ); >+ >+ # Mock userenv >+ t::lib::Mocks::mock_userenv( { branchcode => $library1->branchcode } ); >+ >+ # Test 1: Return at non-home library should remove from display >+ my $item1 = >+ $builder->build_sample_item( { homebranch => $library1->branchcode, holdingbranch => $library1->branchcode } ); >+ >+ my $display1 = $builder->build_object( >+ { >+ class => 'Koha::Displays', >+ value => { >+ display_return_over => 'yes - except at home library', >+ enabled => 1, >+ start_date => undef, >+ end_date => undef, >+ } >+ } >+ ); >+ >+ my $display_item1 = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display1->display_id, >+ itemnumber => $item1->itemnumber, >+ biblionumber => $item1->biblionumber, >+ } >+ } >+ ); >+ >+ my $active_display = $item1->active_display_item; >+ ok( defined $active_display, 'Item should have an active display item' ); >+ >+ AddIssue( $patron, $item1->barcode ); >+ my ( $doreturn, $messages, $issue, $borrower ) = AddReturn( $item1->barcode, $library2->branchcode ); >+ >+ is( $doreturn, 1, 'Item should be returned successfully at non-home library' ); >+ ok( >+ exists $messages->{RemovedFromDisplay}, >+ 'RemovedFromDisplay message should be present when returned at non-home library' >+ ); >+ >+ $active_display = $item1->active_display_item; >+ is( $active_display, undef, 'Item should be removed from display when returned at non-home library' ); >+ >+ # Test 2: Return at home library should NOT remove from display >+ my $item2 = >+ $builder->build_sample_item( { homebranch => $library1->branchcode, holdingbranch => $library1->branchcode } ); >+ >+ my $display2 = $builder->build_object( >+ { >+ class => 'Koha::Displays', >+ value => { >+ display_return_over => 'yes - except at home library', >+ enabled => 1, >+ start_date => undef, >+ end_date => undef, >+ } >+ } >+ ); >+ >+ my $display_item2 = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display2->display_id, >+ itemnumber => $item2->itemnumber, >+ biblionumber => $item2->biblionumber, >+ } >+ } >+ ); >+ >+ $active_display = $item2->active_display_item; >+ ok( defined $active_display, 'Item should have an active display item before return' ); >+ >+ AddIssue( $patron, $item2->barcode ); >+ ( $doreturn, $messages, $issue, $borrower ) = AddReturn( $item2->barcode, $library1->branchcode ); >+ >+ is( $doreturn, 1, 'Item should be returned successfully at home library' ); >+ ok( >+ !exists $messages->{RemovedFromDisplay}, >+ 'RemovedFromDisplay message should NOT be present when returned at home library' >+ ); >+ >+ $active_display = $item2->active_display_item; >+ ok( defined $active_display, 'Item should still have an active display item when returned at home library' ); >+ is( >+ $active_display->display_id, $display2->display_id, >+ 'Display item should still be linked to the correct display' >+ ); >+ >+ # Clean up >+ $display_item2->delete; >+}; >+ >+$schema->storage->txn_rollback; >diff --git a/t/db_dependent/Koha/DisplayItems.t b/t/db_dependent/Koha/DisplayItems.t >new file mode 100644 >index 00000000000..9efbf102bc3 >--- /dev/null >+++ b/t/db_dependent/Koha/DisplayItems.t >@@ -0,0 +1,262 @@ >+#!/usr/bin/perl >+ >+# Copyright 2025 Koha Development team >+# >+# 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::NoWarnings; >+use Test::More tests => 13; >+ >+use DateTime; >+use C4::Context; >+use Koha::DisplayItem; >+use Koha::DisplayItems; >+use Koha::Database; >+ >+use t::lib::TestBuilder; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+my $nb_of_display_items = Koha::DisplayItems->search->count; >+ >+# Create test data >+my $library = $builder->build( { source => 'Branch' } ); >+my $biblio = $builder->build( { source => 'Biblio' } ); >+my $item1 = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+my $item2 = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+ >+my $display = $builder->build( { source => 'Display', value => { display_branch => $library->{branchcode} } } ); >+ >+# Create display items for testing >+my $new_display_item_1 = Koha::DisplayItem->new( >+ { >+ display_id => $display->{display_id}, >+ itemnumber => $item1->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ date_added => '2024-01-01', >+ date_remove => '2024-12-31', >+ } >+)->store; >+ >+my $new_display_item_2 = Koha::DisplayItem->new( >+ { >+ display_id => $display->{display_id}, >+ itemnumber => $item2->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ date_added => '2024-02-01', >+ date_remove => '2024-11-30', >+ } >+)->store; >+ >+# Test basic CRUD operations >+like( $new_display_item_1->display_id, qr|^\d+$|, 'Adding a new display item should have set the display_id' ); >+is( Koha::DisplayItems->search->count, $nb_of_display_items + 2, 'The 2 display items should have been added' ); >+ >+my $retrieved_display_item_1 = Koha::DisplayItems->find( >+ { >+ display_id => $new_display_item_1->display_id, >+ itemnumber => $new_display_item_1->itemnumber >+ } >+); >+is( >+ $retrieved_display_item_1->biblionumber, $new_display_item_1->biblionumber, >+ 'Find a display item by composite key should return the correct display item' >+); >+ >+# Test Koha::DisplayItem methods >+subtest 'display method' => sub { >+ plan tests => 2; >+ >+ my $display_obj = $new_display_item_1->display; >+ isa_ok( $display_obj, 'Koha::Display', 'display should return a Koha::Display object' ); >+ is( $display_obj->display_id, $display->{display_id}, 'display should return the correct display' ); >+}; >+ >+subtest 'item method' => sub { >+ plan tests => 2; >+ >+ my $item_obj = $new_display_item_1->item; >+ isa_ok( $item_obj, 'Koha::Item', 'item should return a Koha::Item object' ); >+ is( $item_obj->itemnumber, $item1->{itemnumber}, 'item should return the correct item' ); >+}; >+ >+subtest 'biblio method' => sub { >+ plan tests => 2; >+ >+ my $biblio_obj = $new_display_item_1->biblio; >+ isa_ok( $biblio_obj, 'Koha::Biblio', 'biblio should return a Koha::Biblio object' ); >+ is( $biblio_obj->biblionumber, $biblio->{biblionumber}, 'biblio should return the correct biblio' ); >+}; >+ >+# Test Koha::DisplayItems methods >+subtest 'for_display method' => sub { >+ plan tests => 2; >+ >+ my $display_items = Koha::DisplayItems->for_display( $display->{display_id} ); >+ isa_ok( $display_items, 'Koha::DisplayItems', 'for_display should return a Koha::DisplayItems object' ); >+ is( $display_items->count, 2, 'for_display should return the correct number of display items' ); >+}; >+ >+subtest 'for_item method' => sub { >+ plan tests => 2; >+ >+ my $display_items = Koha::DisplayItems->for_item( $item1->{itemnumber} ); >+ isa_ok( $display_items, 'Koha::DisplayItems', 'for_item should return a Koha::DisplayItems object' ); >+ is( $display_items->count, 1, 'for_item should return the correct number of display items' ); >+}; >+ >+subtest 'for_biblio method' => sub { >+ plan tests => 2; >+ >+ my $display_items = Koha::DisplayItems->for_biblio( $biblio->{biblionumber} ); >+ isa_ok( $display_items, 'Koha::DisplayItems', 'for_biblio should return a Koha::DisplayItems object' ); >+ is( $display_items->count, 2, 'for_biblio should return the correct number of display items' ); >+}; >+ >+subtest 'due_for_removal method' => sub { >+ plan tests => 3; >+ >+ # Create a display item that should be removed today >+ my $today = DateTime->today->ymd; >+ my $item_to_remove = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+ >+ my $display_item_due = Koha::DisplayItem->new( >+ { >+ display_id => $display->{display_id}, >+ itemnumber => $item_to_remove->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ date_added => '2024-01-01', >+ date_remove => $today, >+ } >+ )->store; >+ >+ my $due_items = Koha::DisplayItems->due_for_removal; >+ isa_ok( $due_items, 'Koha::DisplayItems', 'due_for_removal should return a Koha::DisplayItems object' ); >+ >+ my $found_due_item = 0; >+ while ( my $item = $due_items->next ) { >+ $found_due_item = 1 if $item->itemnumber == $item_to_remove->{itemnumber}; >+ } >+ ok( $found_due_item, 'due_for_removal should include items due for removal today' ); >+ >+ # Create a display item that should be removed in the future >+ my $future_date = DateTime->today->add( days => 30 )->ymd; >+ my $item_future = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+ >+ my $display_item_future = Koha::DisplayItem->new( >+ { >+ display_id => $display->{display_id}, >+ itemnumber => $item_future->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ date_added => '2024-01-01', >+ date_remove => $future_date, >+ } >+ )->store; >+ >+ my $due_items_2 = Koha::DisplayItems->due_for_removal; >+ my $found_future_item = 0; >+ while ( my $item = $due_items_2->next ) { >+ $found_future_item = 1 if $item->itemnumber == $item_future->{itemnumber}; >+ } >+ ok( !$found_future_item, 'due_for_removal should not include items due for removal in the future' ); >+ >+ # Clean up the additional display items >+ $display_item_due->delete; >+ $display_item_future->delete; >+}; >+ >+subtest 'display_days automatic date_remove calculation' => sub { >+ plan tests => 5; >+ >+ # Create a display with display_days set to 30 >+ my $display_with_days = $builder->build_object( >+ { >+ class => 'Koha::Displays', >+ value => { display_days => 30 } >+ } >+ ); >+ >+ my $item3 = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+ >+ # Create display item without date_remove - should auto-calculate >+ my $display_item_auto = Koha::DisplayItem->new( >+ { >+ display_id => $display_with_days->display_id, >+ itemnumber => $item3->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ } >+ )->store; >+ >+ ok( defined $display_item_auto->date_remove, 'date_remove should be set automatically' ); >+ >+ # Calculate expected date (today + 30 days) >+ my $dt = DateTime->now( time_zone => C4::Context->tz() ); >+ $dt->add( days => 30 ); >+ my $expected_date = $dt->ymd; >+ is( $display_item_auto->date_remove, $expected_date, 'date_remove should be today + display_days' ); >+ >+ # Create display item with explicit date_remove - should NOT auto-calculate >+ my $item4 = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+ my $manual_date = '2025-12-31'; >+ my $display_item_manual = Koha::DisplayItem->new( >+ { >+ display_id => $display_with_days->display_id, >+ itemnumber => $item4->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ date_remove => $manual_date, >+ } >+ )->store; >+ >+ is( $display_item_manual->date_remove, $manual_date, 'Explicit date_remove should not be overridden' ); >+ >+ # Create display without display_days - date_remove should be NULL >+ my $display_no_days = $builder->build_object( >+ { >+ class => 'Koha::Displays', >+ value => { display_days => undef } >+ } >+ ); >+ my $item5 = $builder->build( { source => 'Item', value => { biblionumber => $biblio->{biblionumber} } } ); >+ >+ my $display_item_no_days = Koha::DisplayItem->new( >+ { >+ display_id => $display_no_days->display_id, >+ itemnumber => $item5->{itemnumber}, >+ biblionumber => $biblio->{biblionumber}, >+ } >+ )->store; >+ >+ is( $display_item_no_days->date_remove, undef, 'date_remove should be NULL when display has no display_days' ); >+ >+ # Clean up >+ $display_item_auto->delete; >+ $display_item_manual->delete; >+ $display_item_no_days->delete; >+ $display_with_days->delete; >+ $display_no_days->delete; >+ >+ pass('Cleanup successful'); >+}; >+ >+# Test delete >+$retrieved_display_item_1->delete; >+is( Koha::DisplayItems->search->count, $nb_of_display_items + 1, 'Delete should have deleted the display item' ); >+ >+$schema->storage->txn_rollback; >diff --git a/t/db_dependent/Koha/Displays.t b/t/db_dependent/Koha/Displays.t >new file mode 100644 >index 00000000000..96b9fa38584 >--- /dev/null >+++ b/t/db_dependent/Koha/Displays.t >@@ -0,0 +1,174 @@ >+#!/usr/bin/perl >+ >+# Copyright 2025 Koha Development team >+# >+# 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::NoWarnings; >+use Test::More tests => 10; >+ >+use DateTime; >+use Koha::Display; >+use Koha::Displays; >+use Koha::Database; >+ >+use t::lib::TestBuilder; >+ >+my $schema = Koha::Database->new->schema; >+$schema->storage->txn_begin; >+ >+my $builder = t::lib::TestBuilder->new; >+my $nb_of_displays = Koha::Displays->search->count; >+ >+# Create a library for testing display_branch >+my $library = $builder->build( { source => 'Branch' } ); >+ >+# Create item types for testing >+my $itemtype1 = $builder->build( { source => 'Itemtype' } ); >+my $itemtype2 = $builder->build( { source => 'Itemtype' } ); >+ >+# Get current date for testing >+my $today = DateTime->today; >+my $yesterday = $today->clone->subtract( days => 1 ); >+my $tomorrow = $today->clone->add( days => 1 ); >+ >+# Create displays for testing >+my $new_display_1 = Koha::Display->new( >+ { >+ display_name => 'my_display_name_for_test_1', >+ enabled => 1, >+ display_return_over => 'no', >+ start_date => $yesterday->ymd, >+ end_date => $tomorrow->ymd, >+ display_location => 'DISPLAY_LOC_1', >+ display_code => 'DISPLAY_CODE_1', >+ display_branch => $library->{branchcode}, >+ display_itype => $itemtype1->{itemtype}, >+ } >+)->store; >+ >+my $new_display_2 = Koha::Display->new( >+ { >+ display_name => 'my_display_name_for_test_2', >+ enabled => 0, >+ display_return_over => 'yes - any library', >+ display_location => 'DISPLAY_LOC_2', >+ display_code => 'DISPLAY_CODE_2', >+ display_itype => $itemtype2->{itemtype}, >+ } >+)->store; >+ >+# Test basic CRUD operations >+like( $new_display_1->display_id, qr|^\d+$|, 'Adding a new display should have set the display_id' ); >+is( Koha::Displays->search->count, $nb_of_displays + 2, 'The 2 displays should have been added' ); >+ >+my $retrieved_display_1 = Koha::Displays->find( $new_display_1->display_id ); >+is( >+ $retrieved_display_1->display_name, $new_display_1->display_name, >+ 'Find a display by id should return the correct display' >+); >+ >+# Test Koha::Display methods >+subtest 'display_items method' => sub { >+ plan tests => 2; >+ >+ my $display_items = $new_display_1->display_items; >+ isa_ok( $display_items, 'Koha::DisplayItems', 'display_items should return a Koha::DisplayItems object' ); >+ is( $display_items->count, 0, 'New display should have no display items' ); >+}; >+ >+subtest 'library method' => sub { >+ plan tests => 3; >+ >+ my $library_obj = $new_display_1->library; >+ isa_ok( $library_obj, 'Koha::Library', 'library should return a Koha::Library object' ); >+ is( $library_obj->branchcode, $library->{branchcode}, 'library should return the correct library' ); >+ >+ # Test display without library >+ is( $new_display_2->library, undef, 'display without library should return undef' ); >+}; >+ >+# Test Koha::Displays methods >+subtest 'enabled method' => sub { >+ plan tests => 2; >+ >+ my $enabled_displays = Koha::Displays->enabled; >+ isa_ok( $enabled_displays, 'Koha::Displays', 'enabled should return a Koha::Displays object' ); >+ >+ my $found_enabled = 0; >+ while ( my $display = $enabled_displays->next ) { >+ $found_enabled = 1 if $display->display_id == $new_display_1->display_id; >+ } >+ ok( $found_enabled, 'enabled displays should include the enabled display' ); >+}; >+ >+subtest 'for_branch method' => sub { >+ plan tests => 2; >+ >+ my $branch_displays = Koha::Displays->for_branch( $library->{branchcode} ); >+ isa_ok( $branch_displays, 'Koha::Displays', 'for_branch should return a Koha::Displays object' ); >+ >+ my $found_branch_display = 0; >+ while ( my $display = $branch_displays->next ) { >+ $found_branch_display = 1 if $display->display_id == $new_display_1->display_id; >+ } >+ ok( $found_branch_display, 'for_branch should include displays for the specified branch' ); >+}; >+ >+subtest 'active method' => sub { >+ plan tests => 3; >+ >+ my $active_displays = Koha::Displays->active; >+ isa_ok( $active_displays, 'Koha::Displays', 'active should return a Koha::Displays object' ); >+ >+ my $found_active = 0; >+ while ( my $display = $active_displays->next ) { >+ $found_active = 1 if $display->display_id == $new_display_1->display_id; >+ } >+ ok( $found_active, 'active displays should include the active display within date range' ); >+ >+ # Create a display that's not active (dates in the past) >+ my $past_end = $today->clone->subtract( days => 10 ); >+ my $past_start = $today->clone->subtract( days => 20 ); >+ >+ my $inactive_display = Koha::Display->new( >+ { >+ display_name => 'inactive_display', >+ enabled => 1, >+ display_return_over => 'no', >+ start_date => $past_start->ymd, >+ end_date => $past_end->ymd, >+ } >+ )->store; >+ >+ my $active_displays_2 = Koha::Displays->active; >+ my $found_inactive = 0; >+ while ( my $display = $active_displays_2->next ) { >+ $found_inactive = 1 if $display->display_id == $inactive_display->display_id; >+ } >+ ok( !$found_inactive, 'active displays should not include displays outside date range' ); >+ >+ # Clean up the inactive display >+ $inactive_display->delete; >+}; >+ >+# Test delete >+$retrieved_display_1->delete; >+is( Koha::Displays->search->count, $nb_of_displays + 1, 'Delete should have deleted the display' ); >+ >+$schema->storage->txn_rollback; >diff --git a/t/db_dependent/api/v1/displayitems.t b/t/db_dependent/api/v1/displayitems.t >new file mode 100644 >index 00000000000..d775760a795 >--- /dev/null >+++ b/t/db_dependent/api/v1/displayitems.t >@@ -0,0 +1,477 @@ >+#!/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::NoWarnings; >+use Test::More tests => 6; >+use Test::Mojo; >+use JSON; >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+use Koha::DisplayItems; >+use Koha::Database; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+my $t = Test::Mojo->new('Koha::REST::V1'); >+t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 ); >+ >+subtest 'list() tests' => sub { >+ >+ plan tests => 20; >+ >+ $schema->storage->txn_begin; >+ >+ Koha::DisplayItems->search->delete; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ ## Authorized user tests >+ # No displayitems, so empty array should be returned >+ $t->get_ok("//$userid:$password@/api/v1/display/items")->status_is(200)->json_is( [] ); >+ >+ # Create test data >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $biblio = $builder->build_sample_biblio(); >+ my $item = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ >+ my $displayitem = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ >+ # One displayitem created, should get returned >+ $t->get_ok("//$userid:$password@/api/v1/display/items")->status_is(200)->json_is( [ $displayitem->to_api ] ); >+ >+ # Create another displayitem with same display >+ my $item2 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ my $another_displayitem = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item2->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ >+ # Create displayitem with different display >+ my $display2 = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $item3 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ my $displayitem_different_display = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display2->display_id, >+ itemnumber => $item3->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ >+ # Three displayitems created, they should all be returned >+ $t->get_ok("//$userid:$password@/api/v1/display/items")->status_is(200)->json_is( >+ [ >+ $displayitem->to_api, >+ $another_displayitem->to_api, >+ $displayitem_different_display->to_api >+ ] >+ ); >+ >+ # Filtering works, two displayitems sharing display_id >+ $t->get_ok( "//$userid:$password@/api/v1/display/items?display_id=" . $display->display_id )->status_is(200) >+ ->json_is( >+ [ >+ $displayitem->to_api, >+ $another_displayitem->to_api >+ ] >+ ); >+ >+ $t->get_ok( "//$userid:$password@/api/v1/display/items?itemnumber=" . $item->itemnumber )->status_is(200) >+ ->json_is( [ $displayitem->to_api ] ); >+ >+ # Warn on unsupported query parameter >+ $t->get_ok("//$userid:$password@/api/v1/display/items?displayitem_blah=blah")->status_is(400) >+ ->json_is( [ { path => '/query/displayitem_blah', message => 'Malformed query string' } ] ); >+ >+ # Unauthorized access >+ $t->get_ok("//$unauth_userid:$password@/api/v1/display/items")->status_is(403); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'get() tests' => sub { >+ >+ plan tests => 11; >+ >+ $schema->storage->txn_begin; >+ >+ # Create test data >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $biblio = $builder->build_sample_biblio(); >+ my $item = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ >+ my $displayitem = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ $t->get_ok( >+ "//$userid:$password@/api/v1/display/items/" . $displayitem->display_id . "/" . $displayitem->itemnumber ) >+ ->status_is(200)->json_is( $displayitem->to_api ); >+ >+ $t->get_ok( "//$unauth_userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber )->status_is(403); >+ >+ # Create displayitem to delete >+ my $item_to_delete = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ my $displayitem_to_delete = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item_to_delete->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ my $non_existent_display_id = $displayitem_to_delete->display_id; >+ my $non_existent_item_id = $displayitem_to_delete->itemnumber; >+ $displayitem_to_delete->delete; >+ >+ $t->get_ok("//$userid:$password@/api/v1/display/items/$non_existent_display_id/$non_existent_item_id") >+ ->status_is(404)->json_is( '/error' => 'Display item not found' ); >+ >+ # Test with completely non-existent IDs >+ $t->get_ok("//$userid:$password@/api/v1/display/items/99999/99999")->status_is(404) >+ ->json_is( '/error' => 'Display item not found' ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'add() tests' => sub { >+ >+ plan tests => 17; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ # Create test data >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $biblio = $builder->build_sample_biblio(); >+ my $item = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ >+ my $displayitem = { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber, >+ date_added => "2024-01-15", >+ date_remove => "2024-02-15" >+ }; >+ >+ # Unauthorized attempt to write >+ $t->post_ok( "//$unauth_userid:$password@/api/v1/display/items" => json => $displayitem )->status_is(403); >+ >+ # Authorized attempt to write invalid data >+ my $displayitem_with_invalid_field = { >+ blah => "DisplayItem Blah", >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ }; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/display/items" => json => $displayitem_with_invalid_field ) >+ ->status_is(400)->json_is( >+ "/errors" => [ >+ { >+ message => "Properties not allowed: blah.", >+ path => "/body" >+ } >+ ] >+ ); >+ >+ # Authorized attempt to write >+ $t->post_ok( "//$userid:$password@/api/v1/display/items" => json => $displayitem )->status_is( 201, 'REST3.2.1' ) >+ ->header_like( >+ Location => qr|^\/api\/v1\/display/items/\d+/\d+|, >+ 'REST3.4.1' >+ )->json_is( '/display_id' => $displayitem->{display_id} ) >+ ->json_is( '/itemnumber' => $displayitem->{itemnumber} ) >+ ->json_is( '/biblionumber' => $displayitem->{biblionumber} ) >+ ->json_is( '/date_added' => $displayitem->{date_added} ); >+ >+ # Test missing required field (display_id is required) >+ my $displayitem_missing_field = { >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ >+ # Missing display_id (required field) >+ }; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/display/items" => json => $displayitem_missing_field )->status_is(400) >+ ->json_has('/errors'); >+ >+ # Test successful creation with different item >+ my $item2 = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ my $displayitem2 = { >+ display_id => $display->display_id, >+ itemnumber => $item2->itemnumber, >+ biblionumber => $biblio->biblionumber, >+ date_added => "2024-01-16", >+ date_remove => "2024-02-16" >+ }; >+ $t->post_ok( "//$userid:$password@/api/v1/display/items" => json => $displayitem2 )->status_is(201); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'update() tests' => sub { >+ >+ plan tests => 15; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ # Create test data >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $biblio = $builder->build_sample_biblio(); >+ my $item = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ >+ my $displayitem = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ >+ # Unauthorized attempt to update >+ $t->put_ok( "//$unauth_userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber => json => { date_added => '2024-01-20' } )->status_is(403); >+ >+ # Attempt partial update on a PUT (missing required field) >+ my $displayitem_with_missing_field = { >+ biblionumber => $biblio->biblionumber >+ >+ # Missing display_id and itemnumber (required fields) >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber => json => $displayitem_with_missing_field )->status_is(400) >+ ->json_has("/errors"); >+ >+ # Full object update on PUT >+ my $displayitem_with_updated_field = { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber, >+ date_added => "2024-01-20", >+ date_remove => "2024-03-20" >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber => json => $displayitem_with_updated_field )->status_is(200) >+ ->json_is( '/date_added' => '2024-01-20' ); >+ >+ # Authorized attempt to write invalid data >+ my $displayitem_with_invalid_field = { >+ blah => "DisplayItem Blah", >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber => json => $displayitem_with_invalid_field )->status_is(400)->json_is( >+ "/errors" => [ >+ { >+ message => "Properties not allowed: blah.", >+ path => "/body" >+ } >+ ] >+ ); >+ >+ # Test with non-existent displayitem >+ $t->put_ok( "//$userid:$password@/api/v1/display/items/99999/99999" => json => $displayitem_with_updated_field ) >+ ->status_is(404); >+ >+ # Wrong method (POST) >+ $t->post_ok( "//$userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber => json => $displayitem_with_updated_field )->status_is(404); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'delete() tests' => sub { >+ >+ plan tests => 7; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ # Create test data >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $biblio = $builder->build_sample_biblio(); >+ my $item = $builder->build_sample_item( { biblionumber => $biblio->biblionumber } ); >+ >+ my $displayitem = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $biblio->biblionumber >+ } >+ } >+ ); >+ >+ # Unauthorized attempt to delete >+ $t->delete_ok( "//$unauth_userid:$password@/api/v1/display/items/" >+ . $displayitem->display_id . "/" >+ . $displayitem->itemnumber )->status_is(403); >+ >+ $t->delete_ok( >+ "//$userid:$password@/api/v1/display/items/" . $displayitem->display_id . "/" . $displayitem->itemnumber ) >+ ->status_is( 204, 'REST3.2.4' )->content_is( '', 'REST3.3.4' ); >+ >+ $t->delete_ok( >+ "//$userid:$password@/api/v1/display/items/" . $displayitem->display_id . "/" . $displayitem->itemnumber ) >+ ->status_is(404); >+ >+ $schema->storage->txn_rollback; >+}; >diff --git a/t/db_dependent/api/v1/displays.t b/t/db_dependent/api/v1/displays.t >new file mode 100644 >index 00000000000..124a0709f77 >--- /dev/null >+++ b/t/db_dependent/api/v1/displays.t >@@ -0,0 +1,411 @@ >+#!/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::NoWarnings; >+use Test::More tests => 7; >+use Test::Mojo; >+use JSON; >+ >+use t::lib::TestBuilder; >+use t::lib::Mocks; >+ >+use Koha::Displays; >+use Koha::Database; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+my $t = Test::Mojo->new('Koha::REST::V1'); >+t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 ); >+ >+subtest 'config() tests' => sub { >+ >+ plan tests => 5; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ t::lib::Mocks::mock_preference( 'UseDisplayModule', 1 ); >+ >+ ## Authorized user tests >+ # No displays, so empty array should be returned >+ $t->get_ok("//$userid:$password@/api/v1/displays/config")->status_is(200) >+ ->json_is( { settings => { enabled => 1 } } ); >+ >+ # Unauthorized access >+ $t->get_ok("//$unauth_userid:$password@/api/v1/displays/config")->status_is(403); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'list() tests' => sub { >+ >+ plan tests => 20; >+ >+ $schema->storage->txn_begin; >+ >+ Koha::Displays->search->delete; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ ## Authorized user tests >+ # No displays, so empty array should be returned >+ $t->get_ok("//$userid:$password@/api/v1/displays")->status_is(200)->json_is( [] ); >+ >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ >+ # One display created, should get returned >+ $t->get_ok("//$userid:$password@/api/v1/displays")->status_is(200)->json_is( [ $display->to_api ] ); >+ >+ my $another_display = >+ $builder->build_object( >+ { class => 'Koha::Displays', value => { display_branch => $display->display_branch } } ); >+ my $display_with_another_branch = $builder->build_object( { class => 'Koha::Displays' } ); >+ >+ # Three displays created, they should all be returned >+ $t->get_ok("//$userid:$password@/api/v1/displays")->status_is(200)->json_is( >+ [ >+ $display->to_api, >+ $another_display->to_api, >+ $display_with_another_branch->to_api >+ ] >+ ); >+ >+ # Filtering works, two displays sharing display_branch >+ $t->get_ok( "//$userid:$password@/api/v1/displays?display_branch=" . $display->display_branch )->status_is(200) >+ ->json_is( >+ [ >+ $display->to_api, >+ $another_display->to_api >+ ] >+ ); >+ >+ $t->get_ok( "//$userid:$password@/api/v1/displays?display_name=" . $display->display_name )->status_is(200) >+ ->json_is( [ $display->to_api ] ); >+ >+ # Warn on unsupported query parameter >+ $t->get_ok("//$userid:$password@/api/v1/displays?display_blah=blah")->status_is(400) >+ ->json_is( [ { path => '/query/display_blah', message => 'Malformed query string' } ] ); >+ >+ # Unauthorized access >+ $t->get_ok("//$unauth_userid:$password@/api/v1/displays")->status_is(403); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'get() tests' => sub { >+ >+ plan tests => 8; >+ >+ $schema->storage->txn_begin; >+ >+ my $display = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ $t->get_ok( "//$userid:$password@/api/v1/displays/" . $display->display_id )->status_is(200) >+ ->json_is( $display->to_api ); >+ >+ $t->get_ok( "//$unauth_userid:$password@/api/v1/displays/" . $display->display_id )->status_is(403); >+ >+ my $display_to_delete = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $non_existent_id = $display_to_delete->display_id; >+ $display_to_delete->delete; >+ >+ $t->get_ok("//$userid:$password@/api/v1/displays/$non_existent_id")->status_is(404) >+ ->json_is( '/error' => 'Display not found' ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'add() tests' => sub { >+ >+ plan tests => 18; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ my $itemtype = $builder->build_object( { class => 'Koha::ItemTypes' } ); >+ >+ my $display = { >+ display_name => "Test Display", >+ enabled => JSON::true, >+ display_return_over => "no", >+ start_date => "2024-01-01", >+ end_date => "2024-12-31", >+ display_location => "DISPLAY", >+ display_code => "TEST", >+ display_branch => "CPL", >+ display_itype => $itemtype->itemtype >+ }; >+ >+ # Unauthorized attempt to write >+ $t->post_ok( "//$unauth_userid:$password@/api/v1/displays" => json => $display )->status_is(403); >+ >+ # Authorized attempt to write invalid data >+ my $display_with_invalid_field = { >+ blah => "Display Blah", >+ display_name => "Test Display", >+ enabled => JSON::true, >+ display_return_over => "no" >+ }; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/displays" => json => $display_with_invalid_field )->status_is(400) >+ ->json_is( >+ "/errors" => [ >+ { >+ message => "Properties not allowed: blah.", >+ path => "/body" >+ } >+ ] >+ ); >+ >+ # Authorized attempt to write >+ my $display_id = >+ $t->post_ok( "//$userid:$password@/api/v1/displays" => json => $display )->status_is( 201, 'REST3.2.1' ) >+ ->header_like( >+ Location => qr|^\/api\/v1\/displays/\d*|, >+ 'REST3.4.1' >+ )->json_is( '/display_name' => $display->{display_name} )->json_is( '/enabled' => $display->{enabled} ) >+ ->json_is( '/display_return_over' => $display->{display_return_over} ) >+ ->json_is( '/start_date' => $display->{start_date} )->tx->res->json->{display_id}; >+ >+ # Authorized attempt to create with null id >+ $display->{display_id} = undef; >+ $t->post_ok( "//$userid:$password@/api/v1/displays" => json => $display )->status_is(400)->json_has('/errors'); >+ >+ # Authorized attempt to create with existing id >+ $display->{display_id} = $display_id; >+ $t->post_ok( "//$userid:$password@/api/v1/displays" => json => $display )->status_is(400)->json_is( >+ "/errors" => [ >+ { >+ message => "Read-only.", >+ path => "/body/display_id" >+ } >+ ] >+ ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'update() tests' => sub { >+ >+ plan tests => 15; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ my $itemtype = $builder->build_object( { class => 'Koha::ItemTypes' } ); >+ >+ my $display_id = $builder->build_object( { class => 'Koha::Displays' } )->display_id; >+ >+ # Unauthorized attempt to update >+ $t->put_ok( "//$unauth_userid:$password@/api/v1/displays/$display_id" => json => >+ { display_name => 'New unauthorized name change' } )->status_is(403); >+ >+ # Attempt partial update on a PUT >+ my $display_with_missing_field = { >+ display_name => 'Updated Display', >+ enabled => JSON::false >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/displays/$display_id" => json => $display_with_missing_field ) >+ ->status_is(400) >+ ->json_is( "/errors" => [ { message => "Missing property.", path => "/body/display_return_over" } ] ); >+ >+ # Full object update on PUT >+ my $display_with_updated_field = { >+ display_name => "Updated Display Name", >+ enabled => JSON::false, >+ display_return_over => "yes - any library", >+ start_date => "2024-02-01", >+ end_date => "2024-11-30", >+ display_location => "NEWDISPLAY", >+ display_code => "UPDATED", >+ display_branch => "CPL", >+ display_itype => $itemtype->itemtype >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/displays/$display_id" => json => $display_with_updated_field ) >+ ->status_is(200)->json_is( '/display_name' => 'Updated Display Name' ); >+ >+ # Authorized attempt to write invalid data >+ my $display_with_invalid_field = { >+ blah => "Display Blah", >+ display_name => "Test Display", >+ enabled => JSON::true, >+ display_return_over => "no" >+ }; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/displays/$display_id" => json => $display_with_invalid_field ) >+ ->status_is(400)->json_is( >+ "/errors" => [ >+ { >+ message => "Properties not allowed: blah.", >+ path => "/body" >+ } >+ ] >+ ); >+ >+ my $display_to_delete = $builder->build_object( { class => 'Koha::Displays' } ); >+ my $non_existent_id = $display_to_delete->display_id; >+ $display_to_delete->delete; >+ >+ $t->put_ok( "//$userid:$password@/api/v1/displays/$non_existent_id" => json => $display_with_updated_field ) >+ ->status_is(404); >+ >+ # Wrong method (POST) >+ $display_with_updated_field->{display_id} = 2; >+ >+ $t->post_ok( "//$userid:$password@/api/v1/displays/$display_id" => json => $display_with_updated_field ) >+ ->status_is(404); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest 'delete() tests' => sub { >+ >+ plan tests => 7; >+ >+ $schema->storage->txn_begin; >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } # displays permission >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ my $display_id = $builder->build_object( { class => 'Koha::Displays' } )->display_id; >+ >+ # Unauthorized attempt to delete >+ $t->delete_ok("//$unauth_userid:$password@/api/v1/displays/$display_id")->status_is(403); >+ >+ $t->delete_ok("//$userid:$password@/api/v1/displays/$display_id")->status_is( 204, 'REST3.2.4' ) >+ ->content_is( '', 'REST3.3.4' ); >+ >+ $t->delete_ok("//$userid:$password@/api/v1/displays/$display_id")->status_is(404); >+ >+ $schema->storage->txn_rollback; >+}; >diff --git a/t/db_dependent/api/v1/items.t b/t/db_dependent/api/v1/items.t >index 16975e74a28..0b7dd005fb5 100755 >--- a/t/db_dependent/api/v1/items.t >+++ b/t/db_dependent/api/v1/items.t >@@ -19,8 +19,8 @@ > > use Modern::Perl; > >+use Test::More tests => 7; > use Test::NoWarnings; >-use Test::More tests => 6; > use Test::MockModule; > use Test::Mojo; > use Test::Warn; >@@ -601,3 +601,84 @@ subtest 'pickup_locations() tests' => sub { > > $schema->storage->txn_rollback; > }; >+ >+subtest 'effective display fields tests' => sub { >+ >+ plan tests => 12; >+ >+ $schema->storage->txn_begin; >+ >+ t::lib::Mocks::mock_preference( 'UseDisplayModule', 1 ); >+ >+ my $librarian = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 1 } >+ } >+ ); >+ my $password = 'thePassword123'; >+ $librarian->set_password( { password => $password, skip_validation => 1 } ); >+ my $userid = $librarian->userid; >+ >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { flags => 0 } >+ } >+ ); >+ $patron->set_password( { password => $password, skip_validation => 1 } ); >+ my $unauth_userid = $patron->userid; >+ >+ # Create an item with specific location, collection code, homebranch, and holdingbranch >+ my $item = $builder->build_sample_item( >+ { >+ location => 'SHELF', >+ ccode => 'COLL1', >+ homebranch => $librarian->branchcode, >+ holdingbranch => $librarian->branchcode, >+ } >+ ); >+ >+ # Test without display - should return regular values >+ $t->get_ok( "//$userid:$password@/api/v1/items/" . $item->id )->status_is(200) >+ ->json_is( '/effective_location' => 'SHELF' )->json_is( '/effective_collection_code' => 'COLL1' ) >+ ->json_is( '/effective_home_library_id' => $librarian->branchcode ) >+ ->json_is( '/effective_holding_library_id' => $librarian->branchcode ); >+ >+ # Create a display with different values >+ my $display_library = $builder->build_object( { class => 'Koha::Libraries' } ); >+ my $display = $builder->build_object( >+ { >+ class => 'Koha::Displays', >+ value => { >+ display_location => 'DISPLAY', >+ display_code => 'DISPLAYCOLL', >+ display_branch => $display_library->branchcode, >+ display_holding_branch => $display_library->branchcode, >+ enabled => 1, >+ start_date => undef, >+ end_date => undef, >+ } >+ } >+ ); >+ >+ # Add item to display >+ my $display_item = $builder->build_object( >+ { >+ class => 'Koha::DisplayItems', >+ value => { >+ display_id => $display->display_id, >+ itemnumber => $item->itemnumber, >+ biblionumber => $item->biblionumber, >+ } >+ } >+ ); >+ >+ # Test with display - should return display values >+ $t->get_ok( "//$userid:$password@/api/v1/items/" . $item->id )->status_is(200) >+ ->json_is( '/effective_location' => 'DISPLAY' )->json_is( '/effective_collection_code' => 'DISPLAYCOLL' ) >+ ->json_is( '/effective_home_library_id' => $display_library->branchcode ) >+ ->json_is( '/effective_holding_library_id' => $display_library->branchcode ); >+ >+ $schema->storage->txn_rollback; >+}; >-- >2.50.1 (Apple Git-155)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 14962
:
190216
|
190217
|
190218
|
190219
|
190220
|
190221
|
190222
|
190223
|
190224
|
190225
|
190226
|
190227
|
190228
|
190229
|
190230
|
190231
| 190232