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