Catalyst-Plugin-OpenIDConnect
view release on metacpan or search on metacpan
t/03_plugin.t view on Meta::CPAN
# Test get_user_claims() with hash-based user object
my $hash_user = {
id => 'user-123',
full_name => 'John Doe',
email_address => 'john@example.com',
avatar => {
url => 'http://example.com/avatar.jpg',
},
};
my $hash_claims = $context->get_user_claims($hash_user);
ok($hash_claims, 'get_user_claims() works with hash user');
is($hash_claims->{sub}, 'user-123', 'sub claim correct');
is($hash_claims->{name}, 'John Doe', 'name claim correct');
is($hash_claims->{email}, 'john@example.com', 'email claim correct');
is($hash_claims->{picture}, 'http://example.com/avatar.jpg', 'picture claim with nested access');
# Test get_user_claims() with object-based user
package TestUser;
use Moose;
has id => (is => 'ro', default => 'user-456');
has full_name => (is => 'ro', default => 'Jane Doe');
has email_address => (is => 'ro', default => 'jane@example.com');
package main;
my $obj_user = TestUser->new();
my $obj_claims = $context->get_user_claims($obj_user);
ok($obj_claims, 'get_user_claims() works with object user');
is($obj_claims->{sub}, 'user-456', 'sub claim from object');
is($obj_claims->{name}, 'Jane Doe', 'name claim from object');
is($obj_claims->{email}, 'jane@example.com', 'email claim from object');
# Test get_user_claims() with default claims config
my $context_default = Catalyst::Plugin::OpenIDConnect::Context->new(
catalyst => MockCatalyst->new(
config => {
'Plugin::OpenIDConnect' => {},
},
),
);
my $default_user = {
id => '789',
name => 'Bob Smith',
email => 'bob@example.com',
};
my $default_claims = $context_default->get_user_claims($default_user);
ok($default_claims, 'get_user_claims() with default config');
is($default_claims->{sub}, '789', 'default sub claim');
is($default_claims->{name}, 'Bob Smith', 'default name claim');
is($default_claims->{email}, 'bob@example.com', 'default email claim');
# Test get_discovery() method
my $discovery = $context->get_discovery();
ok($discovery, 'get_discovery() returns structure');
is($discovery->{issuer}, 'http://localhost:5000', 'issuer in discovery');
like($discovery->{authorization_endpoint}, qr/authorize/, 'authorization_endpoint');
like($discovery->{token_endpoint}, qr/token/, 'token_endpoint');
like($discovery->{userinfo_endpoint}, qr/userinfo/, 'userinfo_endpoint');
like($discovery->{jwks_uri}, qr/jwks/, 'jwks_uri');
# Check scopes
my @scopes = @{ $discovery->{scopes_supported} };
ok(grep { $_ eq 'openid' } @scopes, 'openid scope supported');
ok(grep { $_ eq 'profile' } @scopes, 'profile scope supported');
ok(grep { $_ eq 'email' } @scopes, 'email scope supported');
# 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
# ---------------------------------------------------------------------------
( run in 0.808 second using v1.01-cache-2.11-cpan-9581c071862 )