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 1625-1627
subtest '->set_password' => sub {
Link Here
|
1625 |
|
1625 |
|
1626 |
$schema->storage->txn_rollback; |
1626 |
$schema->storage->txn_rollback; |
1627 |
}; |
1627 |
}; |
1628 |
- |
1628 |
|
|
|
1629 |
$schema->storage->txn_begin; |
1630 |
subtest 'search_unsubscribed' => sub { |
1631 |
plan tests => 4; |
1632 |
|
1633 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 3 ); |
1634 |
t::lib::Mocks::mock_preference( 'UnsubscribeReflectionDelay', '' ); |
1635 |
is( Koha::Patrons->search_unsubscribed->count, 0, 'Empty delay should return empty set' ); |
1636 |
|
1637 |
my $patron1 = $builder->build_object({ class => 'Koha::Patrons' }); |
1638 |
my $patron2 = $builder->build_object({ class => 'Koha::Patrons' }); |
1639 |
|
1640 |
t::lib::Mocks::mock_preference( 'UnsubscribeReflectionDelay', 0 ); |
1641 |
Koha::Patron::Consents->delete; # for correct counts |
1642 |
Koha::Patron::Consent->new({ borrowernumber => $patron1->borrowernumber, type => 'GDPR_PROCESSING', refused_on => dt_from_string })->store; |
1643 |
is( Koha::Patrons->search_unsubscribed->count, 1, 'Find patron1' ); |
1644 |
|
1645 |
# Add another refusal but shift the period |
1646 |
t::lib::Mocks::mock_preference( 'UnsubscribeReflectionDelay', 2 ); |
1647 |
Koha::Patron::Consent->new({ borrowernumber => $patron2->borrowernumber, type => 'GDPR_PROCESSING', refused_on => dt_from_string->subtract(days=>2) })->store; |
1648 |
is( Koha::Patrons->search_unsubscribed->count, 1, 'Find patron2 only' ); |
1649 |
|
1650 |
# Try another (special) attempts setting |
1651 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 0 ); |
1652 |
# Lockout is now disabled |
1653 |
# Patron2 still matches: refused earlier, not locked |
1654 |
is( Koha::Patrons->search_unsubscribed->count, 1, 'Lockout disabled' ); |
1655 |
}; |
1656 |
|
1657 |
subtest 'search_anonymize_candidates' => sub { |
1658 |
plan tests => 5; |
1659 |
my $patron1 = $builder->build_object({ class => 'Koha::Patrons' }); |
1660 |
my $patron2 = $builder->build_object({ class => 'Koha::Patrons' }); |
1661 |
$patron1->flgAnonymized(0); |
1662 |
$patron1->dateexpiry( dt_from_string->add(days => 1) )->store; |
1663 |
$patron2->flgAnonymized(undef); |
1664 |
$patron2->dateexpiry( dt_from_string->add(days => 1) )->store; |
1665 |
|
1666 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', q{} ); |
1667 |
is( Koha::Patrons->search_anonymize_candidates->count, 0, 'Empty set' ); |
1668 |
|
1669 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', 0 ); |
1670 |
my $cnt = Koha::Patrons->search_anonymize_candidates->count; |
1671 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1672 |
$patron2->dateexpiry( dt_from_string->subtract(days => 3) )->store; |
1673 |
is( Koha::Patrons->search_anonymize_candidates->count, $cnt+2, 'Delay 0' ); |
1674 |
|
1675 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', 2 ); |
1676 |
$patron1->dateexpiry( dt_from_string->add(days => 1) )->store; |
1677 |
$patron2->dateexpiry( dt_from_string->add(days => 1) )->store; |
1678 |
$cnt = Koha::Patrons->search_anonymize_candidates->count; |
1679 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1680 |
$patron2->dateexpiry( dt_from_string->subtract(days => 3) )->store; |
1681 |
is( Koha::Patrons->search_anonymize_candidates->count, $cnt+1, 'Delay 2' ); |
1682 |
|
1683 |
t::lib::Mocks::mock_preference( 'PatronAnonymizeDelay', 4 ); |
1684 |
$patron1->dateexpiry( dt_from_string->add(days => 1) )->store; |
1685 |
$patron2->dateexpiry( dt_from_string->add(days => 1) )->store; |
1686 |
$cnt = Koha::Patrons->search_anonymize_candidates->count; |
1687 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1688 |
$patron2->dateexpiry( dt_from_string->subtract(days => 3) )->store; |
1689 |
is( Koha::Patrons->search_anonymize_candidates->count, $cnt, 'Delay 4' ); |
1690 |
|
1691 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 3 ); |
1692 |
$patron1->dateexpiry( dt_from_string->subtract(days => 5) )->store; |
1693 |
$patron1->login_attempts(0)->store; |
1694 |
$patron2->dateexpiry( dt_from_string->subtract(days => 5) )->store; |
1695 |
$patron2->login_attempts(0)->store; |
1696 |
$cnt = Koha::Patrons->search_anonymize_candidates({locked => 1})->count; |
1697 |
$patron1->login_attempts(3)->store; |
1698 |
is( Koha::Patrons->search_anonymize_candidates({locked => 1})->count, |
1699 |
$cnt+1, 'Locked flag' ); |
1700 |
}; |
1701 |
|
1702 |
subtest 'search_anonymized' => sub { |
1703 |
plan tests => 3; |
1704 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1705 |
|
1706 |
t::lib::Mocks::mock_preference( 'PatronRemovalDelay', q{} ); |
1707 |
is( Koha::Patrons->search_anonymized->count, 0, 'Empty set' ); |
1708 |
|
1709 |
t::lib::Mocks::mock_preference( 'PatronRemovalDelay', 1 ); |
1710 |
$patron1->dateexpiry( dt_from_string ); |
1711 |
$patron1->flgAnonymized(0)->store; |
1712 |
my $cnt = Koha::Patrons->search_anonymized->count; |
1713 |
$patron1->flgAnonymized(1)->store; |
1714 |
is( Koha::Patrons->search_anonymized->count, $cnt, 'Number unchanged' ); |
1715 |
$patron1->dateexpiry( dt_from_string->subtract(days => 1) )->store; |
1716 |
is( Koha::Patrons->search_anonymized->count, $cnt+1, 'Found patron1' ); |
1717 |
}; |
1718 |
|
1719 |
subtest 'lock' => sub { |
1720 |
plan tests => 8; |
1721 |
|
1722 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1723 |
my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1724 |
my $hold = $builder->build_object({ |
1725 |
class => 'Koha::Holds', |
1726 |
value => { borrowernumber => $patron1->borrowernumber }, |
1727 |
}); |
1728 |
|
1729 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', 3 ); |
1730 |
my $expiry = dt_from_string->add(days => 1); |
1731 |
$patron1->dateexpiry( $expiry ); |
1732 |
$patron1->lock; |
1733 |
is( $patron1->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts' ); |
1734 |
is( $patron1->dateexpiry, $expiry, 'Not expired yet' ); |
1735 |
is( $patron1->holds->count, 1, 'No holds removed' ); |
1736 |
|
1737 |
$patron1->lock({ expire => 1, remove => 1}); |
1738 |
isnt( $patron1->dateexpiry, $expiry, 'Expiry date adjusted' ); |
1739 |
is( $patron1->holds->count, 0, 'Holds removed' ); |
1740 |
|
1741 |
# Disable lockout feature |
1742 |
t::lib::Mocks::mock_preference( 'FailedLoginAttempts', q{} ); |
1743 |
$patron1->login_attempts(0); |
1744 |
$patron1->dateexpiry( $expiry ); |
1745 |
$patron1->store; |
1746 |
$patron1->lock; |
1747 |
is( $patron1->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts' ); |
1748 |
|
1749 |
# Trivial wrapper test (Koha::Patrons->lock) |
1750 |
$patron1->login_attempts(0)->store; |
1751 |
Koha::Patrons->search({ borrowernumber => [ $patron1->borrowernumber, $patron2->borrowernumber ] })->lock; |
1752 |
$patron1->discard_changes; # refresh |
1753 |
$patron2->discard_changes; |
1754 |
is( $patron1->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts patron 1' ); |
1755 |
is( $patron2->login_attempts, Koha::Patron::ADMINISTRATIVE_LOCKOUT, 'Check login_attempts patron 2' ); |
1756 |
}; |
1757 |
|
1758 |
subtest 'anonymize' => sub { |
1759 |
plan tests => 9; |
1760 |
|
1761 |
my $patron1 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1762 |
my $patron2 = $builder->build_object( { class => 'Koha::Patrons' } ); |
1763 |
|
1764 |
# First try patron with issues |
1765 |
my $issue = $builder->build_object({ class => 'Koha::Checkouts', value => { borrowernumber => $patron2->borrowernumber } }); |
1766 |
warning_like { $patron2->anonymize } qr/still has issues/, 'Skip patron with issues'; |
1767 |
$issue->delete; |
1768 |
|
1769 |
t::lib::Mocks::mock_preference( 'BorrowerMandatoryField', 'surname|email|cardnumber' ); |
1770 |
my $surname = $patron1->surname; # expect change, no clear |
1771 |
my $branchcode = $patron1->branchcode; # expect skip |
1772 |
$patron1->anonymize; |
1773 |
is($patron1->flgAnonymized, 1, 'Check flag' ); |
1774 |
|
1775 |
is( $patron1->dateofbirth, undef, 'Birth date cleared' ); |
1776 |
is( $patron1->firstname, undef, 'First name cleared' ); |
1777 |
isnt( $patron1->surname, $surname, 'Surname changed' ); |
1778 |
ok( $patron1->surname =~ /^\w{10}$/, 'Mandatory surname randomized' ); |
1779 |
is( $patron1->branchcode, $branchcode, 'Branch code skipped' ); |
1780 |
|
1781 |
# Test wrapper in Koha::Patrons |
1782 |
$patron1->surname($surname)->store; # restore |
1783 |
my $rs = Koha::Patrons->search({ borrowernumber => [ $patron1->borrowernumber, $patron2->borrowernumber ] })->anonymize; |
1784 |
$patron1->discard_changes; # refresh |
1785 |
isnt( $patron1->surname, $surname, 'Surname patron1 changed again' ); |
1786 |
$patron2->discard_changes; # refresh |
1787 |
is( $patron2->firstname, undef, 'First name patron2 cleared' ); |
1788 |
}; |
1789 |
$schema->storage->txn_rollback; |