View | Details | Raw Unified | Return to bug 40636
Collapse All | Expand All

(-)a/t/db_dependent/Reserves/CancelExpiredReserves.t (-10 / +155 lines)
Lines 1-9 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
use Test::More tests => 5;
4
use Test::More tests => 6;
5
use Test::NoWarnings;
5
use Test::NoWarnings;
6
use Test::MockModule;
6
use Test::MockModule;
7
use Time::Fake;
7
8
8
use t::lib::Mocks;
9
use t::lib::Mocks;
9
use t::lib::TestBuilder;
10
use t::lib::TestBuilder;
Lines 15-28 use Koha::DateUtils qw( dt_from_string ); Link Here
15
use Koha::Holds;
16
use Koha::Holds;
16
use Koha::Old::Holds;
17
use Koha::Old::Holds;
17
18
18
my $schema = Koha::Database->new->schema;
19
my $builder = t::lib::TestBuilder->new();
20
my $schema  = Koha::Database->new->schema;
21
19
$schema->storage->txn_begin;
22
$schema->storage->txn_begin;
20
23
21
subtest 'CancelExpiredReserves tests incl. holidays' => sub {
24
subtest 'CancelExpiredReserves tests incl. holidays' => sub {
22
    plan tests => 4;
25
    plan tests => 4;
23
26
24
    my $builder = t::lib::TestBuilder->new();
25
26
    t::lib::Mocks::mock_preference( 'ExpireReservesOnHolidays', 0 );
27
    t::lib::Mocks::mock_preference( 'ExpireReservesOnHolidays', 0 );
27
28
28
    # Waiting holds could be cancelled only if ExpireReservesMaxPickUpDelay is set to "allow", see bug 19260
29
    # Waiting holds could be cancelled only if ExpireReservesMaxPickUpDelay is set to "allow", see bug 19260
Lines 119-125 subtest 'Test handling of waiting reserves by CancelExpiredReserves' => sub { Link Here
119
120
120
    Koha::Holds->delete;
121
    Koha::Holds->delete;
121
122
122
    my $builder        = t::lib::TestBuilder->new();
123
    my $category       = $builder->build( { source => 'Category' } );
123
    my $category       = $builder->build( { source => 'Category' } );
124
    my $branchcode     = $builder->build( { source => 'Branch' } )->{branchcode};
124
    my $branchcode     = $builder->build( { source => 'Branch' } )->{branchcode};
125
    my $item           = $builder->build_sample_item;
125
    my $item           = $builder->build_sample_item;
Lines 184-191 subtest 'Test handling of waiting reserves by CancelExpiredReserves' => sub { Link Here
184
subtest 'Test handling of in transit reserves by CancelExpiredReserves' => sub {
184
subtest 'Test handling of in transit reserves by CancelExpiredReserves' => sub {
185
    plan tests => 2;
185
    plan tests => 2;
186
186
187
    my $builder = t::lib::TestBuilder->new();
188
189
    t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
187
    t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
190
    my $expdate = dt_from_string->add( days => -2 );
188
    my $expdate = dt_from_string->add( days => -2 );
191
    my $reserve = $builder->build(
189
    my $reserve = $builder->build(
Lines 225-232 subtest 'Test handling of in transit reserves by CancelExpiredReserves' => sub { Link Here
225
subtest 'Test handling of cancellation reason if passed' => sub {
223
subtest 'Test handling of cancellation reason if passed' => sub {
226
    plan tests => 2;
224
    plan tests => 2;
227
225
228
    my $builder = t::lib::TestBuilder->new();
229
230
    my $expdate = dt_from_string->add( days => -2 );
226
    my $expdate = dt_from_string->add( days => -2 );
231
    my $reserve = $builder->build(
227
    my $reserve = $builder->build(
232
        {
228
        {
Lines 254-257 subtest 'Test handling of cancellation reason if passed' => sub { Link Here
254
    is( $old_reserve->cancellation_reason, 'EXPIRED', "Hold cancellation_reason was set correctly" );
250
    is( $old_reserve->cancellation_reason, 'EXPIRED', "Hold cancellation_reason was set correctly" );
255
};
251
};
256
252
253
subtest 'Holiday logic edge cases' => sub {
254
255
    plan tests => 2;
256
257
    subtest 'Hold expired on business day should be cancelled retrospectively when script runs on holiday' => sub {
258
        plan tests => 1;
259
260
        $schema->storage->txn_begin;
261
262
        t::lib::Mocks::mock_preference( 'ExpireReservesOnHolidays',     0 );
263
        t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
264
265
        # Clear any existing holidays from previous tests
266
        Koha::Caches->get_instance()->flush_all();
267
268
        # Create a library for our tests
269
        my $library = $builder->build_object( { class => 'Koha::Libraries' } );
270
271
        # The bug scenario: Hold expired on Monday (business day), script runs on Wednesday (holiday)
272
        # The hold SHOULD be cancelled because it expired on a business day and Tuesday was a business day
273
        # that was missed, so we need retrospective cancellation even though today is a holiday
274
275
        my $monday    = dt_from_string('2024-01-15');    # Monday (business day, hold expires)
276
        my $wednesday = dt_from_string('2024-01-17');    # Wednesday (holiday, script runs now)
277
278
        # Create a hold that expired on Monday (business day)
279
        my $hold_expired_monday = $builder->build_object(
280
            {
281
                class => 'Koha::Holds',
282
                value => {
283
                    branchcode             => $library->branchcode,
284
                    patron_expiration_date => $monday->ymd,
285
                    expirationdate         => $monday->ymd,
286
                    cancellationdate       => undef,
287
                    priority               => 0,
288
                    found                  => 'W',
289
                },
290
            }
291
        );
292
293
        # Make Wednesday a holiday (but Monday and Tuesday are business days)
294
        my $wednesday_holiday = $builder->build(
295
            {
296
                source => 'SpecialHoliday',
297
                value  => {
298
                    branchcode  => $library->branchcode,
299
                    day         => $wednesday->day,
300
                    month       => $wednesday->month,
301
                    year        => $wednesday->year,
302
                    title       => 'Wednesday Holiday',
303
                    isexception => 0
304
                },
305
            }
306
        );
307
308
        # Clear cache so holiday is recognized
309
        Koha::Caches->get_instance()->flush_all();
310
311
        # Set fake time to Wednesday (holiday)
312
        Time::Fake->offset( $wednesday->epoch );
313
314
        # The hold SHOULD be cancelled because:
315
        # 1. It expired on Monday (business day)
316
        # 2. Tuesday was a business day that was missed
317
        # 3. Even though today (Wednesday) is a holiday, we need retrospective cancellation
318
        CancelExpiredReserves();
319
320
        my $hold_check = Koha::Holds->find( $hold_expired_monday->id );
321
        is(
322
            $hold_check, undef,
323
            'Hold that expired on business day should be cancelled retrospectively even when script runs on holiday'
324
        );
325
326
        # Reset time
327
        Time::Fake->reset;
328
329
        $schema->storage->txn_rollback;
330
    };
331
332
    subtest 'Hold expired on holiday should not be cancelled when script runs on same holiday' => sub {
333
        plan tests => 1;
334
335
        $schema->storage->txn_begin;
336
337
        t::lib::Mocks::mock_preference( 'ExpireReservesOnHolidays',     0 );
338
        t::lib::Mocks::mock_preference( 'ExpireReservesMaxPickUpDelay', 1 );
339
340
        # Clear any existing holidays from previous tests
341
        Koha::Caches->get_instance()->flush_all();
342
343
        # Create a library for our tests
344
        my $library = $builder->build_object( { class => 'Koha::Libraries' } );
345
346
        # Control scenario: Hold expired on Monday (holiday), script runs on Monday (same holiday)
347
        # The hold should NOT be cancelled because it expired today and today is a holiday
348
349
        my $monday = dt_from_string('2024-01-15');    # Monday (holiday, hold expires and script runs)
350
351
        # Create a hold that expired on Monday (holiday)
352
        my $hold_expired_monday = $builder->build_object(
353
            {
354
                class => 'Koha::Holds',
355
                value => {
356
                    branchcode             => $library->branchcode,
357
                    patron_expiration_date => $monday->ymd,
358
                    expirationdate         => $monday->ymd,
359
                    cancellationdate       => undef,
360
                    priority               => 0,
361
                    found                  => 'W',
362
                },
363
            }
364
        );
365
366
        # Make Monday a holiday
367
        my $monday_holiday = $builder->build(
368
            {
369
                source => 'SpecialHoliday',
370
                value  => {
371
                    branchcode  => $library->branchcode,
372
                    day         => $monday->day,
373
                    month       => $monday->month,
374
                    year        => $monday->year,
375
                    title       => 'Monday Holiday',
376
                    isexception => 0
377
                },
378
            }
379
        );
380
381
        # Clear cache so holiday is recognized
382
        Koha::Caches->get_instance()->flush_all();
383
384
        # Set fake time to Monday (holiday)
385
        Time::Fake->offset( $monday->epoch );
386
387
        # The hold should NOT be cancelled because it expired today and today is a holiday
388
        CancelExpiredReserves();
389
390
        my $hold_check = Koha::Holds->find( $hold_expired_monday->id );
391
        ok(
392
            $hold_check,
393
            'Hold that expired on holiday should not be cancelled when script runs on same holiday'
394
        );
395
396
        # Reset time
397
        Time::Fake->reset;
398
399
        $schema->storage->txn_rollback;
400
    };
401
};
402
257
$schema->storage->txn_rollback;
403
$schema->storage->txn_rollback;
258
- 

Return to bug 40636