Catalyst-Plugin-OpenIDConnect
view release on metacpan or search on metacpan
t/03_plugin.t view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Catalyst::Plugin::OpenIDConnect;
use Catalyst::Plugin::OpenIDConnect::Context;
use Catalyst::Plugin::OpenIDConnect::Utils::JWT;
use Catalyst::Plugin::OpenIDConnect::Utils::Store;
use Crypt::OpenSSL::RSA;
use File::Temp qw(tempfile);
use JSON::MaybeXS qw(encode_json);
# Generate test keys
my $rsa = Crypt::OpenSSL::RSA->generate_key(1024);
my $private_key = $rsa;
my $public_key = Crypt::OpenSSL::RSA->new_public_key(
$rsa->get_public_key_string()
);
# Create JWT handler for testing context methods
my $jwt = Catalyst::Plugin::OpenIDConnect::Utils::JWT->new(
private_key => $private_key,
public_key => $public_key,
key_id => 'test-key',
issuer => 'http://localhost:5000',
);
ok($jwt, 'JWT handler created');
# Create store for testing context methods
my $store = Catalyst::Plugin::OpenIDConnect::Utils::Store->new();
ok($store, 'Store created');
# Test _OpenIDConnectContext (the context object)
require_ok('Catalyst::Plugin::OpenIDConnect');
# Create a mock Catalyst object for testing the context
package MockCatalyst;
use Moose;
has config => (
is => 'ro',
isa => 'HashRef',
default => sub { {} },
);
has _oidc_jwt => (
is => 'rw',
);
has _oidc_store => (
is => 'rw',
);
has log => (
is => 'ro',
isa => 'MockLogger',
default => sub { MockLogger->new() },
);
sub uri_for {
my ($self, $path) = @_;
return bless { path => $path }, 'MockURI';
}
package MockLogger;
use Moose;
sub debug {
my ($self, $msg) = @_;
# Silently log or do nothing for testing
}
sub info {
my ($self, $msg) = @_;
# Silently log or do nothing for testing
}
sub warn {
my ($self, $msg) = @_;
# Silently log or do nothing for testing
}
t/03_plugin.t view on Meta::CPAN
# Check algorithms
is_deeply(
$discovery->{id_token_signing_alg_values_supported},
['RS256'],
'RS256 algorithm supported for ID tokens'
);
# Check claims
my @claims = @{ $discovery->{claims_supported} };
ok(grep { $_ eq 'sub' } @claims, 'sub claim supported');
ok(grep { $_ eq 'email' } @claims, 'email claim supported');
ok(grep { $_ eq 'picture' } @claims, 'picture claim supported');
# Verify discovery contains required fields
ok($discovery->{response_types_supported}, 'response_types_supported present');
ok($discovery->{grant_types_supported}, 'grant_types_supported present');
ok($discovery->{subject_types_supported}, 'subject_types_supported present');
# Test get_discovery() with custom issuer URL
my $custom_issuer_context = Catalyst::Plugin::OpenIDConnect::Context->new(
catalyst => MockCatalyst->new(
config => {
'Plugin::OpenIDConnect' => {
issuer => {
url => 'https://auth.example.com',
},
},
},
),
);
my $custom_discovery = $custom_issuer_context->get_discovery();
is($custom_discovery->{issuer}, 'https://auth.example.com', 'custom issuer URL in discovery');
# Test empty config handling
my $empty_context = Catalyst::Plugin::OpenIDConnect::Context->new(
catalyst => MockCatalyst->new(
config => {},
),
);
ok($empty_context->config, 'config() handles empty configuration');
is_deeply($empty_context->config, {}, 'empty config returns empty hashref');
# Test get_client with empty clients config
my $empty_client = $empty_context->get_client('any-client');
is($empty_client, undef, 'get_client() handles empty clients config');
# ---------------------------------------------------------------------------
# MED-3: JWT and Store instances are isolated per consuming application class
# ---------------------------------------------------------------------------
{
my $app_a = bless {}, 'FakeAppAlpha';
my $app_b = bless {}, 'FakeAppBeta';
# Create a second distinct JWT instance for app_b
my $rsa_b = Crypt::OpenSSL::RSA->generate_key(1024);
my $jwt_b = Catalyst::Plugin::OpenIDConnect::Utils::JWT->new(
private_key => $rsa_b,
public_key => Crypt::OpenSSL::RSA->new_public_key( $rsa_b->get_public_key_string() ),
key_id => 'key-b',
issuer => 'http://b.example.com',
);
Catalyst::Plugin::OpenIDConnect::_oidc_jwt( $app_a, $jwt );
Catalyst::Plugin::OpenIDConnect::_oidc_jwt( $app_b, $jwt_b );
is(
Catalyst::Plugin::OpenIDConnect::_oidc_jwt($app_a), $jwt,
'MED-3: FakeAppAlpha holds its own JWT instance',
);
is(
Catalyst::Plugin::OpenIDConnect::_oidc_jwt($app_b), $jwt_b,
'MED-3: FakeAppBeta holds its own JWT instance',
);
isnt(
Catalyst::Plugin::OpenIDConnect::_oidc_jwt($app_a),
Catalyst::Plugin::OpenIDConnect::_oidc_jwt($app_b),
'MED-3: JWT instances are isolated between application classes',
);
}
# ---------------------------------------------------------------------------
# MED-4: Implicit grant/response types removed from discovery document
# ---------------------------------------------------------------------------
{
my $grant_types = $discovery->{grant_types_supported};
my $response_types = $discovery->{response_types_supported};
ok(
!grep { $_ eq 'implicit' } @$grant_types,
'MED-4: implicit not in grant_types_supported',
);
ok(
scalar( grep { $_ eq 'authorization_code' } @$grant_types ),
'authorization_code still in grant_types_supported',
);
ok(
!grep { $_ eq 'id_token' || $_ eq 'token' } @$response_types,
'MED-4: implicit response types (id_token, token) not in response_types_supported',
);
ok(
scalar( grep { $_ eq 'code' } @$response_types ),
'code still in response_types_supported',
);
}
done_testing();
( run in 0.338 second using v1.01-cache-2.11-cpan-13bb782fe5a )