From cf14f6f84497e46e9b880dbbe26075ba3673b4e4 Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Tue, 14 Mar 2023 20:02:10 +0000 Subject: [PATCH] Bug 33229: Clear patron reading history when privacy is set to never This patch adds a check to patron store routine. When privacy is changed to 'Never' we should immediately clear their history To test: 1 - Set system preferences: AnonymousPatron - to a valid borrowernumber OPACPrivacy - Allow 2 - Checkout some items to a patron with priacy set to default, return them 3 - Log in to opac as patron 4 - Confirm you can see your history 5 - Change history to Never 6 - Confirm history still viewable 7 - Apply patch, restart all 8 - Set privacy to Default 9 - Confirm you can still see history, not deleted when not set as Never 10 - Set privacy to 'Never' 11 - Confirm history is anonymized Signed-off-by: Sally Signed-off-by: Jonathan Druart Signed-off-by: Tomas Cohen Arazi (cherry picked from commit 7c45fc8bdfefb27a1d6f214c2906190bca1d628a) --- Koha/Exceptions/Patron.pm | 4 ++ Koha/Patron.pm | 16 +++++++ t/db_dependent/Koha/Patron.t | 82 +++++++++++++++++++++++++++++++++++- 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/Koha/Exceptions/Patron.pm b/Koha/Exceptions/Patron.pm index 596f28c94c..52fb6c69b6 100644 --- a/Koha/Exceptions/Patron.pm +++ b/Koha/Exceptions/Patron.pm @@ -15,6 +15,10 @@ use Exception::Class ( isa => 'Koha::Exceptions::Patron', description => "Deleting patron failed" }, + 'Koha::Exceptions::Patron::FailedAnonymizing' => { + isa => 'Koha::Exceptions::Patron', + description => "Anonymizing patron reading history failed" + }, 'Koha::Exceptions::Patron::FailedDeleteAnonymousPatron' => { isa => 'Koha::Exceptions::Patron', description => "Deleting patron failed, AnonymousPatron is not deleteable" diff --git a/Koha/Patron.pm b/Koha/Patron.pm index e027e0ce19..8efc749ef0 100644 --- a/Koha/Patron.pm +++ b/Koha/Patron.pm @@ -298,6 +298,22 @@ sub store { $self->userid($stored_userid); } + # If a borrower has set their privacy to never we should immediately anonymize + # their checkouts + if( $self->privacy() == 2 && $self_from_storage->privacy() != 2 ){ + try{ + my $schema = Koha::Database->new()->schema(); + $schema->txn_do( + sub { $self->old_checkouts->anonymize; } + ); + } + catch { + Koha::Exceptions::Patron::FailedAnonymizing->throw( + error => @_ + ); + }; + } + # Password must be updated using $self->set_password $self->password($self_from_storage->password); diff --git a/t/db_dependent/Koha/Patron.t b/t/db_dependent/Koha/Patron.t index e92b054d86..249c9ccfc8 100755 --- a/t/db_dependent/Koha/Patron.t +++ b/t/db_dependent/Koha/Patron.t @@ -19,7 +19,7 @@ use Modern::Perl; -use Test::More tests => 19; +use Test::More tests => 21; use Test::Exception; use Test::Warn; @@ -1349,3 +1349,83 @@ subtest 'notify_library_of_registration()' => sub { $schema->storage->txn_rollback; }; + +subtest 'get_savings tests' => sub { + + plan tests => 4; + + $schema->storage->txn_begin; + + my $library = $builder->build_object({ class => 'Koha::Libraries' }); + my $patron = $builder->build_object({ class => 'Koha::Patrons' }, { value => { branchcode => $library->branchcode } }); + + t::lib::Mocks::mock_userenv({ patron => $patron, branchcode => $library->branchcode }); + + my $biblio = $builder->build_sample_biblio; + my $item1 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + library => $library->branchcode, + replacementprice => rand(20), + } + ); + my $item2 = $builder->build_sample_item( + { + biblionumber => $biblio->biblionumber, + library => $library->branchcode, + replacementprice => rand(20), + } + ); + + is( $patron->get_savings, 0, 'No checkouts, no savings' ); + + # Add an old checkout with deleted itemnumber + $builder->build_object({ class => 'Koha::Old::Checkouts', value => { itemnumber => undef, borrowernumber => $patron->id } }); + + is( $patron->get_savings, 0, 'No checkouts with itemnumber, no savings' ); + + AddIssue( $patron->unblessed, $item1->barcode ); + AddIssue( $patron->unblessed, $item2->barcode ); + + my $savings = $patron->get_savings; + is( $savings + 0, $item1->replacementprice + $item2->replacementprice, "Savings correctly calculated from current issues" ); + + AddReturn( $item2->barcode, $item2->homebranch ); + + $savings = $patron->get_savings; + is( $savings + 0, $item1->replacementprice + $item2->replacementprice, "Savings correctly calculated from current and old issues" ); + + $schema->storage->txn_rollback; +}; + +subtest 'update privacy tests' => sub { + + plan tests => 5; + + my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { privacy => 1 } }); + + my $old_checkout = $builder->build_object({ class => 'Koha::Old::Checkouts', value => { borrowernumber => $patron->id } }); + + t::lib::Mocks::mock_preference( 'AnonymousPatron', '0' ); + + $patron->privacy(2); #set to never + + throws_ok{ $patron->store } 'Koha::Exceptions::Patron::FailedAnonymizing', 'We throw an exception when anonymizing fails'; + + $old_checkout->discard_changes; #refresh from db + $patron->discard_changes; + + is( $old_checkout->borrowernumber, $patron->id, "When anonymizing fails, we don't clear the checkouts"); + is( $patron->privacy(), 1, "When anonymizing fails, we don't chaneg the privacy"); + + my $anon_patron = $builder->build_object({ class => 'Koha::Patrons'}); + t::lib::Mocks::mock_preference( 'AnonymousPatron', $anon_patron->id ); + + $patron->privacy(2)->store(); #set to never + + $old_checkout->discard_changes; #refresh from db + $patron->discard_changes; + + is( $old_checkout->borrowernumber, $anon_patron->id, "Checkout is successfully anonymized"); + is( $patron->privacy(), 2, "Patron privacy is successfully updated"); +}; -- 2.39.5