using Books.Api.Banking; using AwesomeAssertions; using Microsoft.Extensions.Logging.Abstractions; namespace Books.Api.Tests.Integration; /// /// Integration tests for Enable Banking API client. /// These tests call the real Enable Banking API. /// [Trait("Category", "Integration")] public class EnableBankingClientTests : IDisposable { private readonly EnableBankingClient _client; private readonly HttpClient _httpClient; public EnableBankingClientTests() { var options = new EnableBankingOptions { ApplicationId = "0bafa28d-41ea-4275-a4d5-221a78c72350", KeyId = "0bafa28d-41ea-4275-a4d5-221a78c72350", PrivateKey = File.ReadAllText(Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "projects/ledger/private.key")) }; _httpClient = new HttpClient { BaseAddress = new Uri("https://api.enablebanking.com") }; _client = new EnableBankingClient(_httpClient, options, NullLogger.Instance); } public void Dispose() { _client.Dispose(); _httpClient.Dispose(); } [Fact] public async Task GetAspsps_ReturnsDanishBanks() { // Act var banks = await _client.GetAspspsAsync("DK"); // Assert banks.Should().NotBeEmpty(); banks.Should().Contain(b => b.Name.Contains("Danske", StringComparison.OrdinalIgnoreCase)); } [Fact(Skip = "Requires redirect URL to be registered in Enable Banking dashboard")] public async Task StartAuthorization_WithRegisteredRedirectUrl_ReturnsAuthorizationUrl() { // Arrange - First get actual bank name from API var banks = await _client.GetAspspsAsync("DK"); var danskeBank = banks.FirstOrDefault(b => b.Name.Contains("Danske", StringComparison.OrdinalIgnoreCase)); danskeBank.Should().NotBeNull("Danske Bank should exist in available banks"); // Note: This redirect URL must be registered in Enable Banking dashboard // Configure at: https://enablebanking.com/dashboard var redirectUrl = "https://your-registered-url.com/callback"; var state = Guid.NewGuid().ToString(); // Act var result = await _client.StartAuthorizationAsync( aspspName: danskeBank!.Name, redirectUrl: redirectUrl, state: state, psuType: "personal"); // Assert result.Should().NotBeNull(); result.AuthorizationId.Should().NotBeNullOrEmpty(); result.Url.Should().StartWith("https://"); } [Fact] public async Task StartAuthorization_WithUnregisteredRedirectUrl_ThrowsExpectedError() { // Arrange var banks = await _client.GetAspspsAsync("DK"); var bank = banks.First(); var unregisteredRedirectUrl = "https://unregistered-domain.example.com/callback"; var state = Guid.NewGuid().ToString(); // Act var act = async () => await _client.StartAuthorizationAsync( aspspName: bank.Name, redirectUrl: unregisteredRedirectUrl, state: state, psuType: "personal"); // Assert - Should get REDIRECT_URI_NOT_ALLOWED error (proves API auth works) var exception = await act.Should().ThrowAsync(); exception.Which.Message.Should().Contain("REDIRECT_URI_NOT_ALLOWED"); } }