mirror of
https://github.com/azaion/admin.git
synced 2026-04-22 22:16:33 +00:00
74f5594b0c
Made-with: Cursor
222 lines
7.5 KiB
C#
222 lines
7.5 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
using Azaion.E2E.Helpers;
|
|
using FluentAssertions;
|
|
using Xunit;
|
|
|
|
namespace Azaion.E2E.Tests;
|
|
|
|
[Collection("E2E")]
|
|
public sealed class UserManagementTests
|
|
{
|
|
private static readonly JsonSerializerOptions JsonOptions = new()
|
|
{
|
|
PropertyNameCaseInsensitive = true
|
|
};
|
|
|
|
private sealed record ErrorResponse(int ErrorCode, string Message);
|
|
private sealed record UserDto(Guid Id, string Email, int Role, bool IsEnabled);
|
|
|
|
private readonly TestFixture _fixture;
|
|
|
|
public UserManagementTests(TestFixture fixture) => _fixture = fixture;
|
|
|
|
private static string UserBasePath(string email) => $"/users/{Uri.EscapeDataString(email)}";
|
|
|
|
[Fact]
|
|
public async Task Registration_with_valid_data_succeeds()
|
|
{
|
|
var email = $"testuser-{Guid.NewGuid():N}@azaion.com";
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
try
|
|
{
|
|
// Arrange
|
|
var body = new { email, password = "SecurePass1!", role = 10 };
|
|
|
|
// Act
|
|
using var response = await client.PostAsync("/users", body);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
}
|
|
finally
|
|
{
|
|
using var deleteResponse = await client.DeleteAsync(UserBasePath(email));
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task List_users_returns_non_empty_array()
|
|
{
|
|
// Arrange
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
|
|
// Act
|
|
using var response = await client.GetAsync("/users");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
var users = await response.Content.ReadFromJsonAsync<UserDto[]>(JsonOptions);
|
|
users.Should().NotBeNull();
|
|
users!.Length.Should().BeGreaterThanOrEqualTo(1);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task List_users_filtered_by_email_contains_only_matches()
|
|
{
|
|
// Arrange
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
|
|
// Act
|
|
using var response = await client.GetAsync("/users?searchEmail=" + Uri.EscapeDataString("admin"));
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
var users = await response.Content.ReadFromJsonAsync<UserDto[]>(JsonOptions);
|
|
users.Should().NotBeNull();
|
|
users!.Should().NotBeEmpty();
|
|
users.Should().OnlyContain(u => u.Email.Contains("admin", StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Set_user_role_succeeds()
|
|
{
|
|
var email = $"testuser-{Guid.NewGuid():N}@azaion.com";
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
try
|
|
{
|
|
// Arrange
|
|
using (var createResp = await client.PostAsync("/users", new { email, password = "SecurePass1!", role = 10 }))
|
|
{
|
|
createResp.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
}
|
|
|
|
// Act
|
|
using var response = await client.PutAsync($"{UserBasePath(email)}/set-role/50");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
}
|
|
finally
|
|
{
|
|
using var deleteResponse = await client.DeleteAsync(UserBasePath(email));
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Disable_user_succeeds()
|
|
{
|
|
var email = $"testuser-{Guid.NewGuid():N}@azaion.com";
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
try
|
|
{
|
|
// Arrange
|
|
using (var createResp = await client.PostAsync("/users", new { email, password = "SecurePass1!", role = 10 }))
|
|
{
|
|
createResp.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
}
|
|
|
|
// Act
|
|
using var response = await client.PutAsync($"{UserBasePath(email)}/disable");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
}
|
|
finally
|
|
{
|
|
using var deleteResponse = await client.DeleteAsync(UserBasePath(email));
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Delete_user_succeeds_and_user_not_in_search_results()
|
|
{
|
|
var email = $"testuser-{Guid.NewGuid():N}@azaion.com";
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
try
|
|
{
|
|
// Arrange
|
|
using (var createResp = await client.PostAsync("/users", new { email, password = "SecurePass1!", role = 10 }))
|
|
{
|
|
createResp.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
}
|
|
|
|
// Act
|
|
using var deleteResponse = await client.DeleteAsync(UserBasePath(email));
|
|
|
|
// Assert
|
|
deleteResponse.StatusCode.Should().BeOneOf(HttpStatusCode.OK, HttpStatusCode.NoContent);
|
|
|
|
using var verifyResponse = await client.GetAsync("/users?searchEmail=" + Uri.EscapeDataString(email));
|
|
verifyResponse.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
var users = await verifyResponse.Content.ReadFromJsonAsync<UserDto[]>(JsonOptions);
|
|
users.Should().NotBeNull();
|
|
users!.Should().NotContain(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
|
|
}
|
|
finally
|
|
{
|
|
using var deleteResponse = await client.DeleteAsync(UserBasePath(email));
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Registration_rejects_empty_email_with_400()
|
|
{
|
|
// Arrange
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
|
|
// Act
|
|
using var response = await client.PostAsync("/users",
|
|
new { email = "", password = "ValidPass123", role = 10 });
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Registration_rejects_invalid_email_format_with_400()
|
|
{
|
|
// Arrange
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
|
|
// Act
|
|
using var response = await client.PostAsync("/users",
|
|
new { email = "notavalidemail", password = "ValidPass123", role = 10 });
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Registration_rejects_short_password_with_400()
|
|
{
|
|
// Arrange
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
|
|
// Act
|
|
using var response = await client.PostAsync("/users",
|
|
new { email = "validmail@test.com", password = "short", role = 10 });
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Registration_rejects_duplicate_admin_email_with_409()
|
|
{
|
|
// Arrange
|
|
using var client = _fixture.CreateAuthenticatedClient(_fixture.AdminToken);
|
|
|
|
// Act
|
|
using var response = await client.PostAsync("/users",
|
|
new { email = _fixture.AdminEmail, password = "DuplicateP1!", role = 10 });
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.Conflict);
|
|
var err = await response.Content.ReadFromJsonAsync<ErrorResponse>(JsonOptions);
|
|
err.Should().NotBeNull();
|
|
err!.ErrorCode.Should().Be(20);
|
|
}
|
|
}
|