Bug 42310: (QA follow-up) Fire per-row delete hooks in Koha::Calendar delete_* methods

The four delete_*_closure / delete_exception methods in Koha::Calendar
were calling ResultSet->delete, which issues a single bulk SQL DELETE
and never calls the row-level delete() override. The cache-invalidation
hooks on Koha::Calendar::SingleClosure->delete and
Koha::Calendar::Exception->delete were therefore skipped when callers
went through $library->calendar->delete_single_closure(...) or
delete_exception(...), and the <library>_holidays cache kept reporting
deleted dates as closed until its TTL expired.

The underlying tables enforce UNIQUE constraints on (library_id, weekday),
(library_id, day, month) and (library_id, date), so each search can
match at most one row. Switch the four methods to ->search({...},
{ rows => 1 })->single followed by ->delete on the row, which both
makes the single-row expectation explicit and ensures the per-row
delete override runs.

A regression test is added to t/db_dependent/Koha/Calendar.t asserting
that the _holidays cache is cleared after delete_single_closure and
delete_exception.

Test plan:
1) prove t/db_dependent/Koha/Calendar.t
2) Confirm the new 'delete_*_closure clears _holidays cache' subtest
   passes.

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:
Martin Renvoize 2026-04-17 07:30:42 +01:00 committed by Pedro Amorim
parent d4e4f57072
commit c3880a70e6
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
2 changed files with 50 additions and 7 deletions

View File

@ -445,27 +445,41 @@ sub add_exception {
sub delete_weekly_closure {
my ( $self, $params ) = @_;
Koha::Calendar::WeeklyClosures->search( { library_id => $self->{branchcode}, weekday => $params->{weekday} } )
->delete;
my $row = Koha::Calendar::WeeklyClosures->search(
{ library_id => $self->{branchcode}, weekday => $params->{weekday} },
{ rows => 1 }
)->single;
$row->delete if $row;
return $self;
}
sub delete_repeating_closure {
my ( $self, $params ) = @_;
Koha::Calendar::RepeatingClosures->search(
{ library_id => $self->{branchcode}, day => $params->{day}, month => $params->{month} } )->delete;
my $row = Koha::Calendar::RepeatingClosures->search(
{ library_id => $self->{branchcode}, day => $params->{day}, month => $params->{month} },
{ rows => 1 }
)->single;
$row->delete if $row;
return $self;
}
sub delete_single_closure {
my ( $self, $params ) = @_;
Koha::Calendar::SingleClosures->search( { library_id => $self->{branchcode}, date => $params->{date} } )->delete;
my $row = Koha::Calendar::SingleClosures->search(
{ library_id => $self->{branchcode}, date => $params->{date} },
{ rows => 1 }
)->single;
$row->delete if $row;
return $self;
}
sub delete_exception {
my ( $self, $params ) = @_;
Koha::Calendar::Exceptions->search( { library_id => $self->{branchcode}, date => $params->{date} } )->delete;
my $row = Koha::Calendar::Exceptions->search(
{ library_id => $self->{branchcode}, date => $params->{date} },
{ rows => 1 }
)->single;
$row->delete if $row;
return $self;
}

View File

@ -19,10 +19,11 @@
use Modern::Perl;
use Test::More tests => 4;
use Test::More tests => 5;
use Test::Exception;
use Test::NoWarnings;
use Koha::Caches;
use Koha::Database;
use Koha::DateUtils qw( dt_from_string );
use Koha::Calendar::WeeklyClosures;
@ -227,3 +228,31 @@ subtest 'CRUD methods' => sub {
$schema->storage->txn_rollback;
};
subtest 'delete_*_closure clears _holidays cache' => sub {
plan tests => 4;
$schema->storage->txn_begin;
my $library = $builder->build_object( { class => 'Koha::Libraries' } );
my $branchcode = $library->branchcode;
my $cache_key = $branchcode . '_holidays';
my $cache = Koha::Caches->get_instance;
my $calendar = Koha::Calendar->new( branchcode => $branchcode );
$calendar->add_single_closure( { date => '2027-07-04', title => 'Independence', description => '' } );
$calendar->is_holiday( dt_from_string('2027-07-04') ); # warm cache
ok( defined $cache->get_from_cache($cache_key), 'Cache warm after is_holiday (single)' );
$calendar->delete_single_closure( { date => '2027-07-04' } );
is( $cache->get_from_cache($cache_key), undef, 'Cache cleared after delete_single_closure' );
$calendar->add_exception( { date => '2027-07-05', title => 'Special open', description => '' } );
$calendar->is_holiday( dt_from_string('2027-07-05') ); # warm cache
ok( defined $cache->get_from_cache($cache_key), 'Cache warm after is_holiday (exception)' );
$calendar->delete_exception( { date => '2027-07-05' } );
is( $cache->get_from_cache($cache_key), undef, 'Cache cleared after delete_exception' );
$schema->storage->txn_rollback;
};