feat(oidc): a fake provider for hosts' tests (testing.dart)

The module's test provider moves into `package:halkyon_oidc_server/testing.dart`,
so a host tests its own sign-in against the module's real checks rather than
a copy: `TestKey` makes and publishes an RSA key and signs ID tokens with
headers written by hand (no `typ`, as SimpleLogin's), and `FakeProvider`
answers discovery, the keys and the token endpoint through an HTTP client
the host hands the module. `FakeProvider.simpleLogin` has SimpleLogin's
issuer and endpoints, without PKCE, as the preset expects; a test now signs
in through the preset end to end. pointycastle, already in the lock through
dart_jsonwebtoken, becomes a dependency for it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-23 20:33:13 +02:00
commit 54c0b3f7b8
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -3,12 +3,11 @@ import 'dart:io';
import 'package:clock/clock.dart';
import 'package:halkyon_oidc_server/oidc.dart';
import 'package:halkyon_oidc_server/testing.dart';
import 'package:serverpod/serverpod.dart';
import 'package:serverpod_auth_idp_server/core.dart';
import 'package:test/test.dart';
import '../support/fake_provider.dart';
import '../support/test_provider.dart';
import 'test_tools/serverpod_test_tools.dart';
// Signing in with an OpenID Connect provider (ADR 0023): an attempt begun,
@ -671,6 +670,35 @@ void main() {
});
});
test("SimpleLogin's preset signs in as SimpleLogin has it: its "
'endpoints, no PKCE, no discovery', () async {
useProvider(
FakeProvider.simpleLogin(
key: key,
clientId: 'halkyon',
clientSecret: 'secret-2',
callbackUrl: Uri.parse('https://learn.example/simplelogin-callback'),
),
);
final start = await idp.begin(session, provider: 'simplelogin');
final url = start.authorizationUrl;
expect(
'${url.origin}${url.path}',
'https://app.simplelogin.io/oauth2/authorize',
);
expect(url.queryParameters, isNot(contains('code_challenge')));
final identity = await idp.verify(
session,
attempt: start.attempt,
code: fake.authorize(url, subject: 'sl-1'),
);
expect((identity.provider, identity.subject), ('simplelogin', 'sl-1'));
expect(fake.tokenRequests.single.url.path, '/oauth2/token');
expect(fake.discoveries, 0);
});
test('forgets attempts whose time ran out', () async {
await idp.begin(session, provider: 'fake');
final (:attempt, :code) = await allowed('42');