Lines 19-25
Link Here
|
19 |
|
19 |
|
20 |
use Modern::Perl; |
20 |
use Modern::Perl; |
21 |
|
21 |
|
22 |
use Test::More tests => 33; |
22 |
use Test::More tests => 38; |
23 |
use Test::Warn; |
23 |
use Test::Warn; |
24 |
use Test::Exception; |
24 |
use Test::Exception; |
25 |
use Test::MockModule; |
25 |
use Test::MockModule; |
Lines 1452-1457
subtest 'Log cardnumber change' => sub {
Link Here
|
1452 |
is( scalar @logs, 2, 'With BorrowerLogs, Change in cardnumber should be logged, as well as general alert of patron mod.' ); |
1452 |
is( scalar @logs, 2, 'With BorrowerLogs, Change in cardnumber should be logged, as well as general alert of patron mod.' ); |
1453 |
}; |
1453 |
}; |
1454 |
|
1454 |
|
|
|
1455 |
subtest 'search_unsubscribed' => sub { |
1456 |
plan tests => 4; |
1457 |
|
1458 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 3 ); |
1459 |
t::lib::Mocks::mock_preference( 'UnsubscribeReflectionDelay', '' ); |
1460 |
is( Koha::Patrons->search_unsubscribed->count, 0, 'Empty delay should return empty set' ); |
1461 |
|
1462 |
my $patron1 = $builder->build_object({ class => 'Koha::Patrons' }); |
1463 |
my $patron2 = $builder->build_object({ class => 'Koha::Patrons' }); |
1464 |
|
1465 |
t::lib::Mocks::mock_preference( 'UnsubscribeReflectionDelay', 0 ); |
1466 |
Koha::Patron::Consents->delete; # for correct counts |
1467 |
Koha::Patron::Consent->new({ borrowernumber => $patron1->borrowernumber, type => 'GDPR_PROCESSING', refused_on => dt_from_string })->store; |
1468 |
is( Koha::Patrons->search_unsubscribed->count, 1, 'Find patron1' ); |
1469 |
|
1470 |
# Add another refusal but shift the period |
1471 |
t::lib::Mocks::mock_preference( 'UnsubscribeReflectionDelay', 2 ); |
1472 |
Koha::Patron::Consent->new({ borrowernumber => $patron2->borrowernumber, type => 'GDPR_PROCESSING', refused_on => dt_from_string->subtract(days=>2) })->store; |
1473 |
is( Koha::Patrons->search_unsubscribed->count, 1, 'Find patron2 only' ); |
1474 |
|
1475 |
# Try another (special) attempts setting |
1476 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 0 ); |
1477 |
# Lockout is now disabled |
1478 |
# Patron2 still matches: refused earlier, not locked |
1479 |
is( Koha::Patrons->search_unsubscribed->count, 1, 'Lockout disabled' ); |
1480 |
}; |
1481 |
|
1482 |
subtest 'search_anonymize_candidates' => sub { |
1483 |
plan tests => 5; |
1484 |
my $patron1 = $builder->build_object({ class => 'Koha::Patrons' }); |
1485 |
my $patron2 = $builder->build_object({ class => 'Koha::Patrons' }); |
1486 |
$patron1->flgAnonymized(0); |
1487 |
$patron1->dateexpiry( dt_from_string->add(days => 1) )->store; |
1488 |
$patron2->flgAnonymized(undef); |
1489 |
$patron2->dateexpiry( dt_from_string->add(days => 1) )->store; |
1490 |
|
1491 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', q{} ); |
1492 |
is( Koha::Patrons->search_anonymize_candidates->count, 0, 'Empty set' ); |
1493 |
|
1494 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', 0 ); |
1495 |
my $cnt = Koha::Patrons->search_anonymize_candidates->count; |
1496 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1497 |
$patron2->dateexpiry( dt_from_string->subtract(days => 3) )->store; |
1498 |
is( Koha::Patrons->search_anonymize_candidates->count, $cnt+2, 'Delay 0' ); |
1499 |
|
1500 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', 2 ); |
1501 |
$patron1->dateexpiry( dt_from_string->add(days => 1) )->store; |
1502 |
$patron2->dateexpiry( dt_from_string->add(days => 1) )->store; |
1503 |
$cnt = Koha::Patrons->search_anonymize_candidates->count; |
1504 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1505 |
$patron2->dateexpiry( dt_from_string->subtract(days => 3) )->store; |
1506 |
is( Koha::Patrons->search_anonymize_candidates->count, $cnt+1, 'Delay 2' ); |
1507 |
|
1508 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', 4 ); |
1509 |
$patron1->dateexpiry( dt_from_string->add(days => 1) )->store; |
1510 |
$patron2->dateexpiry( dt_from_string->add(days => 1) )->store; |
1511 |
$cnt = Koha::Patrons->search_anonymize_candidates->count; |
1512 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1513 |
$patron2->dateexpiry( dt_from_string->subtract(days => 3) )->store; |
1514 |
is( Koha::Patrons->search_anonymize_candidates->count, $cnt, 'Delay 4' ); |
1515 |
|
1516 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 3 ); |
1517 |
$patron1->dateexpiry( dt_from_string->subtract(days => 5) )->store; |
1518 |
$patron1->login_attempts(0)->store; |
1519 |
$patron2->dateexpiry( dt_from_string->subtract(days => 5) )->store; |
1520 |
$patron2->login_attempts(0)->store; |
1521 |
$cnt = Koha::Patrons->search_anonymize_candidates({locked => 1})->count; |
1522 |
$patron1->login_attempts(3)->store; |
1523 |
is( Koha::Patrons->search_anonymize_candidates({locked => 1})->count, |
1524 |
$cnt+1, 'Locked flag' ); |
1525 |
}; |
1526 |
|
1527 |
subtest 'search_anonymized' => sub { |
1528 |
plan tests => 3; |
1529 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1530 |
|
1531 |
t::lib::Mocks::mock_preference( 'PatronRemovalDelay', q{} ); |
1532 |
is( Koha::Patrons->search_anonymized->count, 0, 'Empty set' ); |
1533 |
|
1534 |
t::lib::Mocks::mock_preference( 'PatronRemovalDelay', 1 ); |
1535 |
$patron1->dateexpiry( dt_from_string ); |
1536 |
$patron1->flgAnonymized(0)->store; |
1537 |
my $cnt = Koha::Patrons->search_anonymized->count; |
1538 |
$patron1->flgAnonymized(1)->store; |
1539 |
is( Koha::Patrons->search_anonymized->count, $cnt, 'Number unchanged' ); |
1540 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1541 |
is( Koha::Patrons->search_anonymized->count, $cnt+1, 'Found patron1' ); |
1542 |
}; |
1543 |
|
1544 |
subtest 'lock' => sub { |
1545 |
plan tests => 8; |
1546 |
|
1547 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1548 |
my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1549 |
my $hold = $builder->build_object({ |
1550 |
class => 'Koha::Holds', |
1551 |
value => { borrowernumber => $patron1->borrowernumber }, |
1552 |
}); |
1553 |
|
1554 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 3 ); |
1555 |
my $expiry = dt_from_string->add(days => 1); |
1556 |
$patron1->dateexpiry( $expiry ); |
1557 |
$patron1->lock; |
1558 |
is( $patron1->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts' ); |
1559 |
is( $patron1->dateexpiry, $expiry, 'Not expired yet' ); |
1560 |
is( $patron1->holds->count, 1, 'No holds removed' ); |
1561 |
|
1562 |
$patron1->lock({ expire => 1, remove => 1}); |
1563 |
isnt( $patron1->dateexpiry, $expiry, 'Expiry date adjusted' ); |
1564 |
is( $patron1->holds->count, 0, 'Holds removed' ); |
1565 |
|
1566 |
# Disable lockout feature |
1567 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', q{} ); |
1568 |
$patron1->login_attempts(0); |
1569 |
$patron1->dateexpiry( $expiry ); |
1570 |
$patron1->store; |
1571 |
$patron1->lock; |
1572 |
is( $patron1->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts' ); |
1573 |
|
1574 |
# Trivial wrapper test (Koha::Patrons->lock) |
1575 |
$patron1->login_attempts(0)->store; |
1576 |
Koha::Patrons->search({ borrowernumber => [ $patron1->borrowernumber, $patron2->borrowernumber ] })->lock; |
1577 |
$patron1->discard_changes; # refresh |
1578 |
$patron2->discard_changes; |
1579 |
is( $patron1->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts patron 1' ); |
1580 |
is( $patron2->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts patron 2' ); |
1581 |
}; |
1582 |
|
1583 |
subtest 'anonymize' => sub { |
1584 |
plan tests => 9; |
1585 |
|
1586 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1587 |
my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1588 |
|
1589 |
# First try patron with issues |
1590 |
my $issue = $builder->build_object({ class => 'Koha::Checkouts', value => { borrowernumber => $patron2->borrowernumber } }); |
1591 |
warning_like { $patron2->anonymize } qr/still has issues/, 'Skip patron with issues'; |
1592 |
$issue->delete; |
1593 |
|
1594 |
t::lib::Mocks::mock_preference( 'BorrowerMandatoryField', 'surname|email|cardnumber' ); |
1595 |
my $surname = $patron1->surname; # expect change, no clear |
1596 |
my $branchcode = $patron1->branchcode; # expect skip |
1597 |
$patron1->anonymize; |
1598 |
is($patron1->flgAnonymized, 1, 'Check flag' ); |
1599 |
|
1600 |
is( $patron1->dateofbirth, undef, 'Birth date cleared' ); |
1601 |
is( $patron1->firstname, undef, 'First name cleared' ); |
1602 |
isnt( $patron1->surname, $surname, 'Surname changed' ); |
1603 |
ok( $patron1->surname =~ /^\w{10}$/, 'Mandatory surname randomized' ); |
1604 |
is( $patron1->branchcode, $branchcode, 'Branch code skipped' ); |
1605 |
|
1606 |
# Test wrapper in Koha::Patrons |
1607 |
$patron1->surname($surname)->store; # restore |
1608 |
my $rs = Koha::Patrons->search({ borrowernumber => [ $patron1->borrowernumber, $patron2->borrowernumber ] })->anonymize; |
1609 |
$patron1->discard_changes; # refresh |
1610 |
isnt( $patron1->surname, $surname, 'Surname patron1 changed again' ); |
1611 |
$patron2->discard_changes; # refresh |
1612 |
is( $patron2->firstname, undef, 'First name patron2 cleared' ); |
1613 |
}; |
1614 |
|
1455 |
$schema->storage->txn_rollback; |
1615 |
$schema->storage->txn_rollback; |
1456 |
|
1616 |
|
1457 |
subtest 'Test Koha::Patrons::merge' => sub { |
1617 |
subtest 'Test Koha::Patrons::merge' => sub { |
1458 |
- |
|
|