View | Details | Raw Unified | Return to bug 39224
Collapse All | Expand All

(-)a/t/db_dependent/Auth_with_shibboleth.t (-12 / +74 lines)
Lines 35-40 use t::lib::Dates; Link Here
35
use C4::Auth_with_shibboleth qw( shib_ok login_shib_url get_login_shib checkpw_shib );
35
use C4::Auth_with_shibboleth qw( shib_ok login_shib_url get_login_shib checkpw_shib );
36
use Koha::Database;
36
use Koha::Database;
37
use Koha::DateUtils qw( dt_from_string );
37
use Koha::DateUtils qw( dt_from_string );
38
use Koha::Auth::Hostname;
39
use Koha::Auth::Hostnames;
40
use Koha::Auth::Identity::Provider;
41
use Koha::Auth::Identity::Provider::Hostname;
42
use Koha::Auth::Identity::Provider::Mapping;
43
use Koha::Auth::Identity::Provider::SAML2;
44
use Koha::Auth::Identity::Providers;
38
45
39
BEGIN {
46
BEGIN {
40
    use_ok(
47
    use_ok(
Lines 48-56 $schema->storage->txn_begin; Link Here
48
my $builder = t::lib::TestBuilder->new;
55
my $builder = t::lib::TestBuilder->new;
49
my $logger  = t::lib::Mocks::Logger->new();
56
my $logger  = t::lib::Mocks::Logger->new();
50
57
51
# Mock variables
52
my $shibboleth;
58
my $shibboleth;
53
change_config( {} );
54
my $interface = 'opac';
59
my $interface = 'opac';
55
60
56
# Mock few preferences
61
# Mock few preferences
Lines 59-70 t::lib::Mocks::mock_preference( 'StaffClientBaseURL', 'teststaff.com' ); Link Here
59
t::lib::Mocks::mock_preference( 'EmailFieldPrimary',    '' );
64
t::lib::Mocks::mock_preference( 'EmailFieldPrimary',    '' );
60
t::lib::Mocks::mock_preference( 'EmailFieldPrecedence', 'emailpro' );
65
t::lib::Mocks::mock_preference( 'EmailFieldPrecedence', 'emailpro' );
61
66
62
# Mock Context: config, tz and interface
67
# Mock Context: tz and interface
63
my $context = Test::MockModule->new('C4::Context');
68
my $context = Test::MockModule->new('C4::Context');
64
$context->mock( 'config',    sub { return $shibboleth; } );    # easier than caching by Mocks::mock_config
65
$context->mock( 'timezone',  sub { return 'local'; } );
69
$context->mock( 'timezone',  sub { return 'local'; } );
66
$context->mock( 'interface', sub { return $interface; } );
70
$context->mock( 'interface', sub { return $interface; } );
67
71
72
change_config( {} );
73
68
# Mock Letters: GetPreparedLetter, EnqueueLetter and SendQueuedMessages
74
# Mock Letters: GetPreparedLetter, EnqueueLetter and SendQueuedMessages
69
# We want to test the params
75
# We want to test the params
70
my $mocked_letters = Test::MockModule->new('C4::Letters');
76
my $mocked_letters = Test::MockModule->new('C4::Letters');
Lines 97-116 $mocked_letters->mock( Link Here
97
# Start testing ----------------------------------------------------------------
103
# Start testing ----------------------------------------------------------------
98
104
99
subtest "shib_ok tests" => sub {
105
subtest "shib_ok tests" => sub {
100
    plan tests => 5;
106
    plan tests => 6;
101
    my $result;
107
    my $result;
102
108
103
    # correct config, no debug
109
    # correct config, no debug
104
    is( shib_ok(), '1', "good config" );
110
    is( shib_ok(), '1', "good config" );
105
111
106
    # bad config, no debug
112
    # bad config, no debug - clear matchpoint on hostname entries
113
    $schema->resultset('IdentityProviderHostname')->update( { matchpoint => undef } );
107
    delete $shibboleth->{matchpoint};
114
    delete $shibboleth->{matchpoint};
115
    $logger->clear();
108
    warnings_are { $result = shib_ok() }
116
    warnings_are { $result = shib_ok() }
109
    [ { carped => 'shibboleth matchpoint not defined' }, ],
117
    [ { carped => 'shibboleth matchpoint not defined' } ],
110
        "undefined matchpoint = fatal config, warning given";
118
        "matchpoint warning given when no matchpoint set";
111
    is( $result, '0', "bad config" );
119
    is( $result, '0', "bad config" );
112
120
113
    change_config( { matchpoint => 'email' } );
121
    change_config( { matchpoint => 'email', mapping => { email => { content => 'default@example.com' } } } );
114
    warnings_are { $result = shib_ok() }
122
    warnings_are { $result = shib_ok() }
115
    [ { carped => 'shibboleth matchpoint not mapped' }, ],
123
    [ { carped => 'shibboleth matchpoint not mapped' }, ],
116
        "unmapped matchpoint = fatal config, warning given";
124
        "unmapped matchpoint = fatal config, warning given";
Lines 119-124 subtest "shib_ok tests" => sub { Link Here
119
    # add test for undefined shibboleth block
127
    # add test for undefined shibboleth block
120
    $logger->clear;
128
    $logger->clear;
121
    change_config( {} );
129
    change_config( {} );
130
    is( shib_ok(), '1', 'good config after reset' );
122
};
131
};
123
132
124
subtest "login_shib_url tests" => sub {
133
subtest "login_shib_url tests" => sub {
Lines 279-284 subtest "checkpw_shib tests" => sub { Link Here
279
    );
288
    );
280
289
281
    # sync user
290
    # sync user
291
    my $saml2_provider = Koha::Auth::Identity::Providers->search( { protocol => 'SAML2' } )->next;
292
    my $saml2_config   = $saml2_provider->get_config // {};
293
    $saml2_config->{sync} = 1;
294
    $saml2_provider->set_config($saml2_config)->store;
282
    $shibboleth->{sync} = 1;
295
    $shibboleth->{sync} = 1;
283
    $ENV{'city'} = 'AnotherCity';
296
    $ENV{'city'} = 'AnotherCity';
284
    ( $retval, $retcard, $retuserid, $retpatron ) = checkpw_shib($shib_login);
297
    ( $retval, $retcard, $retuserid, $retpatron ) = checkpw_shib($shib_login);
Lines 335-341 subtest "checkpw_shib tests" => sub { Link Here
335
    $ENV{'emailpro'} = 'me@myemail.com';
348
    $ENV{'emailpro'} = 'me@myemail.com';
336
    $ENV{branchcode} = $library->branchcode;      # needed since T::D::C does no longer hides the FK constraint
349
    $ENV{branchcode} = $library->branchcode;      # needed since T::D::C does no longer hides the FK constraint
337
350
338
    checkpw($shib_login);
351
    ( $retval, $retcard, $retuserid, $retpatron ) = checkpw_shib($shib_login);
339
    ok(
352
    ok(
340
        my $new_user_autocreated = Koha::Patrons->find( { userid => 'test43210' } ),
353
        my $new_user_autocreated = Koha::Patrons->find( { userid => 'test43210' } ),
341
        "new user found"
354
        "new user found"
Lines 424-429 $schema->storage->txn_rollback; Link Here
424
sub change_config {
437
sub change_config {
425
    my $params = shift;
438
    my $params = shift;
426
439
440
    # Remove any existing SAML2 providers
441
    Koha::Auth::Identity::Providers->search( { protocol => 'SAML2' } )->delete;
442
443
    my $provider = Koha::Auth::Identity::Provider::SAML2->new(
444
        {
445
            code        => 'shibboleth',
446
            description => 'Shibboleth',
447
            enabled     => 1,
448
        }
449
    )->store;
450
451
    $provider->set_config(
452
        {
453
            autocreate => $params->{autocreate} // 0,
454
            sync       => $params->{sync}       // 0,
455
            welcome    => $params->{welcome}    // 0,
456
        }
457
    )->store;
458
459
    # Link provider to the test hostname so _get_shib_config can find it
460
    my $test_hostname = 'testopac.com';
461
    $ENV{SERVER_NAME} = $test_hostname;
462
    my $hostname_obj = Koha::Auth::Hostnames->search( { hostname => $test_hostname } )->next
463
        // $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => $test_hostname } } );
464
    Koha::Auth::Identity::Provider::Hostname->new(
465
        {
466
            hostname_id          => $hostname_obj->hostname_id,
467
            identity_provider_id => $provider->identity_provider_id,
468
            is_enabled           => 1,
469
        }
470
    )->store;
471
427
    my %mapping = (
472
    my %mapping = (
428
        'userid'       => { 'is' => 'uid' },
473
        'userid'       => { 'is' => 'uid' },
429
        'surname'      => { 'is' => 'sn' },
474
        'surname'      => { 'is' => 'sn' },
Lines 437-451 sub change_config { Link Here
437
    if ( exists $params->{mapping} ) {
482
    if ( exists $params->{mapping} ) {
438
        $mapping{$_} = $params->{mapping}->{$_} for keys %{ $params->{mapping} };
483
        $mapping{$_} = $params->{mapping}->{$_} for keys %{ $params->{mapping} };
439
    }
484
    }
485
486
    my $matchpoint = $params->{matchpoint} // 'userid';
487
488
    foreach my $koha_field ( keys %mapping ) {
489
        Koha::Auth::Identity::Provider::Mapping->new(
490
            {
491
                identity_provider_id => $provider->identity_provider_id,
492
                koha_field           => $koha_field,
493
                provider_field       => $mapping{$koha_field}->{is},
494
                default_content      => $mapping{$koha_field}->{content},
495
            }
496
        )->store;
497
    }
498
499
    $schema->resultset('IdentityProviderHostname')
500
        ->search( { identity_provider_id => $provider->identity_provider_id } )
501
        ->update( { matchpoint           => $matchpoint } );
502
440
    $shibboleth = {
503
    $shibboleth = {
441
        autocreate => $params->{autocreate} // 0,
504
        autocreate => $params->{autocreate} // 0,
442
        welcome    => $params->{welcome}    // 0,
505
        welcome    => $params->{welcome}    // 0,
443
        sync       => $params->{sync}       // 0,
506
        sync       => $params->{sync}       // 0,
444
        matchpoint => $params->{matchpoint} // 'userid',
507
        matchpoint => $matchpoint,
445
        mapping    => \%mapping,
508
        mapping    => \%mapping,
446
    };
509
    };
447
510
448
    # Change environment too
449
    $ENV{'uid'}      = "test1234";
511
    $ENV{'uid'}      = "test1234";
450
    $ENV{'sn'}       = undef;
512
    $ENV{'sn'}       = undef;
451
    $ENV{'exp'}      = undef;
513
    $ENV{'exp'}      = undef;
(-)a/t/db_dependent/Koha/Auth/Client.t (-18 / +42 lines)
Lines 45-53 subtest 'get_user() tests' => sub { Link Here
45
45
46
    $schema->storage->txn_begin;
46
    $schema->storage->txn_begin;
47
47
48
    my $client = Koha::Auth::Client::OAuth->new;
48
    my $client   = Koha::Auth::Client::OAuth->new;
49
    my $provider =
49
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
50
        $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
50
    my $hostname_obj =
51
        $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => 'test.library.com' } } );
52
    $builder->build_object(
53
        {
54
            class => 'Koha::Auth::Identity::Provider::Hostnames',
55
            value => {
56
                identity_provider_id => $provider->id,
57
                hostname_id          => $hostname_obj->id,
58
                matchpoint           => 'email',
59
            }
60
        }
61
    );
51
    my $domain = $builder->build_object(
62
    my $domain = $builder->build_object(
52
        {
63
        {
53
            class => 'Koha::Auth::Identity::Provider::Domains',
64
            class => 'Koha::Auth::Identity::Provider::Domains',
Lines 59-70 subtest 'get_user() tests' => sub { Link Here
59
    );
70
    );
60
    my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { email => 'patron@test.com' } } );
71
    my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { email => 'patron@test.com' } } );
61
    t::lib::Mocks::mock_userenv( { patron => $patron } );
72
    t::lib::Mocks::mock_userenv( { patron => $patron } );
62
    my $mapping = {
73
    $builder->build_object(
63
        email     => 'electronic_mail',
74
        {
64
        firstname => 'given_name',
75
            class => 'Koha::Auth::Identity::Provider::Mappings',
65
        surname   => 'family_name'
76
            value =>
66
    };
77
                { identity_provider_id => $provider->id, koha_field => 'email', provider_field => 'electronic_mail' }
67
    $provider->set_mapping($mapping)->store;
78
        }
79
    );
80
    $builder->build_object(
81
        {
82
            class => 'Koha::Auth::Identity::Provider::Mappings',
83
            value =>
84
                { identity_provider_id => $provider->id, koha_field => 'firstname', provider_field => 'given_name' }
85
        }
86
    );
87
    $builder->build_object(
88
        {
89
            class => 'Koha::Auth::Identity::Provider::Mappings',
90
            value => { identity_provider_id => $provider->id, koha_field => 'surname', provider_field => 'family_name' }
91
        }
92
    );
68
93
69
    my $id_token = 'header.' . encode_base64url(
94
    my $id_token = 'header.' . encode_base64url(
70
        encode_json(
95
        encode_json(
Lines 78-84 subtest 'get_user() tests' => sub { Link Here
78
    my $data = { id_token => $id_token };
103
    my $data = { id_token => $id_token };
79
104
80
    my ( $resolved_patron, $mapped_data, $resolved_domain ) =
105
    my ( $resolved_patron, $mapped_data, $resolved_domain ) =
81
        $client->get_user( { provider => $provider->code, data => $data, interface => 'opac' } );
106
        $client->get_user(
107
        { provider => $provider->code, data => $data, interface => 'opac', hostname => 'test.library.com' } );
82
    is_deeply(
108
    is_deeply(
83
        $resolved_patron->to_api( { user => $patron } ), $patron->to_api( { user => $patron } ),
109
        $resolved_patron->to_api( { user => $patron } ), $patron->to_api( { user => $patron } ),
84
        'Patron correctly retrieved'
110
        'Patron correctly retrieved'
Lines 95-104 subtest 'get_valid_domain_config() tests' => sub { Link Here
95
121
96
    $schema->storage->txn_begin;
122
    $schema->storage->txn_begin;
97
123
98
    my $client = Koha::Auth::Client->new;
124
    my $client   = Koha::Auth::Client->new;
99
    my $provider =
125
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
100
        $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
126
    my $domain1  = $builder->build_object(
101
    my $domain1 = $builder->build_object(
102
        {
127
        {
103
            class => 'Koha::Auth::Identity::Provider::Domains',
128
            class => 'Koha::Auth::Identity::Provider::Domains',
104
            value => { identity_provider_id => $provider->id, domain => '', allow_opac => 0, allow_staff => 0 }
129
            value => { identity_provider_id => $provider->id, domain => '', allow_opac => 0, allow_staff => 0 }
Lines 200-209 subtest 'has_valid_domain_config() tests' => sub { Link Here
200
    plan tests => 2;
225
    plan tests => 2;
201
    $schema->storage->txn_begin;
226
    $schema->storage->txn_begin;
202
227
203
    my $client = Koha::Auth::Client->new;
228
    my $client   = Koha::Auth::Client->new;
204
    my $provider =
229
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
205
        $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
230
    my $domain1  = $builder->build_object(
206
    my $domain1 = $builder->build_object(
207
        {
231
        {
208
            class => 'Koha::Auth::Identity::Provider::Domains',
232
            class => 'Koha::Auth::Identity::Provider::Domains',
209
            value => { identity_provider_id => $provider->id, domain => '', allow_opac => 1, allow_staff => 0 }
233
            value => { identity_provider_id => $provider->id, domain => '', allow_opac => 1, allow_staff => 0 }
(-)a/t/db_dependent/Koha/Auth/Client/OAuth.t (-33 / +64 lines)
Lines 50-68 subtest '_get_data_and_patron() with id_token tests' => sub { Link Here
50
    );
50
    );
51
51
52
    # Create provider with email matchpoint
52
    # Create provider with email matchpoint
53
    my $provider = $builder->build_object(
53
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
54
    my $hostname_obj =
55
        $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => 'test.library.com' } } );
56
    $builder->build_object(
54
        {
57
        {
55
            class => 'Koha::Auth::Identity::Providers',
58
            class => 'Koha::Auth::Identity::Provider::Hostnames',
56
            value => {
59
            value => { identity_provider_id => $provider->id, hostname_id => $hostname_obj->id, matchpoint => 'email' }
57
                matchpoint => 'email',
60
        }
58
                mapping    => encode_json(
61
    );
59
                    {
62
    $builder->build_object(
60
                        email     => 'mail',
63
        {
61
                        firstname => 'given_name',
64
            class => 'Koha::Auth::Identity::Provider::Mappings',
62
                        surname   => 'family_name'
65
            value => { identity_provider_id => $provider->id, koha_field => 'email', provider_field => 'mail' }
63
                    }
66
        }
64
                )
67
    );
65
            }
68
    $builder->build_object(
69
        {
70
            class => 'Koha::Auth::Identity::Provider::Mappings',
71
            value =>
72
                { identity_provider_id => $provider->id, koha_field => 'firstname', provider_field => 'given_name' }
73
        }
74
    );
75
    $builder->build_object(
76
        {
77
            class => 'Koha::Auth::Identity::Provider::Mappings',
78
            value => { identity_provider_id => $provider->id, koha_field => 'surname', provider_field => 'family_name' }
66
        }
79
        }
67
    );
80
    );
68
81
Lines 83-89 subtest '_get_data_and_patron() with id_token tests' => sub { Link Here
83
        {
96
        {
84
            provider => $provider,
97
            provider => $provider,
85
            data     => $data,
98
            data     => $data,
86
            config   => $config
99
            config   => $config,
100
            hostname => 'test.library.com',
87
        }
101
        }
88
    );
102
    );
89
103
Lines 112-129 subtest '_get_data_and_patron() with userinfo_url tests' => sub { Link Here
112
    );
126
    );
113
127
114
    # Create provider with email matchpoint
128
    # Create provider with email matchpoint
115
    my $provider = $builder->build_object(
129
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
130
    my $hostname_obj =
131
        $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => 'test2.library.com' } } );
132
    $builder->build_object(
116
        {
133
        {
117
            class => 'Koha::Auth::Identity::Providers',
134
            class => 'Koha::Auth::Identity::Provider::Hostnames',
118
            value => {
135
            value => { identity_provider_id => $provider->id, hostname_id => $hostname_obj->id, matchpoint => 'email' }
119
                matchpoint => 'email',
136
        }
120
                mapping    => encode_json(
137
    );
121
                    {
138
    $builder->build_object(
122
                        email     => 'email',
139
        {
123
                        firstname => 'first_name'
140
            class => 'Koha::Auth::Identity::Provider::Mappings',
124
                    }
141
            value => { identity_provider_id => $provider->id, koha_field => 'email', provider_field => 'email' }
125
                )
142
        }
126
            }
143
    );
144
    $builder->build_object(
145
        {
146
            class => 'Koha::Auth::Identity::Provider::Mappings',
147
            value =>
148
                { identity_provider_id => $provider->id, koha_field => 'firstname', provider_field => 'first_name' }
127
        }
149
        }
128
    );
150
    );
129
151
Lines 179-185 subtest '_get_data_and_patron() with userinfo_url tests' => sub { Link Here
179
        {
201
        {
180
            provider => $provider,
202
            provider => $provider,
181
            data     => $data,
203
            data     => $data,
182
            config   => $config
204
            config   => $config,
205
            hostname => 'test2.library.com',
183
        }
206
        }
184
    );
207
    );
185
208
Lines 205-211 subtest '_get_data_and_patron() with userinfo_url tests' => sub { Link Here
205
        {
228
        {
206
            provider => $provider,
229
            provider => $provider,
207
            data     => $data,
230
            data     => $data,
208
            config   => $config
231
            config   => $config,
232
            hostname => 'test2.library.com',
209
        }
233
        }
210
    );
234
    );
211
235
Lines 223-235 subtest '_get_data_and_patron() no patron found tests' => sub { Link Here
223
    my $client = Koha::Auth::Client::OAuth->new;
247
    my $client = Koha::Auth::Client::OAuth->new;
224
248
225
    # Create provider
249
    # Create provider
226
    my $provider = $builder->build_object(
250
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
251
    my $hostname_obj =
252
        $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => 'test3.library.com' } } );
253
    $builder->build_object(
254
        {
255
            class => 'Koha::Auth::Identity::Provider::Hostnames',
256
            value => { identity_provider_id => $provider->id, hostname_id => $hostname_obj->id, matchpoint => 'email' }
257
        }
258
    );
259
    $builder->build_object(
227
        {
260
        {
228
            class => 'Koha::Auth::Identity::Providers',
261
            class => 'Koha::Auth::Identity::Provider::Mappings',
229
            value => {
262
            value => { identity_provider_id => $provider->id, koha_field => 'email', provider_field => 'mail' }
230
                matchpoint => 'email',
231
                mapping    => encode_json( { email => 'mail' } )
232
            }
233
        }
263
        }
234
    );
264
    );
235
265
Lines 245-251 subtest '_get_data_and_patron() no patron found tests' => sub { Link Here
245
        {
275
        {
246
            provider => $provider,
276
            provider => $provider,
247
            data     => $data,
277
            data     => $data,
248
            config   => $config
278
            config   => $config,
279
            hostname => 'test3.library.com',
249
        }
280
        }
250
    );
281
    );
251
282
(-)a/t/db_dependent/Koha/Auth/Hostname.t (+139 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright Koha Community 2026
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 <https://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::NoWarnings;
23
use Test::More tests => 4;
24
25
use Koha::Auth::Hostname;
26
use Koha::Auth::Hostnames;
27
28
use t::lib::TestBuilder;
29
use t::lib::Mocks;
30
31
my $schema  = Koha::Database->new->schema;
32
my $builder = t::lib::TestBuilder->new;
33
34
subtest 'sync_from_syspref() tests' => sub {
35
36
    plan tests => 12;
37
38
    $schema->storage->txn_begin;
39
40
    Koha::Auth::Hostnames->search->delete;
41
42
    # OPACBaseURL maps to hostname_id=1
43
    t::lib::Mocks::mock_preference( 'OPACBaseURL', 'https://opac.example.com' );
44
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', 'https://opac.example.com' );
45
46
    my $opac = Koha::Auth::Hostnames->find(1);
47
    ok( $opac, 'OPACBaseURL creates hostname_id=1' );
48
    is( $opac->hostname, 'opac.example.com', 'hostname_id=1 has correct hostname' );
49
50
    # staffClientBaseURL maps to hostname_id=2
51
    Koha::Auth::Hostname->sync_from_syspref( 'staffClientBaseURL', 'https://staff.example.com' );
52
53
    my $staff = Koha::Auth::Hostnames->find(2);
54
    ok( $staff, 'staffClientBaseURL creates hostname_id=2' );
55
    is( $staff->hostname, 'staff.example.com', 'hostname_id=2 has correct hostname' );
56
57
    # Updating the URL changes the stored hostname in-place
58
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', 'https://newopac.example.com' );
59
    $opac->discard_changes;
60
    is( $opac->hostname, 'newopac.example.com', 'hostname_id=1 updated when OPACBaseURL changes' );
61
    is( Koha::Auth::Hostnames->search( { hostname_id => 1 } )->count, 1, 'Still only one row for hostname_id=1' );
62
63
    # Idempotent: calling again with the same value is a no-op
64
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', 'https://newopac.example.com' );
65
    is(
66
        Koha::Auth::Hostnames->search( { hostname => 'newopac.example.com' } )->count, 1,
67
        'Idempotent: no duplicate created'
68
    );
69
70
    # http:// URLs are supported
71
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', 'http://opac.example.org' );
72
    $opac->discard_changes;
73
    is( $opac->hostname, 'opac.example.org', 'http:// URL extracted correctly' );
74
75
    # Port numbers are stripped
76
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', 'https://opac.example.net:8080/path' );
77
    $opac->discard_changes;
78
    is( $opac->hostname, 'opac.example.net', 'Port number stripped from hostname' );
79
80
    # Empty value is a no-op
81
    my $hostname_before = $opac->hostname;
82
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', '' );
83
    $opac->discard_changes;
84
    is( $opac->hostname, $hostname_before, 'Empty value leaves existing hostname unchanged' );
85
86
    # Malformed URL (no protocol) is a no-op
87
    Koha::Auth::Hostname->sync_from_syspref( 'OPACBaseURL', 'not-a-valid-url' );
88
    $opac->discard_changes;
89
    is( $opac->hostname, $hostname_before, 'Malformed URL leaves existing hostname unchanged' );
90
91
    # Unknown preference name is ignored
92
    Koha::Auth::Hostname->sync_from_syspref( 'SomeOtherPref', 'https://other.example.com' );
93
    is(
94
        Koha::Auth::Hostnames->search( { hostname => 'other.example.com' } )->count,
95
        0, 'Unknown syspref name is ignored'
96
    );
97
98
    $schema->storage->txn_rollback;
99
};
100
101
subtest 'sync_from_sysprefs() tests' => sub {
102
103
    plan tests => 4;
104
105
    $schema->storage->txn_begin;
106
107
    Koha::Auth::Hostnames->search->delete;
108
109
    t::lib::Mocks::mock_preference( 'OPACBaseURL',        'https://opac.example.com' );
110
    t::lib::Mocks::mock_preference( 'staffClientBaseURL', 'https://staff.example.com' );
111
112
    Koha::Auth::Hostname->sync_from_sysprefs;
113
114
    my $opac  = Koha::Auth::Hostnames->find(1);
115
    my $staff = Koha::Auth::Hostnames->find(2);
116
117
    ok( $opac, 'hostname_id=1 exists after sync_from_sysprefs' );
118
    is( $opac->hostname, 'opac.example.com', 'hostname_id=1 has OPAC hostname' );
119
120
    ok( $staff, 'hostname_id=2 exists after sync_from_sysprefs' );
121
    is( $staff->hostname, 'staff.example.com', 'hostname_id=2 has staff hostname' );
122
123
    $schema->storage->txn_rollback;
124
};
125
126
subtest 'Koha::Auth::Hostnames type tests' => sub {
127
128
    plan tests => 2;
129
130
    $schema->storage->txn_begin;
131
132
    my $hostname = $builder->build_object( { class => 'Koha::Auth::Hostnames' } );
133
    is( ref($hostname), 'Koha::Auth::Hostname', 'build_object returns correct object type' );
134
135
    my $hostnames = Koha::Auth::Hostnames->search( { hostname_id => $hostname->hostname_id } );
136
    is( ref($hostnames), 'Koha::Auth::Hostnames', 'search returns correct collection type' );
137
138
    $schema->storage->txn_rollback;
139
};
(-)a/t/db_dependent/Koha/Auth/Identity/Provider.t (-38 / +120 lines)
Lines 20-32 Link Here
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use Test::NoWarnings;
22
use Test::NoWarnings;
23
use Test::More tests => 7;
23
use Test::More tests => 8;
24
24
25
use Test::MockModule;
25
use Test::MockModule;
26
use Test::Exception;
26
use Test::Exception;
27
27
28
use JSON qw(encode_json);
28
use JSON qw(encode_json);
29
29
30
use Koha::Auth::Hostnames;
31
use Koha::Auth::Identity::Provider;
32
use Koha::Auth::Identity::Provider::Hostnames;
33
use Koha::Auth::Identity::Provider::Mappings;
30
use Koha::Auth::Identity::Providers;
34
use Koha::Auth::Identity::Providers;
31
35
32
use t::lib::TestBuilder;
36
use t::lib::TestBuilder;
Lines 88-94 subtest 'set_config() tests' => sub { Link Here
88
92
89
        my $provider =
93
        my $provider =
90
            $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OIDC' } } );
94
            $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OIDC' } } );
91
        $provider = $provider->upgrade_class;
92
95
93
        my $config = {
96
        my $config = {
94
            key    => 'key',
97
            key    => 'key',
Lines 114-120 subtest 'set_config() tests' => sub { Link Here
114
117
115
        my $provider =
118
        my $provider =
116
            $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OAuth' } } );
119
            $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OAuth' } } );
117
        $provider = $provider->upgrade_class;
118
120
119
        my $config = {
121
        my $config = {
120
            key       => 'key',
122
            key       => 'key',
Lines 135-149 subtest 'set_config() tests' => sub { Link Here
135
        is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
137
        is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
136
    };
138
    };
137
139
138
    subtest 'Unsupported protocol tests' => sub {
140
    subtest 'Base class (unsupported protocol) tests' => sub {
139
141
140
        plan tests => 2;
142
        plan tests => 2;
141
143
142
        my $provider =
144
        # Cannot build in DB with invalid protocol; instantiate base class directly
143
            $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'CAS' } } );
145
        my $provider = Koha::Auth::Identity::Provider->new( { protocol => 'OAuth' } );
144
146
145
        throws_ok { $provider->set_config() }
147
        throws_ok { $provider->set_config( {} ) }
146
        'Koha::Exception', 'Exception thrown on unsupported protocol';
148
        'Koha::Exception', 'Exception thrown when calling set_config on base class';
147
149
148
        like( "$@", qr/This method needs to be subclassed/, 'Message is correct' );
150
        like( "$@", qr/This method needs to be subclassed/, 'Message is correct' );
149
    };
151
    };
Lines 151-198 subtest 'set_config() tests' => sub { Link Here
151
    $schema->storage->txn_rollback;
153
    $schema->storage->txn_rollback;
152
};
154
};
153
155
154
subtest 'get_mapping() tests' => sub {
156
subtest 'mappings() tests' => sub {
155
157
156
    plan tests => 2;
158
    plan tests => 3;
157
159
158
    $schema->storage->txn_begin;
160
    $schema->storage->txn_begin;
159
161
160
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { config => '{' } } );
162
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
161
163
    my $mappings = $provider->mappings;
162
    throws_ok { $provider->get_mapping() }
164
163
    'Koha::Exceptions::Object::BadValue', 'Expected exception thrown on bad JSON';
165
    is( ref($mappings),   'Koha::Auth::Identity::Provider::Mappings', 'Type is correct' );
164
166
    is( $mappings->count, 0,                                          'No mappings defined' );
165
    my $mapping = { some => 'value', and => 'another' };
167
166
    $provider->mapping( encode_json($mapping) )->store;
168
    $builder->build(
167
169
        {
168
    is_deeply( $provider->get_mapping, $mapping, 'Mapping correctly retrieved' );
170
            source => 'IdentityProviderMapping',
171
            value  => { identity_provider_id => $provider->id, koha_field => 'userid', provider_field => 'uid' }
172
        }
173
    );
174
    $builder->build(
175
        {
176
            source => 'IdentityProviderMapping',
177
            value  => { identity_provider_id => $provider->id, koha_field => 'email', provider_field => 'mail' }
178
        }
179
    );
180
181
    is( $provider->mappings->count, 2, 'The provider has 2 mappings defined' );
169
182
170
    $schema->storage->txn_rollback;
183
    $schema->storage->txn_rollback;
171
};
184
};
172
185
173
subtest 'set_mapping() tests' => sub {
186
subtest 'hostnames() tests' => sub {
174
187
175
    plan tests => 1;
188
    plan tests => 3;
176
189
177
    $schema->storage->txn_begin;
190
    $schema->storage->txn_begin;
178
191
179
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
192
    my $provider  = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
193
    my $hostnames = $provider->hostnames;
180
194
181
    my $mapping = { some => 'value', and => 'another' };
195
    is( ref($hostnames),   'Koha::Auth::Identity::Provider::Hostnames', 'Type is correct' );
182
    $provider->set_mapping($mapping)->store;
196
    is( $hostnames->count, 0,                                           'No hostnames defined' );
197
198
    $builder->build_object(
199
        { class => 'Koha::Auth::Identity::Provider::Hostnames', value => { identity_provider_id => $provider->id } } );
200
    $builder->build_object(
201
        { class => 'Koha::Auth::Identity::Provider::Hostnames', value => { identity_provider_id => $provider->id } } );
183
202
184
    is_deeply( $provider->get_mapping, $mapping, 'Mapping correctly retrieved' );
203
    is( $provider->hostnames->count, 2, 'The provider has 2 hostnames defined' );
185
204
186
    $schema->storage->txn_rollback;
205
    $schema->storage->txn_rollback;
187
};
206
};
188
207
189
subtest 'upgrade_class() tests' => sub {
208
subtest 'polymorphic_retrieval() tests' => sub {
190
209
191
    plan tests => 5;
210
    plan tests => 7;
192
211
193
    $schema->storage->txn_begin;
212
    $schema->storage->txn_begin;
194
213
195
    my $mapping   = Koha::Auth::Identity::Provider::protocol_to_class_mapping;
214
    my $providers = Koha::Auth::Identity::Providers->new;
215
    my $mapping   = $providers->_polymorphic_map;
196
    my @protocols = keys %{$mapping};
216
    my @protocols = keys %{$mapping};
197
217
198
    foreach my $protocol (@protocols) {
218
    foreach my $protocol (@protocols) {
Lines 204-223 subtest 'upgrade_class() tests' => sub { Link Here
204
            }
224
            }
205
        );
225
        );
206
226
207
        is( ref($provider), 'Koha::Auth::Identity::Provider', "Base class used for $protocol" );
227
        is( ref($provider), $mapping->{$protocol}, "build_object returns correct subclass for $protocol" );
208
228
209
        # upgrade
229
        my $found = Koha::Auth::Identity::Providers->find( $provider->id );
210
        $provider = $provider->upgrade_class;
230
        is( ref($found), $mapping->{$protocol}, "Providers->find returns correct subclass for $protocol" );
211
        is(
212
            ref($provider), $mapping->{$protocol},
213
            "Class upgraded to " . $mapping->{$protocol} . "for protocol $protocol"
214
        );
215
    }
231
    }
216
232
217
    my $provider = Koha::Auth::Identity::Provider->new( { protocol => 'Invalid' } );
233
    my $provider = Koha::Auth::Identity::Provider->new( { protocol => 'Invalid' } );
218
    throws_ok { $provider->upgrade }
234
    throws_ok { $provider->set_config( {} ) } 'Koha::Exception', 'Exception thrown calling set_config on base class';
219
    'Koha::Exception',
235
220
        'Exception throw on invalid protocol';
236
    $schema->storage->txn_rollback;
237
};
238
239
subtest 'find_forced_provider() tests' => sub {
240
241
    plan tests => 8;
242
243
    $schema->storage->txn_begin;
244
245
    # No hostname argument returns undef
246
    is( Koha::Auth::Identity::Providers->find_forced_provider(undef), undef, 'Returns undef when hostname is undef' );
247
    is(
248
        Koha::Auth::Identity::Providers->find_forced_provider(''), undef,
249
        'Returns undef when hostname is empty string'
250
    );
251
252
    my $provider = $builder->build_object(
253
        { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OIDC', enabled => 1 } } );
254
255
    my $hostname_record =
256
        $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => 'sso.example.com' } } );
257
258
    # Hostname linked but force_sso=0 (default)
259
    $builder->build_object(
260
        {
261
            class => 'Koha::Auth::Identity::Provider::Hostnames',
262
            value => {
263
                identity_provider_id => $provider->id,
264
                hostname_id          => $hostname_record->hostname_id,
265
                is_enabled           => 1,
266
                force_sso            => 0,
267
            }
268
        }
269
    );
270
    is(
271
        Koha::Auth::Identity::Providers->find_forced_provider('sso.example.com'),
272
        undef, 'Returns undef when hostname is linked but force_sso is 0'
273
    );
274
275
    # Update to force_sso=1 but is_enabled=0 on the hostname link
276
    Koha::Auth::Identity::Provider::Hostnames->search(
277
        { identity_provider_id => $provider->id, hostname_id => $hostname_record->hostname_id } )
278
        ->update( { force_sso => 1, is_enabled => 0 } );
279
    is(
280
        Koha::Auth::Identity::Providers->find_forced_provider('sso.example.com'),
281
        undef, 'Returns undef when hostname link has is_enabled=0'
282
    );
283
284
    # Enable the hostname link but disable the provider itself
285
    Koha::Auth::Identity::Provider::Hostnames->search(
286
        { identity_provider_id => $provider->id, hostname_id => $hostname_record->hostname_id } )
287
        ->update( { is_enabled => 1 } );
288
    $provider->update( { enabled => 0 } );
289
    is(
290
        Koha::Auth::Identity::Providers->find_forced_provider('sso.example.com'),
291
        undef, 'Returns undef when provider itself is disabled'
292
    );
293
294
    # Re-enable the provider - now all conditions met
295
    $provider->update( { enabled => 1 } );
296
    my $forced = Koha::Auth::Identity::Providers->find_forced_provider('sso.example.com');
297
    ok( $forced, 'Returns provider when hostname linked with force_sso=1, is_enabled=1, and provider enabled=1' );
298
    is(
299
        ref($forced), 'Koha::Auth::Identity::Provider::OIDC',
300
        'Returned object is the correct Identity Provider subclass'
301
    );
302
    is( $forced->id, $provider->id, 'Returns the correct provider' );
221
303
222
    $schema->storage->txn_rollback;
304
    $schema->storage->txn_rollback;
223
};
305
};
(-)a/t/db_dependent/Koha/Auth/Identity/Provider/Mapping.t (+140 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# Copyright Koha Community 2026
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 <https://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Test::NoWarnings;
23
use Test::More tests => 3;
24
use Test::Exception;
25
26
use Koha::Auth::Hostnames;
27
use Koha::Auth::Identity::Provider::Hostname;
28
use Koha::Auth::Identity::Provider::Mapping;
29
use Koha::Auth::Identity::Provider::Mappings;
30
use Koha::Auth::Identity::Providers;
31
32
use t::lib::TestBuilder;
33
34
my $schema  = Koha::Database->new->schema;
35
my $builder = t::lib::TestBuilder->new;
36
37
subtest 'Mapping::store() tests' => sub {
38
39
    plan tests => 4;
40
41
    $schema->storage->txn_begin;
42
43
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
44
45
    # Must throw if neither provider_field nor default_content is set
46
    throws_ok {
47
        Koha::Auth::Identity::Provider::Mapping->new(
48
            {
49
                identity_provider_id => $provider->id,
50
                koha_field           => 'userid',
51
            }
52
        )->store;
53
    }
54
    'Koha::Exceptions::MissingParameter',
55
        'Exception thrown when neither provider_field nor default_content is provided';
56
57
    like( $@->parameter, qr/provider_field or default_content/, 'Exception parameter message is correct' );
58
59
    # Succeeds with provider_field only
60
    my $m1 = Koha::Auth::Identity::Provider::Mapping->new(
61
        {
62
            identity_provider_id => $provider->id,
63
            koha_field           => 'userid',
64
            provider_field       => 'uid',
65
        }
66
    )->store;
67
    ok( $m1, 'store() succeeds when only provider_field is supplied' );
68
69
    # Succeeds with default_content only
70
    my $m2 = Koha::Auth::Identity::Provider::Mapping->new(
71
        {
72
            identity_provider_id => $provider->id,
73
            koha_field           => 'categorycode',
74
            default_content      => 'PT',
75
        }
76
    )->store;
77
    ok( $m2, 'store() succeeds when only default_content is supplied' );
78
79
    $schema->storage->txn_rollback;
80
};
81
82
subtest 'Mappings::as_auth_mapping() tests' => sub {
83
84
    plan tests => 3;
85
86
    $schema->storage->txn_begin;
87
88
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
89
90
    my $mapping = $provider->mappings->as_auth_mapping;
91
    is_deeply( $mapping, {}, 'Returns empty hashref when provider has no mappings' );
92
93
    # Create mappings: one with provider_field, one with default_content only
94
    $builder->build(
95
        {
96
            source => 'IdentityProviderMapping',
97
            value  => {
98
                identity_provider_id => $provider->id,
99
                koha_field           => 'userid',
100
                provider_field       => 'uid',
101
                default_content      => undef,
102
            }
103
        }
104
    );
105
    $builder->build(
106
        {
107
            source => 'IdentityProviderMapping',
108
            value  => {
109
                identity_provider_id => $provider->id,
110
                koha_field           => 'categorycode',
111
                provider_field       => undef,
112
                default_content      => 'PT',
113
            }
114
        }
115
    );
116
117
    $mapping = $provider->mappings->as_auth_mapping;
118
    is_deeply(
119
        $mapping,
120
        {
121
            userid       => { is => 'uid', content => undef },
122
            categorycode => { is => undef, content => 'PT' },
123
        },
124
        'Returns correct mapping hashref with is/content keys for each koha_field'
125
    );
126
127
    # Matchpoint is stored on the hostname association, not the provider
128
    my $hostname_obj = $builder->build_object(
129
        { class => 'Koha::Auth::Hostnames', value => { hostname => 'matchpoint.example.com' } } );
130
    my $hostname_assoc = Koha::Auth::Identity::Provider::Hostname->new(
131
        {
132
            identity_provider_id => $provider->id,
133
            hostname_id          => $hostname_obj->hostname_id,
134
            matchpoint           => 'userid',
135
        }
136
    )->store;
137
    is( $hostname_assoc->matchpoint, 'userid', 'Hostname matchpoint is stored and retrieved correctly' );
138
139
    $schema->storage->txn_rollback;
140
};
(-)a/t/db_dependent/Koha/Plugins/Auth/Client.t (-12 / +44 lines)
Lines 56-64 subtest 'auth_client_get_user hook tests' => sub { Link Here
56
    # Test Plugin manipulates mapped_data
56
    # Test Plugin manipulates mapped_data
57
    my $plugin = Koha::Plugin::Test->new->enable;
57
    my $plugin = Koha::Plugin::Test->new->enable;
58
58
59
    my $client = Koha::Auth::Client::OAuth->new;
59
    my $client   = Koha::Auth::Client::OAuth->new;
60
    my $provider =
60
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
61
        $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
61
    my $hostname_obj =
62
        $builder->build_object( { class => 'Koha::Auth::Hostnames', value => { hostname => 'test.library.com' } } );
63
    $builder->build_object(
64
        {
65
            class => 'Koha::Auth::Identity::Provider::Hostnames',
66
            value => {
67
                identity_provider_id => $provider->id,
68
                hostname_id          => $hostname_obj->id,
69
                matchpoint           => 'email',
70
            }
71
        }
72
    );
62
    my $domain = $builder->build_object(
73
    my $domain = $builder->build_object(
63
        {
74
        {
64
            class => 'Koha::Auth::Identity::Provider::Domains',
75
            class => 'Koha::Auth::Identity::Provider::Domains',
Lines 68-81 subtest 'auth_client_get_user hook tests' => sub { Link Here
68
            }
79
            }
69
        }
80
        }
70
    );
81
    );
71
    my $patron  = $builder->build_object( { class => 'Koha::Patrons', value => { email => 'patron@test.com' } } );
82
    my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { email => 'patron@test.com' } } );
72
    my $mapping = {
83
    $builder->build_object(
73
        email      => 'electronic_mail',
84
        {
74
        firstname  => 'given_name',
85
            class => 'Koha::Auth::Identity::Provider::Mappings',
75
        surname    => 'family_name',
86
            value =>
76
        cardnumber => 'cardnumber',
87
                { identity_provider_id => $provider->id, koha_field => 'email', provider_field => 'electronic_mail' }
77
    };
88
        }
78
    $provider->set_mapping($mapping)->store;
89
    );
90
    $builder->build_object(
91
        {
92
            class => 'Koha::Auth::Identity::Provider::Mappings',
93
            value =>
94
                { identity_provider_id => $provider->id, koha_field => 'firstname', provider_field => 'given_name' }
95
        }
96
    );
97
    $builder->build_object(
98
        {
99
            class => 'Koha::Auth::Identity::Provider::Mappings',
100
            value => { identity_provider_id => $provider->id, koha_field => 'surname', provider_field => 'family_name' }
101
        }
102
    );
103
    $builder->build_object(
104
        {
105
            class => 'Koha::Auth::Identity::Provider::Mappings',
106
            value =>
107
                { identity_provider_id => $provider->id, koha_field => 'cardnumber', provider_field => 'cardnumber' }
108
        }
109
    );
79
110
80
    my $id_token = 'header.' . encode_base64url(
111
    my $id_token = 'header.' . encode_base64url(
81
        encode_json(
112
        encode_json(
Lines 90-96 subtest 'auth_client_get_user hook tests' => sub { Link Here
90
    my $data = { id_token => $id_token };
121
    my $data = { id_token => $id_token };
91
122
92
    my ( $resolved_patron, $mapped_data, $resolved_domain ) =
123
    my ( $resolved_patron, $mapped_data, $resolved_domain ) =
93
        $client->get_user( { provider => $provider->code, data => $data, interface => 'opac' } );
124
        $client->get_user(
125
        { provider => $provider->code, data => $data, interface => 'opac', hostname => 'test.library.com' } );
94
    is( $mapped_data->{cardnumber}, '12345', 'Plugin manipulated mapped_data successfully' );
126
    is( $mapped_data->{cardnumber}, '12345', 'Plugin manipulated mapped_data successfully' );
95
    isnt( $resolved_patron->borrowernumber, $patron->borrowernumber, 'Plugin changed the resolved patron' );
127
    isnt( $resolved_patron->borrowernumber, $patron->borrowernumber, 'Plugin changed the resolved patron' );
96
    isnt( $resolved_domain->domain,         $domain->domain,         'Plugin changed the resolved domain' );
128
    isnt( $resolved_domain->domain,         $domain->domain,         'Plugin changed the resolved domain' );
(-)a/t/db_dependent/Koha/REST/Plugin/Auth/IdP.t (-3 / +1 lines)
Lines 105-112 subtest 'auth.register helper' => sub { Link Here
105
    $patron_to_delete_1->delete;
105
    $patron_to_delete_1->delete;
106
    $patron_to_delete_2->delete;
106
    $patron_to_delete_2->delete;
107
107
108
    my $provider =
108
    my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
109
        $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
110
109
111
    my $domain_1 = $builder->build_object(
110
    my $domain_1 = $builder->build_object(
112
        {
111
        {
113
- 

Return to bug 39224