Bug 32437: Add replace method to Koha::Import::Record objects
[koha.git] / t / db_dependent / Koha / Patron_generate_userid.t
1 #!/usr/bin/perl
2
3 # Copyright 2022 Rijksmuseum, Koha development team
4 #
5 # This file is part of Koha
6 #
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20 use Modern::Perl;
21 use utf8;
22 #use Data::Dumper;
23 use Test::More tests => 2;
24 use Test::Warn;
25 use Test::MockModule;
26 use Test::MockObject;
27
28 use t::lib::Mocks;
29 use t::lib::TestBuilder;
30
31 use Koha::Database;
32 use Koha::Patrons;
33 use Koha::Plugins;
34
35 our $schema = Koha::Database->new->schema;
36 $schema->storage->txn_begin;
37 our $builder = t::lib::TestBuilder->new;
38 our $expected_plugins = [];
39
40 sub mockedGetPlugins {
41     my @plugins;
42     foreach my $p ( @$expected_plugins ) {
43         my $object = Test::MockObject->new;
44         my $method;
45         if( $p eq 'email' ) {
46             $method = sub { return $_[1]->{patron}->email; };
47         } elsif( $p eq 'firstname' ) {
48             $method = sub { return $_[1]->{patron}->firstname. ($_[1]->{patron}->id // 0); };
49         } elsif( $p eq 'baduserid' ) {
50             $method = sub { return ''; }; # bad return
51         } elsif( $p eq 'die' ) {
52             $method = sub { die; };
53         } elsif( $p eq 'undef' ) {
54             $method = sub { return; };
55         } else { # borrowernumber
56             $method = sub { return $_[1]->{patron}->id // 0; };
57         }
58         $object->mock('patron_generate_userid', $method);
59         $object->mock('get_metadata', sub { return { name => $p }}); # called when warning from ->call
60         push @plugins, $object;
61     }
62     return @plugins;
63 }
64
65 subtest 'generate_userid (legacy, without plugins)' => sub {
66     plan tests => 7;
67
68     t::lib::Mocks::mock_config('enable_plugins', 0);
69
70     my $library = $builder->build_object( { class => 'Koha::Libraries' } );
71     my $patron_category = $builder->build_object(
72         {
73             class => 'Koha::Patron::Categories',
74             value => { category_type => 'P', enrolmentfee => 0 }
75         }
76     );
77     my %data = (
78         cardnumber   => "123456789",
79         firstname    => "Tômàsító",
80         surname      => "Ñoné",
81         categorycode => $patron_category->categorycode,
82         branchcode   => $library->branchcode,
83     );
84
85     my $expected_userid_patron_1 = 'tomasito.none';
86     my $new_patron = Koha::Patron->new({ firstname => $data{firstname}, surname => $data{surname} } );
87     $new_patron->generate_userid;
88     my $userid = $new_patron->userid;
89     is( $userid, $expected_userid_patron_1, 'generate_userid should generate the userid we expect' );
90     my $borrowernumber = Koha::Patron->new(\%data)->store->borrowernumber;
91     my $patron_1 = Koha::Patrons->find($borrowernumber);
92     is ( $patron_1->userid, $expected_userid_patron_1, 'The userid generated should be the one we expect' );
93
94     $new_patron->generate_userid;
95     $userid = $new_patron->userid;
96     is( $userid, $expected_userid_patron_1 . '1', 'generate_userid should generate the userid we expect' );
97     $data{cardnumber} = '987654321';
98     my $new_borrowernumber = Koha::Patron->new(\%data)->store->borrowernumber;
99     my $patron_2 = Koha::Patrons->find($new_borrowernumber);
100     isnt( $patron_2->userid, 'tomasito',
101         "Patron with duplicate userid has new userid generated" );
102     is( $patron_2->userid, $expected_userid_patron_1 . '1', # TODO we could make that configurable
103         "Patron with duplicate userid has new userid generated (1 is appended" );
104
105     $new_patron->generate_userid;
106     $userid = $new_patron->userid;
107     is( $userid, $expected_userid_patron_1 . '2', 'generate_userid should generate the userid we expect' );
108
109     $patron_1 = Koha::Patrons->find($borrowernumber);
110     $patron_1->userid(undef);
111     $patron_1->generate_userid;
112     $userid = $patron_1->userid;
113     is( $userid, $expected_userid_patron_1, 'generate_userid should generate the userid we expect' );
114
115     # Cleanup
116     $patron_1->delete;
117     $patron_2->delete;
118 };
119
120 subtest 'Plugins for generate_userid' => sub {
121     plan tests => 6;
122     t::lib::Mocks::mock_config('enable_plugins', 1);
123
124     my $auth = Test::MockModule->new( 'Koha::Plugins' );
125     $auth->mock( 'GetPlugins', \&mockedGetPlugins );
126     $auth->mock( 'get_enabled_plugins', \&mockedGetPlugins );
127
128     # Check the email plugin
129     $expected_plugins = [ 'email' ];
130     my $patron1 = $builder->build_object({ class => 'Koha::Patrons', value => { email => 'test@domain.com' } });
131     $patron1->generate_userid;
132     is( $patron1->userid, 'test@domain.com', 'generated userid from email plugin' );
133
134     # Expect second response from firstname, because empty string from baduserid is not valid
135     $expected_plugins = [ 'baduserid', 'firstname', 'email' ];
136     $patron1->generate_userid;
137     my $reg = $patron1->firstname. '\d+';
138     like( $patron1->userid, qr/$reg/, 'ignored baduserid, generated userid from firstname plugin' );
139
140     # Expect third response from fallback for wrong_method, catch warning from die plugin
141     $expected_plugins = [ 'die', 'baduserid', 'wrong_method', 'firstname', 'email' ];
142     warning_like { $patron1->generate_userid; } qr/Plugin error \(die\): Died/, 'Caught warn for die plugin';
143     like( $patron1->userid, qr/^\d+$/, 'generated borrowernumber userid from plugin when given wrong_method' );
144     $patron1->delete;
145
146     # Testing with an object not in storage; unknown should return id 0, the plugin undef returns undef :)
147     $expected_plugins = [ 'unknown', 'undef' ];
148     $patron1= Koha::Patron->new({ firstname => 'A', surname => 'B', email => 'test2@domain.com', userid => 'user999' });
149     $patron1->generate_userid;
150     is( $patron1->userid, undef, 'No valid plugin responses' );
151
152     # Finally pass no plugins, so we would expect legacy response
153     $expected_plugins = [];
154     $patron1->generate_userid;
155     is( $patron1->userid, 'a.b', 'No plugins: legacy response' );
156 };
157
158 $schema->storage->txn_rollback;