bff947d1e8
Add 5 integration tests for AuthApiClient: - GetPublicKeyAsync_ReturnsValidPublicKey - LoginAsync_WithValidCredentials_ReturnsSuccess - GetCurrentUserAsync_AfterLogin_ReturnsUserInfo - GetCurrentUserAsync_WithoutAuth_ReturnsUnauthorized - LogoutAsync_AfterLogin_InvalidatesSession Tests use RSA encryption pattern for login credentials and verify auth cookie behavior across requests.
112 lines
3.9 KiB
C#
112 lines
3.9 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;
|
|
using Shouldly;
|
|
|
|
namespace JdeScoping.Api.IntegrationTests.ClientIntegration;
|
|
|
|
public class AuthApiClientIntegrationTests : ClientIntegrationTestBase
|
|
{
|
|
public AuthApiClientIntegrationTests(TestWebApplicationFactory factory) : base(factory) { }
|
|
|
|
[Fact]
|
|
public async Task GetPublicKeyAsync_ReturnsValidPublicKey()
|
|
{
|
|
// Act
|
|
var result = await AuthClient.GetPublicKeyAsync();
|
|
|
|
// Assert
|
|
result.IsSuccess.ShouldBeTrue();
|
|
result.Value.PublicKeyPem.ShouldStartWith("-----BEGIN PUBLIC KEY-----");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task LoginAsync_WithValidCredentials_ReturnsSuccess()
|
|
{
|
|
// Arrange - get public key and encrypt credentials
|
|
var publicKeyResult = await AuthClient.GetPublicKeyAsync();
|
|
publicKeyResult.IsSuccess.ShouldBeTrue();
|
|
|
|
var loginModel = new LoginModel { Username = "testuser", Password = "testpass" };
|
|
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);
|
|
|
|
var encryptedRequest = new EncryptedLoginRequest(Convert.ToBase64String(ciphertext));
|
|
|
|
// Act
|
|
var result = await AuthClient.LoginAsync(encryptedRequest);
|
|
|
|
// Assert
|
|
result.IsSuccess.ShouldBeTrue();
|
|
result.Value.Success.ShouldBeTrue();
|
|
result.Value.User.ShouldNotBeNull();
|
|
result.Value.User.Username.ShouldBe("testuser");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetCurrentUserAsync_AfterLogin_ReturnsUserInfo()
|
|
{
|
|
// Arrange
|
|
await LoginAsync();
|
|
|
|
// Act
|
|
var result = await AuthClient.GetCurrentUserAsync();
|
|
|
|
// Assert
|
|
result.IsSuccess.ShouldBeTrue();
|
|
result.Value.Username.ShouldBe("testuser");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetCurrentUserAsync_WithoutAuth_ReturnsUnauthorized()
|
|
{
|
|
// Arrange - use fresh client without cookies
|
|
var freshClient = new AuthApiClient(CreateFreshClient());
|
|
|
|
// Act
|
|
var result = await freshClient.GetCurrentUserAsync();
|
|
|
|
// Assert
|
|
result.IsUnauthorized.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task LogoutAsync_AfterLogin_InvalidatesSession()
|
|
{
|
|
// Arrange - create fresh client for this test to avoid affecting other tests
|
|
var client = Factory.CreateClient(new WebApplicationFactoryClientOptions
|
|
{
|
|
HandleCookies = true,
|
|
AllowAutoRedirect = false
|
|
});
|
|
var authClient = new AuthApiClient(client);
|
|
|
|
// Login first
|
|
var publicKeyResult = await authClient.GetPublicKeyAsync();
|
|
var loginModel = new LoginModel { Username = "testuser", Password = "testpass" };
|
|
var json = JsonSerializer.Serialize(loginModel);
|
|
using var rsa = RSA.Create();
|
|
rsa.ImportFromPem(publicKeyResult.Value.PublicKeyPem);
|
|
var ciphertext = rsa.Encrypt(Encoding.UTF8.GetBytes(json), RSAEncryptionPadding.OaepSHA256);
|
|
await authClient.LoginAsync(new EncryptedLoginRequest(Convert.ToBase64String(ciphertext)));
|
|
|
|
// Verify login worked
|
|
var beforeLogout = await authClient.GetCurrentUserAsync();
|
|
beforeLogout.IsSuccess.ShouldBeTrue();
|
|
|
|
// Act - call logout (server returns 200 OK with empty body)
|
|
await authClient.LogoutAsync();
|
|
|
|
// Assert - verify session is invalidated (me endpoint should return unauthorized)
|
|
var meResult = await authClient.GetCurrentUserAsync();
|
|
meResult.IsUnauthorized.ShouldBeTrue();
|
|
}
|
|
}
|