78 lines
3.0 KiB
C#
78 lines
3.0 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using JdeScoping.Client.Services;
|
|
using JdeScoping.Core.Models.Auth;
|
|
using Microsoft.AspNetCore.Mvc.Testing;
|
|
|
|
namespace JdeScoping.Api.IntegrationTests.ClientIntegration;
|
|
|
|
/// <summary>
|
|
/// Base class for API client integration tests.
|
|
/// Provides shared HttpClient with cookie handling for auth state.
|
|
/// </summary>
|
|
[Collection("ClientIntegration")]
|
|
public abstract class ClientIntegrationTestBase : IClassFixture<TestWebApplicationFactory>
|
|
{
|
|
protected readonly TestWebApplicationFactory Factory;
|
|
protected readonly HttpClient SharedClient;
|
|
|
|
// API clients share the authenticated HttpClient
|
|
protected readonly SearchApiClient SearchClient;
|
|
protected readonly LookupApiClient LookupClient;
|
|
protected readonly AuthApiClient AuthClient;
|
|
protected readonly FileApiClient FileClient;
|
|
|
|
protected ClientIntegrationTestBase(TestWebApplicationFactory factory)
|
|
{
|
|
Factory = factory;
|
|
SharedClient = factory.CreateClient(new WebApplicationFactoryClientOptions
|
|
{
|
|
HandleCookies = true,
|
|
AllowAutoRedirect = false
|
|
});
|
|
|
|
// All clients share the same HttpClient (cookie container)
|
|
SearchClient = new SearchApiClient(SharedClient);
|
|
LookupClient = new LookupApiClient(SharedClient);
|
|
FileClient = new FileApiClient(SharedClient);
|
|
AuthClient = new AuthApiClient(SharedClient);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs login with encrypted credentials.
|
|
/// </summary>
|
|
protected async Task LoginAsync(string username = "testuser", string password = "testpass")
|
|
{
|
|
// Step 1: Get public key
|
|
var publicKeyResult = await AuthClient.GetPublicKeyAsync();
|
|
if (!publicKeyResult.IsSuccess)
|
|
throw new Exception("Failed to get public key");
|
|
|
|
// Step 2: Encrypt credentials
|
|
var loginModel = new LoginModel { Username = username, Password = password };
|
|
var json = JsonSerializer.Serialize(loginModel);
|
|
var plaintext = Encoding.UTF8.GetBytes(json);
|
|
|
|
using var rsa = RSA.Create();
|
|
rsa.ImportFromPem(publicKeyResult.Value.PublicKeyPem);
|
|
var ciphertext = rsa.Encrypt(plaintext, RSAEncryptionPadding.OaepSHA256);
|
|
|
|
// Step 3: Login
|
|
var encryptedRequest = new EncryptedLoginRequest(Convert.ToBase64String(ciphertext));
|
|
var loginResult = await AuthClient.LoginAsync(encryptedRequest);
|
|
|
|
if (!loginResult.IsSuccess || !loginResult.Value.Success)
|
|
throw new Exception($"Login failed: {loginResult.Value?.ErrorMessage ?? "Unknown error"}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a fresh HttpClient without cookies for testing unauthorized scenarios.
|
|
/// </summary>
|
|
protected HttpClient CreateFreshClient() => Factory.CreateClient(new WebApplicationFactoryClientOptions
|
|
{
|
|
HandleCookies = false,
|
|
AllowAutoRedirect = false
|
|
});
|
|
}
|