Bug 42310: (follow-up) Retire t/db_dependent/Holidays.t

t/db_dependent/Holidays.t was a legacy file whose coverage is now
provided by the two dedicated calendar test files. Its calendar
behaviour assertions (is_holiday for weekly/day-month/single holidays)
are already exercised by t/db_dependent/Calendar.t and
t/db_dependent/Koha/Library/Calendar.t. The remaining unique cases
queried the special_holidays / repeatable_holidays tables directly,
which this bug drops during the migration to the
Koha::Library::Calendar::*Closure schema, so the file could no longer
run.

This commit folds the unique coverage into
t/db_dependent/Koha/Library/Calendar.t, rewritten against the new
closure objects/API (no raw legacy-table SQL):

- is_holiday DST edge case (America/Santiago days_between)
- next_open_days / prev_open_days throwing NoOpenDays when the library
  is never open, and finding an open day created via an exception
- copy_to completeness: repeating-closure copy, exception copy, and
  exclusion of past-dated single closures and exceptions, plus the
  no-duplication guarantee for all four closure types

and then deletes t/db_dependent/Holidays.t.

Test plan:
- prove t/db_dependent/Koha/Library/Calendar.t
- prove t/db_dependent/Calendar.t

Signed-off-by: Tomás Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Tomás Cohen Arazi 2026-09-14 10:58:14 -03:00 committed by Pedro Amorim
parent 755521ba0f
commit 51fd136eb1
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
3 changed files with 225 additions and 446 deletions

View File

@ -18,7 +18,7 @@
use Modern::Perl;
use Test::NoWarnings;
use Test::More tests => 7;
use Test::More tests => 8;
use Time::Fake;
use t::lib::Mocks;
@ -26,6 +26,7 @@ use t::lib::TestBuilder;
use DateTime;
use DateTime::Duration;
use C4::Calendar;
use Koha::Caches;
use Koha::Library::Calendar;
use Koha::Database;
@ -793,4 +794,59 @@ subtest 'get_push_amt' => sub {
};
};
subtest 'insert_single_holiday/insert_exception_holiday update the in-memory cache' => sub {
# Migrated from t/db_dependent/Holidays.t (C4::Calendar in-memory cache sync)
plan tests => 4;
$schema->storage->txn_begin;
my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
my $calendar = C4::Calendar->new( branchcode => $branchcode );
my $single_day = dt_from_string()->add( days => 10 );
$calendar->insert_single_holiday(
day => $single_day->day,
month => $single_day->month,
year => $single_day->year,
title => 'Single',
description => '',
);
is(
$calendar->isHoliday( $single_day->day, $single_day->month, $single_day->year ), 1,
'isHoliday sees a single holiday just inserted on the same C4::Calendar object'
);
# Close every weekday so exception_day is a holiday until the exception is added.
foreach my $weekday ( 0 .. 6 ) {
$calendar->insert_week_day_holiday( weekday => $weekday, title => '', description => '' );
}
# insert_exception_holiday called with 'date' rather than day/month/year,
# exercising the date-string derivation path.
my $exception_day = dt_from_string()->add( days => 20 );
$calendar->insert_exception_holiday(
date => $exception_day->ymd,
title => 'Exception',
description => '',
);
is(
$calendar->isHoliday( $exception_day->day, $exception_day->month, $exception_day->year ), 0,
'isHoliday sees an exception holiday just inserted on the same C4::Calendar object, overriding the weekday closure'
);
# A second, freshly instantiated C4::Calendar object should agree.
my $reloaded = C4::Calendar->new( branchcode => $branchcode );
is(
$reloaded->isHoliday( $single_day->day, $single_day->month, $single_day->year ), 1,
'A freshly instantiated C4::Calendar also sees the single holiday'
);
is(
$reloaded->isHoliday( $exception_day->day, $exception_day->month, $exception_day->year ), 0,
'A freshly instantiated C4::Calendar also sees the exception holiday'
);
$schema->storage->txn_rollback;
};
$schema->storage->txn_rollback();

View File

@ -1,443 +0,0 @@
#!/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 <https://www.gnu.org/licenses>.
use Modern::Perl;
use Test::NoWarnings;
use Test::More tests => 16;
use Test::Exception;
use DateTime;
use DateTime::TimeZone;
use t::lib::TestBuilder;
use C4::Context;
use Koha::Database;
use Koha::DateUtils qw( dt_from_string );
BEGIN {
use_ok('Koha::Library::Calendar');
use_ok('C4::Calendar');
}
my $schema = Koha::Database->new->schema;
my $dbh = C4::Context->dbh;
my $builder = t::lib::TestBuilder->new;
subtest 'is_holiday timezone tests' => sub {
plan tests => 1;
$schema->storage->txn_begin;
$dbh->do("DELETE FROM library_single_closures");
$dbh->do("DELETE FROM library_closure_exceptions");
# Clear cache
Koha::Caches->get_instance->flush_all;
# Artificially set timezone
my $timezone = 'America/Santiago';
$ENV{TZ} = $timezone;
use POSIX qw(tzset);
tzset;
my $branch = $builder->build( { source => 'Branch' } )->{branchcode};
my $calendar = Koha::Library::Calendar->new( branchcode => $branch );
C4::Calendar->new( branchcode => $branch )->insert_exception_holiday(
day => 6,
month => 9,
year => 2015,
title => 'Invalid date',
description => 'Invalid date description',
);
my $exception_holiday = DateTime->new( day => 6, month => 9, year => 2015 );
my $now_dt = DateTime->now;
my $diff;
eval { $diff = $calendar->days_between( $now_dt, $exception_holiday ) };
unlike(
$@,
qr/Invalid local time for date in time zone: America\/Santiago/,
'Avoid invalid datetime due to DST'
);
$schema->storage->txn_rollback;
};
$schema->storage->txn_begin;
# Create two fresh branches for the tests
my $branch_1 = $builder->build( { source => 'Branch' } )->{branchcode};
my $branch_2 = $builder->build( { source => 'Branch' } )->{branchcode};
C4::Calendar->new( branchcode => $branch_1 )->insert_week_day_holiday(
weekday => 0,
title => '',
description => 'Sundays',
);
my $holiday2add = dt_from_string("2015-01-01");
C4::Calendar->new( branchcode => $branch_1 )->insert_day_month_holiday(
day => $holiday2add->day(),
month => $holiday2add->month(),
year => $holiday2add->year(),
title => '',
description => "New Year's Day",
);
$holiday2add = dt_from_string("2014-12-25");
C4::Calendar->new( branchcode => $branch_1 )->insert_day_month_holiday(
day => $holiday2add->day(),
month => $holiday2add->month(),
year => $holiday2add->year(),
title => '',
description => 'Christmas',
);
my $koha_calendar = Koha::Library::Calendar->new( branchcode => $branch_1 );
my $c4_calendar = C4::Calendar->new( branchcode => $branch_1 );
isa_ok( $koha_calendar, 'Koha::Library::Calendar', 'Koha::Library::Calendar class returned' );
isa_ok( $c4_calendar, 'C4::Calendar', 'C4::Calendar class returned' );
my $sunday = DateTime->new(
year => 2011,
month => 6,
day => 26,
);
my $monday = DateTime->new(
year => 2011,
month => 6,
day => 27,
);
my $christmas = DateTime->new(
year => 2032,
month => 12,
day => 25,
);
my $newyear = DateTime->new(
year => 2035,
month => 1,
day => 1,
);
is( $koha_calendar->is_holiday($sunday), 1, 'Sunday is a closed day' );
is( $koha_calendar->is_holiday($monday), 0, 'Monday is not a closed day' );
is( $koha_calendar->is_holiday($christmas), 1, 'Christmas is a closed day' );
is( $koha_calendar->is_holiday($newyear), 1, 'New Years day is a closed day' );
$dbh->do("DELETE FROM library_weekly_closures");
$dbh->do("DELETE FROM library_repeating_closures");
$dbh->do("DELETE FROM library_single_closures");
$dbh->do("DELETE FROM library_closure_exceptions");
my $custom_holiday = DateTime->new(
year => 2013,
month => 11,
day => 12,
);
my $today = dt_from_string();
C4::Calendar->new( branchcode => $branch_2 )->insert_single_holiday(
day => $today->day(),
month => $today->month(),
year => $today->year(),
title => "$today",
description => "$today",
);
is(
Koha::Library::Calendar->new( branchcode => $branch_2 )->is_holiday($today), 1,
"Today is a holiday for $branch_2"
);
is(
Koha::Library::Calendar->new( branchcode => $branch_1 )->is_holiday($today), 0,
"Today is not a holiday for $branch_1"
);
$schema->storage->txn_rollback;
subtest 'copy_to_branch' => sub {
plan tests => 10;
$schema->storage->txn_begin;
my $branch1 = $builder->build( { source => 'Branch' } )->{branchcode};
my $calendar1 = C4::Calendar->new( branchcode => $branch1 );
my $sunday = dt_from_string("2020-03-15");
$calendar1->insert_week_day_holiday(
weekday => 0,
title => '',
description => 'Sundays',
);
my $day_month = dt_from_string("2020-03-17");
$calendar1->insert_day_month_holiday(
day => $day_month->day(),
month => $day_month->month(),
year => $day_month->year(),
title => '',
description => "",
);
my $future_date = dt_from_string("9999-12-31");
$calendar1->insert_single_holiday(
day => $future_date->day(),
month => $future_date->month(),
year => $future_date->year(),
title => "",
description => "",
);
my $future_exception = dt_from_string("9999-12-30");
$calendar1->insert_exception_holiday(
day => $future_exception->day(),
month => $future_exception->month(),
year => $future_exception->year(),
title => "",
description => "",
);
my $past_date = dt_from_string("2019-11-20");
$calendar1->insert_single_holiday(
day => $past_date->day(),
month => $past_date->month(),
year => $past_date->year(),
title => "",
description => "",
);
my $past_exception = dt_from_string("2020-03-09");
$calendar1->insert_exception_holiday(
day => $past_exception->day(),
month => $past_exception->month(),
year => $past_exception->year(),
title => "",
description => "",
);
my $branch2 = $builder->build( { source => 'Branch' } )->{branchcode};
C4::Calendar->new( branchcode => $branch1 )->copy_to_branch($branch2);
my $calendar2 = C4::Calendar->new( branchcode => $branch2 );
my $exceptions = $calendar2->get_exception_holidays;
is( $calendar2->isHoliday( $sunday->day, $sunday->month, $sunday->year ), 1, "Weekday holiday copied to branch 2" );
is(
$calendar2->isHoliday( $day_month->day, $day_month->month, $day_month->year ), 1,
"Day/month holiday copied to branch 2"
);
is(
$calendar2->isHoliday( $future_date->day, $future_date->month, $future_date->year ), 1,
"Single holiday copied to branch 2"
);
is( ( grep { $_->{date} eq "9999-12-30" } values %$exceptions ), 1, "Exception holiday copied to branch 2" );
is(
$calendar2->isHoliday( $past_date->day, $past_date->month, $past_date->year ), 0,
"Don't copy past single holidays"
);
is( ( grep { $_->{date} eq "2020-03-09" } values %$exceptions ), 0, "Don't copy past exception holidays " );
C4::Calendar->new( branchcode => $branch1 )->copy_to_branch($branch2);
#Select all rows with same values from database
my $dbh = C4::Context->dbh;
my $get_weekly_closures = "SELECT a.* FROM library_weekly_closures a
JOIN (SELECT library_id, weekday, COUNT(*)
FROM library_weekly_closures
GROUP BY library_id, weekday HAVING count(*) > 1) b
ON a.library_id = b.library_id AND a.weekday = b.weekday
ORDER BY a.library_id;";
my $sth = $dbh->prepare($get_weekly_closures);
$sth->execute;
my @weekly_closures;
while ( my $row = $sth->fetchrow_hashref ) {
push @weekly_closures, $row;
}
is( scalar(@weekly_closures), 0, "None of the weekly closures were doubled" );
my $get_repeating_closures = "SELECT a.* FROM library_repeating_closures a
JOIN (SELECT library_id, day, month, COUNT(*)
FROM library_repeating_closures
GROUP BY library_id, day, month HAVING count(*) > 1) b
ON a.library_id = b.library_id AND a.day = b.day AND a.month = b.month
ORDER BY a.library_id;";
$sth = $dbh->prepare($get_repeating_closures);
$sth->execute;
my @repeating_closures;
while ( my $row = $sth->fetchrow_hashref ) {
push @repeating_closures, $row;
}
is( scalar(@repeating_closures), 0, "None of the repeating closures were doubled" );
my $get_single_closures = "SELECT a.* FROM library_single_closures a
JOIN (SELECT library_id, date, COUNT(*)
FROM library_single_closures
GROUP BY library_id, date HAVING count(*) > 1) b
ON a.library_id = b.library_id AND a.date = b.date
ORDER BY a.library_id;";
$sth = $dbh->prepare($get_single_closures);
$sth->execute;
my @single_closures;
while ( my $row = $sth->fetchrow_hashref ) {
push @single_closures, $row;
}
is( scalar(@single_closures), 0, "None of the single closures were doubled" );
my $get_closure_exceptions = "SELECT a.* FROM library_closure_exceptions a
JOIN (SELECT library_id, date, COUNT(*)
FROM library_closure_exceptions
GROUP BY library_id, date HAVING count(*) > 1) b
ON a.library_id = b.library_id AND a.date = b.date
ORDER BY a.library_id;";
$sth = $dbh->prepare($get_closure_exceptions);
$sth->execute;
my @closure_exceptions;
while ( my $row = $sth->fetchrow_hashref ) {
push @closure_exceptions, $row;
}
is( scalar(@closure_exceptions), 0, "None of the closure exceptions were doubled" );
$schema->storage->txn_rollback;
};
subtest 'with a library that is never open' => sub {
plan tests => 2;
$schema->storage->txn_begin;
my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
my $calendar = C4::Calendar->new( branchcode => $branchcode );
foreach my $weekday ( 0 .. 6 ) {
$calendar->insert_week_day_holiday( weekday => $weekday, title => '', description => '' );
}
my $now = dt_from_string;
subtest 'next_open_days should throw an exception' => sub {
my $kcalendar = Koha::Library::Calendar->new( branchcode => $branchcode, days_mode => 'Calendar' );
throws_ok { $kcalendar->next_open_days( $now, 1 ) } 'Koha::Exceptions::Calendar::NoOpenDays';
};
subtest 'prev_open_days should throw an exception' => sub {
my $kcalendar = Koha::Library::Calendar->new( branchcode => $branchcode, days_mode => 'Calendar' );
throws_ok { $kcalendar->prev_open_days( $now, 1 ) } 'Koha::Exceptions::Calendar::NoOpenDays';
};
$schema->storage->txn_rollback;
};
subtest 'with a library that is *almost* never open' => sub {
plan tests => 2;
$schema->storage->txn_begin;
my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
my $calendar = C4::Calendar->new( branchcode => $branchcode );
foreach my $weekday ( 0 .. 6 ) {
$calendar->insert_week_day_holiday( weekday => $weekday, title => '', description => '' );
}
my $now = dt_from_string;
my $open_day_in_the_future = $now->clone()->add( years => 1 );
my $open_day_in_the_past = $now->clone()->subtract( years => 1 );
$calendar->insert_exception_holiday( date => $open_day_in_the_future->ymd, title => '', description => '' );
$calendar->insert_exception_holiday( date => $open_day_in_the_past->ymd, title => '', description => '' );
subtest 'next_open_days should find the open day' => sub {
my $kcalendar = Koha::Library::Calendar->new( branchcode => $branchcode, days_mode => 'Calendar' );
my $next_open_day = $kcalendar->next_open_days( $now, 1 );
is( $next_open_day->ymd, $open_day_in_the_future->ymd );
};
subtest 'prev_open_days should find the open day' => sub {
my $kcalendar = Koha::Library::Calendar->new( branchcode => $branchcode, days_mode => 'Calendar' );
my $prev_open_day = $kcalendar->prev_open_days( $now, 1 );
is( $prev_open_day->ymd, $open_day_in_the_past->ymd );
};
$schema->storage->txn_rollback;
};
subtest 'insert_single_holiday/insert_exception_holiday update the in-memory cache' => sub {
plan tests => 4;
$schema->storage->txn_begin;
my $branchcode = $builder->build( { source => 'Branch' } )->{branchcode};
my $calendar = C4::Calendar->new( branchcode => $branchcode );
my $single_day = dt_from_string()->add( days => 10 );
$calendar->insert_single_holiday(
day => $single_day->day,
month => $single_day->month,
year => $single_day->year,
title => 'Single',
description => '',
);
is(
$calendar->isHoliday( $single_day->day, $single_day->month, $single_day->year ), 1,
'isHoliday sees a single holiday just inserted on the same C4::Calendar object'
);
# Close every weekday so exception_day is a holiday until the exception is added.
foreach my $weekday ( 0 .. 6 ) {
$calendar->insert_week_day_holiday( weekday => $weekday, title => '', description => '' );
}
# insert_exception_holiday called with 'date' rather than day/month/year,
# exercising the date-string derivation path.
my $exception_day = dt_from_string()->add( days => 20 );
$calendar->insert_exception_holiday(
date => $exception_day->ymd,
title => 'Exception',
description => '',
);
is(
$calendar->isHoliday( $exception_day->day, $exception_day->month, $exception_day->year ), 0,
'isHoliday sees an exception holiday just inserted on the same C4::Calendar object, overriding the weekday closure'
);
# A second, freshly instantiated C4::Calendar object should agree.
my $reloaded = C4::Calendar->new( branchcode => $branchcode );
is(
$reloaded->isHoliday( $single_day->day, $single_day->month, $single_day->year ), 1,
'A freshly instantiated C4::Calendar also sees the single holiday'
);
is(
$reloaded->isHoliday( $exception_day->day, $exception_day->month, $exception_day->year ), 0,
'A freshly instantiated C4::Calendar also sees the exception holiday'
);
$schema->storage->txn_rollback;
};
# Clear cache
Koha::Caches->get_instance->flush_all;

View File

@ -1,4 +1,4 @@
#!/usr/bin/perl
#!/usr/bin/env perl
# Copyright 2025 Koha Development team
#
@ -19,13 +19,15 @@
use Modern::Perl;
use Test::More tests => 12;
use Test::More tests => 15;
use Test::Exception;
use Test::NoWarnings;
use Koha::Caches;
use Koha::Database;
use Koha::DateUtils qw( dt_from_string );
use DateTime;
use Koha::Library::Calendar::WeeklyClosures;
use Koha::Library::Calendar::RepeatingClosures;
use Koha::Library::Calendar::SingleClosures;
@ -473,3 +475,167 @@ subtest 'delete_weekly_closure/delete_repeating_closure refresh in-process state
$schema->storage->txn_rollback;
};
subtest 'is_holiday DST edge case' => sub {
# Migrated from t/db_dependent/Holidays.t
plan tests => 1;
$schema->storage->txn_begin;
Koha::Caches->get_instance->flush_all;
# Artificially set a timezone with a DST transition that historically
# triggered "Invalid local time for date in time zone" in date math.
local $ENV{TZ} = 'America/Santiago';
require POSIX;
POSIX::tzset();
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
my $calendar = Koha::Library::Calendar->new( branchcode => $library->branchcode );
$calendar->add_exception(
{ date => '2015-09-06', title => 'Invalid date', description => 'Invalid date description' } );
my $exception_holiday = DateTime->new( day => 6, month => 9, year => 2015 );
my $now_dt = dt_from_string;
my $diff;
eval { $diff = $calendar->days_between( $now_dt, $exception_holiday ) };
unlike(
$@,
qr{Invalid local time for date in time zone: America/Santiago},
'Avoid invalid datetime due to DST'
);
# Restore the process timezone so later teardown / end-of-run checks
# (e.g. Test::NoWarnings) are not affected by the artificial TZ.
delete $ENV{TZ};
POSIX::tzset();
$schema->storage->txn_rollback;
};
subtest 'next_open_days / prev_open_days' => sub {
# Migrated from t/db_dependent/Holidays.t
plan tests => 2;
subtest 'with a library that is never open' => sub {
plan tests => 2;
$schema->storage->txn_begin;
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
my $branchcode = $library->branchcode;
my $calendar = Koha::Library::Calendar->new( branchcode => $branchcode );
$calendar->add_weekly_closure( { weekday => $_, title => '', description => '' } ) for ( 0 .. 6 );
my $now = dt_from_string;
my $kcalendar = Koha::Library::Calendar->new( branchcode => $branchcode, days_mode => 'Calendar' );
throws_ok { $kcalendar->next_open_days( $now, 1 ) } 'Koha::Exceptions::Calendar::NoOpenDays',
'next_open_days throws when the library is never open';
throws_ok { $kcalendar->prev_open_days( $now, 1 ) } 'Koha::Exceptions::Calendar::NoOpenDays',
'prev_open_days throws when the library is never open';
$schema->storage->txn_rollback;
};
subtest 'with a library that is *almost* never open' => sub {
plan tests => 2;
$schema->storage->txn_begin;
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
my $branchcode = $library->branchcode;
my $calendar = Koha::Library::Calendar->new( branchcode => $branchcode );
$calendar->add_weekly_closure( { weekday => $_, title => '', description => '' } ) for ( 0 .. 6 );
my $now = dt_from_string;
my $open_day_in_the_future = $now->clone->add( years => 1 );
my $open_day_in_the_past = $now->clone->subtract( years => 1 );
# Exceptions override the weekly closures, making those single days open
$calendar->add_exception( { date => $open_day_in_the_future->ymd, title => '', description => '' } );
$calendar->add_exception( { date => $open_day_in_the_past->ymd, title => '', description => '' } );
my $kcalendar = Koha::Library::Calendar->new( branchcode => $branchcode, days_mode => 'Calendar' );
is(
$kcalendar->next_open_days( $now, 1 )->ymd, $open_day_in_the_future->ymd,
'next_open_days finds the future open day created via an exception'
);
is(
$kcalendar->prev_open_days( $now, 1 )->ymd, $open_day_in_the_past->ymd,
'prev_open_days finds the past open day created via an exception'
);
$schema->storage->txn_rollback;
};
};
subtest 'copy_to completeness' => sub {
# Migrated from t/db_dependent/Holidays.t copy_to_branch: all four closure
# types copy, past-dated single/exception are excluded, and a second copy
# does not duplicate any of the four types.
plan tests => 8;
$schema->storage->txn_begin;
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
my $calendar = Koha::Library::Calendar->new( branchcode => $library->branchcode );
my $today = dt_from_string;
$calendar->add_weekly_closure( { weekday => 6, title => 'Saturdays', description => '' } );
$calendar->add_repeating_closure( { day => 4, month => 7, title => 'Independence', description => '' } );
$calendar->add_single_closure( { date => '2027-01-01', title => 'New Year', description => '' } );
$calendar->add_exception( { date => '2027-01-02', title => 'Special opening', description => '' } );
# Past-dated single closure and exception must not be copied
my $past_date = $today->clone->subtract( years => 1 )->ymd;
$calendar->add_single_closure( { date => $past_date, title => 'Past single', description => '' } );
$calendar->add_exception( { date => $past_date, title => 'Past exception', description => '' } );
my $library2 = $builder->build_object( { class => 'Koha::Libraries' } );
$calendar->copy_to( $library2->branchcode );
is(
Koha::Library::Calendar::WeeklyClosures->search( { library_id => $library2->branchcode } )->count, 1,
'Weekly closure copied'
);
is(
Koha::Library::Calendar::RepeatingClosures->search( { library_id => $library2->branchcode } )->count, 1,
'Repeating closure copied'
);
is(
Koha::Library::Calendar::SingleClosures->search( { library_id => $library2->branchcode } )->count, 1,
'Only the future single closure copied (past single excluded)'
);
is(
Koha::Library::Calendar::Exceptions->search( { library_id => $library2->branchcode } )->count, 1,
'Only the future exception copied (past exception excluded)'
);
# copy_to should not duplicate on a second run
$calendar->copy_to( $library2->branchcode );
is(
Koha::Library::Calendar::WeeklyClosures->search( { library_id => $library2->branchcode } )->count, 1,
'No duplicate weekly after second copy'
);
is(
Koha::Library::Calendar::RepeatingClosures->search( { library_id => $library2->branchcode } )->count, 1,
'No duplicate repeating after second copy'
);
is(
Koha::Library::Calendar::SingleClosures->search( { library_id => $library2->branchcode } )->count, 1,
'No duplicate single after second copy'
);
is(
Koha::Library::Calendar::Exceptions->search( { library_id => $library2->branchcode } )->count, 1,
'No duplicate exception after second copy'
);
$schema->storage->txn_rollback;
};