Bugzilla – Attachment 186630 Details for
Bug 33782
OAuth2/OIDC identity providers code is not covered by unit tests
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 33782: Add unit tests for Koha::Auth::Client::OAuth
Bug-33782-Add-unit-tests-for-KohaAuthClientOAuth.patch (text/plain), 8.73 KB, created by
Tomás Cohen Arazi (tcohen)
on 2025-09-20 14:32:48 UTC
(
hide
)
Description:
Bug 33782: Add unit tests for Koha::Auth::Client::OAuth
Filename:
MIME Type:
Creator:
Tomás Cohen Arazi (tcohen)
Created:
2025-09-20 14:32:48 UTC
Size:
8.73 KB
patch
obsolete
>From 94c81145a55cc5c04abbcf3d701ab2b9083e27ae Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Tom=C3=A1s=20Cohen=20Arazi?= <tomascohen@theke.io> >Date: Sat, 20 Sep 2025 11:22:54 -0300 >Subject: [PATCH] Bug 33782: Add unit tests for Koha::Auth::Client::OAuth > >This patch adds comprehensive unit tests for the OAuth authentication >client, specifically covering the _get_data_and_patron method which >handles JWT token processing and UserInfo endpoint integration. > >Test plan: >1. Apply patch >2. Run: > $ ktd --shell > k$ prove t/db_dependent/Koha/Auth/Client/OAuth.t >=> SUCCESS: Tests pass! >3. Tests cover: > - JWT id_token processing and patron matching > - UserInfo endpoint calls and data merging > - Non-existent user scenarios > - Combined JWT + UserInfo data sources >4. Sign off :-D >--- > t/db_dependent/Koha/Auth/Client/OAuth.t | 257 ++++++++++++++++++++++++ > 1 file changed, 257 insertions(+) > create mode 100755 t/db_dependent/Koha/Auth/Client/OAuth.t > >diff --git a/t/db_dependent/Koha/Auth/Client/OAuth.t b/t/db_dependent/Koha/Auth/Client/OAuth.t >new file mode 100755 >index 0000000000..0da9a83fe7 >--- /dev/null >+++ b/t/db_dependent/Koha/Auth/Client/OAuth.t >@@ -0,0 +1,257 @@ >+#!/usr/bin/perl >+ >+# Copyright 2025 Koha Development Team >+# >+# This file is part of Koha >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Test::More tests => 4; >+use Test::MockModule; >+use Test::NoWarnings; >+ >+use JSON qw(encode_json); >+use MIME::Base64 qw(encode_base64url); >+ >+use Koha::Auth::Client::OAuth; >+use Koha::Database; >+ >+use t::lib::TestBuilder; >+ >+my $schema = Koha::Database->new->schema; >+my $builder = t::lib::TestBuilder->new; >+ >+subtest '_get_data_and_patron() with id_token tests' => sub { >+ plan tests => 4; >+ >+ $schema->storage->txn_begin; >+ >+ my $client = Koha::Auth::Client::OAuth->new; >+ >+ # Create test patron >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { email => 'test@example.com' } >+ } >+ ); >+ >+ # Create provider with email matchpoint >+ my $provider = $builder->build_object( >+ { >+ class => 'Koha::Auth::Identity::Providers', >+ value => { >+ matchpoint => 'email', >+ mapping => encode_json( >+ { >+ email => 'mail', >+ firstname => 'given_name', >+ surname => 'family_name' >+ } >+ ) >+ } >+ } >+ ); >+ >+ # Create JWT token with user data >+ my $claims = { >+ mail => 'test@example.com', >+ given_name => 'John', >+ family_name => 'Doe' >+ }; >+ >+ my $id_token = 'header.' . encode_base64url( encode_json($claims) ) . '.signature'; >+ >+ my $data = { id_token => $id_token }; >+ my $config = {}; >+ >+ # Test the method >+ my ( $mapped_data, $found_patron ) = $client->_get_data_and_patron( >+ { >+ provider => $provider, >+ data => $data, >+ config => $config >+ } >+ ); >+ >+ # Verify results >+ is( $mapped_data->{email}, 'test@example.com', 'Email mapped correctly' ); >+ is( $mapped_data->{firstname}, 'John', 'First name mapped correctly' ); >+ is( $mapped_data->{surname}, 'Doe', 'Surname mapped correctly' ); >+ is( $found_patron->id, $patron->id, 'Patron found by email matchpoint' ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest '_get_data_and_patron() with userinfo_url tests' => sub { >+ plan tests => 5; >+ >+ $schema->storage->txn_begin; >+ >+ my $client = Koha::Auth::Client::OAuth->new; >+ >+ # Create test patron >+ my $patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { email => 'userinfo@example.com' } >+ } >+ ); >+ >+ # Create provider with email matchpoint >+ my $provider = $builder->build_object( >+ { >+ class => 'Koha::Auth::Identity::Providers', >+ value => { >+ matchpoint => 'email', >+ mapping => encode_json( >+ { >+ email => 'email', >+ firstname => 'first_name' >+ } >+ ) >+ } >+ } >+ ); >+ >+ # Mock UserAgent for userinfo endpoint >+ my $ua_mock = Test::MockModule->new('Mojo::UserAgent'); >+ my $tx_mock = Test::MockModule->new('Mojo::Transaction::HTTP'); >+ my $res_mock = Test::MockModule->new('Mojo::Message::Response'); >+ my $headers_mock = Test::MockModule->new('Mojo::Headers'); >+ >+ $headers_mock->mock( 'content_type', sub { 'application/json' } ); >+ $res_mock->mock( 'code', sub { '200' } ); >+ $res_mock->mock( >+ 'json', >+ sub { >+ return { >+ email => 'userinfo@example.com', >+ first_name => 'Jane' >+ }; >+ } >+ ); >+ $res_mock->mock( >+ 'headers', >+ sub { >+ my $headers = {}; >+ bless $headers, 'Mojo::Headers'; >+ return $headers; >+ } >+ ); >+ >+ $tx_mock->mock( >+ 'res', >+ sub { >+ my $res = {}; >+ bless $res, 'Mojo::Message::Response'; >+ return $res; >+ } >+ ); >+ >+ $ua_mock->mock( >+ 'get', >+ sub { >+ my $tx = {}; >+ bless $tx, 'Mojo::Transaction::HTTP'; >+ return $tx; >+ } >+ ); >+ >+ my $data = { access_token => 'test_token' }; >+ my $config = { userinfo_url => 'https://provider.com/userinfo' }; >+ >+ # Test the method >+ my ( $mapped_data, $found_patron ) = $client->_get_data_and_patron( >+ { >+ provider => $provider, >+ data => $data, >+ config => $config >+ } >+ ); >+ >+ # Verify results >+ is( $mapped_data->{email}, 'userinfo@example.com', 'Email mapped from userinfo' ); >+ is( $mapped_data->{firstname}, 'Jane', 'First name mapped from userinfo' ); >+ is( $found_patron->id, $patron->id, 'Patron found by email from userinfo' ); >+ >+ # Test with both id_token and userinfo (patron should be found from id_token first) >+ my $id_token_claims = { email => 'token@example.com' }; >+ my $id_token = 'header.' . encode_base64url( encode_json($id_token_claims) ) . '.signature'; >+ >+ my $token_patron = $builder->build_object( >+ { >+ class => 'Koha::Patrons', >+ value => { email => 'token@example.com' } >+ } >+ ); >+ >+ $data->{id_token} = $id_token; >+ >+ ( $mapped_data, $found_patron ) = $client->_get_data_and_patron( >+ { >+ provider => $provider, >+ data => $data, >+ config => $config >+ } >+ ); >+ >+ is( $found_patron->id, $token_patron->id, 'Patron found from id_token takes precedence' ); >+ is( $mapped_data->{email}, 'userinfo@example.com', 'But userinfo data still merged' ); >+ >+ $schema->storage->txn_rollback; >+}; >+ >+subtest '_get_data_and_patron() no patron found tests' => sub { >+ plan tests => 2; >+ >+ $schema->storage->txn_begin; >+ >+ my $client = Koha::Auth::Client::OAuth->new; >+ >+ # Create provider >+ my $provider = $builder->build_object( >+ { >+ class => 'Koha::Auth::Identity::Providers', >+ value => { >+ matchpoint => 'email', >+ mapping => encode_json( { email => 'mail' } ) >+ } >+ } >+ ); >+ >+ # Create token for non-existent user >+ my $claims = { mail => 'nonexistent@example.com' }; >+ my $id_token = 'header.' . encode_base64url( encode_json($claims) ) . '.signature'; >+ >+ my $data = { id_token => $id_token }; >+ my $config = {}; >+ >+ # Test the method >+ my ( $mapped_data, $found_patron ) = $client->_get_data_and_patron( >+ { >+ provider => $provider, >+ data => $data, >+ config => $config >+ } >+ ); >+ >+ # Verify results >+ is( $mapped_data->{email}, 'nonexistent@example.com', 'Email mapped correctly' ); >+ is( $found_patron, undef, 'No patron found for non-existent email' ); >+ >+ $schema->storage->txn_rollback; >+}; >-- >2.51.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 33782
: 186630 |
186631