Bug 42868: (follow-up) Add regression test for non-UTC library timezone
The bug this fixed only manifests when the library's configured timezone (C4::Context->tz) is not UTC: Koha::Object::_recursive_fixup converts an incoming RFC3339 instant to that timezone before storing it in the timezone-naive 'bookings.start_date'/'end_date' columns, so a UTC-anchored boundary shifts by the timezone offset on write. None of the existing Cypress specs catch this, because they never run with the browser/test-runner timezone diverging from the configured library timezone - both always come from the same container clock. Add a Perl-level API test that mocks C4::Context->tz to a non-UTC zone (America/New_York) and asserts the boundaries sent by place_booking.js round-trip to the correct library-local date, pinning this regression independently of any particular environment's timezone. Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
parent
5a7c328475
commit
111637445a
|
|
@ -18,8 +18,9 @@
|
|||
use Modern::Perl;
|
||||
|
||||
use Test::NoWarnings;
|
||||
use Test::More tests => 8;
|
||||
use Test::More tests => 9;
|
||||
use Test::Mojo;
|
||||
use Test::MockModule;
|
||||
use Test::Warn;
|
||||
|
||||
use t::lib::TestBuilder;
|
||||
|
|
@ -654,3 +655,77 @@ subtest 'add() with itemtype_id tests' => sub {
|
|||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'add() applies the library timezone to start_date/end_date (Bug 42868)' => sub {
|
||||
|
||||
plan tests => 4;
|
||||
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
# Regression test for Bug 42868: the API converts the incoming RFC3339
|
||||
# instant to C4::Context->tz before storing it in the timezone-naive
|
||||
# 'datetime' column (see Koha::Object::_recursive_fixup), so a client
|
||||
# must anchor day boundaries to the library's configured timezone, not
|
||||
# UTC, or the stored date shifts whenever that timezone isn't UTC.
|
||||
my $context = Test::MockModule->new('C4::Context');
|
||||
$context->mock( 'tz', sub { 'America/New_York' } );
|
||||
|
||||
my $librarian = $builder->build_object(
|
||||
{
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 } # no additional permissions
|
||||
}
|
||||
);
|
||||
$builder->build(
|
||||
{
|
||||
source => 'UserPermission',
|
||||
value => {
|
||||
borrowernumber => $librarian->borrowernumber,
|
||||
module_bit => 1,
|
||||
code => 'manage_bookings',
|
||||
},
|
||||
}
|
||||
);
|
||||
my $password = 'thePassword123';
|
||||
$librarian->set_password( { password => $password, skip_validation => 1 } );
|
||||
my $userid = $librarian->userid;
|
||||
|
||||
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
|
||||
my $biblio = $builder->build_sample_biblio;
|
||||
my $item = $builder->build_sample_item( { bookable => 1, biblionumber => $biblio->id } );
|
||||
my $pickup_library = $builder->build_object( { class => 'Koha::Libraries' } );
|
||||
|
||||
# 2026-07-01T00:00:00 and 2026-07-01T23:59:59 in America/New_York (EDT, UTC-4) -
|
||||
# exactly what place_booking.js sends via dayjs.tz(date, $timezone()).
|
||||
my $booking = {
|
||||
biblio_id => $biblio->id,
|
||||
item_id => $item->itemnumber,
|
||||
pickup_library_id => $pickup_library->branchcode,
|
||||
patron_id => $patron->id,
|
||||
start_date => '2026-07-01T04:00:00Z',
|
||||
end_date => '2026-07-02T03:59:59Z',
|
||||
};
|
||||
|
||||
my $booking_id =
|
||||
$t->post_ok( "//$userid:$password@/api/v1/bookings" => json => $booking )
|
||||
->status_is(201)
|
||||
->tx->res->json->{booking_id};
|
||||
|
||||
my ( $start_date, $end_date ) = $schema->storage->dbh->selectrow_array(
|
||||
q{SELECT start_date, end_date FROM bookings WHERE booking_id = ?},
|
||||
undef, $booking_id
|
||||
);
|
||||
|
||||
is(
|
||||
$start_date, '2026-07-01 00:00:00',
|
||||
'start_date is stored as library-local midnight, not shifted by the UTC offset'
|
||||
);
|
||||
is(
|
||||
$end_date, '2026-07-01 23:59:59',
|
||||
'end_date is stored as library-local end of day, not shifted by the UTC offset'
|
||||
);
|
||||
|
||||
$context->unmock('tz');
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue