From 76241364cfa0d6ccedcd5517edbc9f2a609f197d Mon Sep 17 00:00:00 2001 From: Matt Blenkinsop Date: Thu, 5 Jun 2025 13:40:25 +0100 Subject: [PATCH] Bug 40082: Add unit tests Test plan: 1) Choose an existing patron and note their first and second names as well as their date of birth 2) In the interface, create a new patron and enter all of those details to be the same as your patron from step 1 3) Submit the form, you will get a warning saying that there is a duplicate 4) In the OPAC, self register a new patron using the same details again 5) The form should submit with no error or warning 6) Apply patch, yarn api:bundle and restart_all 7) Repeat steps 2 - 5 8) Step 3 should still have the same behaviour 9) Step 5 should now show a warning at the top to say that there is a duplicate, please contact a member of staff 10) Find the 'PatronDuplicateMatchingAddFields' syspref and select an extra field there, ensuring that your patron from step 1 has data for that field 11) In either the interface or the OPAC, register a new patron but this time change the data of the new field you added in step 10 12) No warning should show for a duplicate patron 13) prove t/db_dependent/api/v1/patrons.t 14) prove t/db_dependent/Koha/Patrons.t --- t/db_dependent/Koha/Patrons.t | 34 ++++++++++++++++++++++++++++++++- t/db_dependent/api/v1/patrons.t | 27 +++++++++++++++----------- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/t/db_dependent/Koha/Patrons.t b/t/db_dependent/Koha/Patrons.t index ed7ad7a3516..f19eb91ea6a 100755 --- a/t/db_dependent/Koha/Patrons.t +++ b/t/db_dependent/Koha/Patrons.t @@ -20,7 +20,7 @@ use Modern::Perl; use Test::NoWarnings; -use Test::More tests => 46; +use Test::More tests => 47; use Test::Warn; use Test::Exception; use Test::MockModule; @@ -3573,4 +3573,36 @@ subtest 'filter_by_expired_opac_registrations' => sub { $schema->storage->txn_rollback; }; +subtest 'check_for_existing_matches' => sub { + plan tests => 5; + + $schema->storage->txn_begin; + + my $patron = $builder->build_object( + { class => 'Koha::Patrons', value => { firstname => 'John', surname => 'Smith', dateofbirth => '1980-01-01' } } + ); + + t::lib::Mocks::mock_preference( 'PatronDuplicateMatchingAddFields', 'dateofbirth|firstname|surname' ); + + my $match_result = Koha::Patrons->check_for_existing_matches( + { firstname => 'John', surname => 'Smith', dateofbirth => '1980-01-01' } ); + is( $match_result->{duplicate_found}, 1, 'Duplicate found' ); + is( $match_result->{matching_patrons}->next->borrowernumber, $patron->borrowernumber, 'Matching patron' ); + + t::lib::Mocks::mock_preference( 'PatronDuplicateMatchingAddFields', 'dateofbirth|firstname|surname|city' ); + $match_result = Koha::Patrons->check_for_existing_matches( + { firstname => 'John', surname => 'Smith', dateofbirth => '1980-01-01', city => '' } ); + is( $match_result->{duplicate_found}, 1, 'Duplicate found despite missing data for the city field' ); + is( + $match_result->{matching_patrons}->next->borrowernumber, $patron->borrowernumber, + 'Patron match ignores undefined field and still identifies the match' + ); + + $match_result = Koha::Patrons->check_for_existing_matches( + { firstname => 'John', surname => 'Smith', dateofbirth => '1980-01-01', city => 'Sandwich, Kent' } ); + is( $match_result->{duplicate_found}, 0, 'No duplicate found' ); + + $schema->storage->txn_rollback; +}; + $schema->storage->txn_rollback; diff --git a/t/db_dependent/api/v1/patrons.t b/t/db_dependent/api/v1/patrons.t index 4441725386d..c68b184a781 100755 --- a/t/db_dependent/api/v1/patrons.t +++ b/t/db_dependent/api/v1/patrons.t @@ -427,7 +427,7 @@ subtest 'add() tests' => sub { $schema->storage->txn_rollback; subtest 'librarian access tests' => sub { - plan tests => 25; + plan tests => 28; $schema->storage->txn_begin; @@ -458,6 +458,14 @@ subtest 'add() tests' => sub { delete $newpatron->{expired}; delete $newpatron->{anonymized}; + my $password = 'thePassword123'; + $librarian->set_password( { password => $password, skip_validation => 1 } ); + my $userid = $librarian->userid; + t::lib::Mocks::mock_preference( 'PatronDuplicateMatchingAddFields', 'firstname|surname|dateofbirth' ); + + $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(409) + ->json_is( '/error' => "A patron record matching these details already exists" ); + # Create a library just to make sure its ID doesn't exist on the DB my $library_to_delete = $builder->build_object( { class => 'Koha::Libraries' } ); my $deleted_library_id = $library_to_delete->id; @@ -465,14 +473,10 @@ subtest 'add() tests' => sub { # Delete library $library_to_delete->delete; - my $password = 'thePassword123'; - $librarian->set_password( { password => $password, skip_validation => 1 } ); - my $userid = $librarian->userid; - $newpatron->{library_id} = $deleted_library_id; - $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(400) - ->json_is( '/error' => "Problem with " . $newpatron->{userid} ); + $t->post_ok( "//$userid:$password@/api/v1/patrons" => { 'x-confirm-not-duplicate' => 1 } => json => $newpatron ) + ->status_is(400)->json_is( '/error' => "Problem with " . $newpatron->{userid} ); $newpatron->{library_id} = $patron->branchcode; @@ -485,8 +489,8 @@ subtest 'add() tests' => sub { $newpatron->{category_id} = $deleted_category_id; # Test invalid patron category - $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(400) - ->json_is( '/error' => "Given category_id does not exist" ); + $t->post_ok( "//$userid:$password@/api/v1/patrons" => { 'x-confirm-not-duplicate' => 1 } => json => $newpatron ) + ->status_is(400)->json_is( '/error' => "Given category_id does not exist" ); $newpatron->{category_id} = $patron->categorycode; $newpatron->{falseproperty} = "Non existent property"; @@ -528,8 +532,9 @@ subtest 'add() tests' => sub { $newpatron->{userid} = undef; # force regeneration warning_like { - $t->post_ok( "//$userid:$password@/api/v1/patrons" => json => $newpatron )->status_is(409) - ->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' ) + $t->post_ok( + "//$userid:$password@/api/v1/patrons" => { 'x-confirm-not-duplicate' => 1 } => json => $newpatron ) + ->status_is(409)->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' ) ->json_like( '/conflict' => qr/(borrowers\.)?cardnumber/ ); } qr/DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key '(borrowers\.)?cardnumber'/; -- 2.48.1