Files
pos-system/services/membership-service-net/tests/MembershipService.FunctionalTests/Controllers/MembersControllerTests.cs

270 lines
7.6 KiB
C#

using System.Net;
using System.Net.Http.Json;
using FluentAssertions;
using MembershipService.API.Application.Commands;
using MembershipService.API.Application.Queries;
using Xunit;
namespace MembershipService.FunctionalTests.Controllers;
/// <summary>
/// EN: Comprehensive functional tests for MembersController.
/// VI: Functional tests toàn diện cho MembersController.
/// </summary>
public class MembersControllerTests : IClassFixture<CustomWebApplicationFactory>
{
private readonly CustomWebApplicationFactory _factory;
public MembersControllerTests(CustomWebApplicationFactory factory)
{
_factory = factory;
}
#region GET /api/v1/members
[Fact]
public async Task GetMembers_WithoutAuth_ShouldReturnUnauthorized()
{
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync("/api/v1/members?page=1&pageSize=10");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task GetMembers_WithAuth_ShouldReturnOk()
{
// Arrange
var client = _factory.CreateAuthenticatedClient();
// Act
var response = await client.GetAsync("/api/v1/members?page=1&pageSize=10");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
}
#endregion
#region GET /api/v1/members/{id}
[Fact]
public async Task GetMemberById_WithoutAuth_ShouldReturnUnauthorized()
{
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync($"/api/v1/members/{Guid.NewGuid()}");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task GetMemberById_NonExistent_ShouldReturnNotFound()
{
// Arrange
var client = _factory.CreateAuthenticatedClient();
// Act
var response = await client.GetAsync($"/api/v1/members/{Guid.NewGuid()}");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
}
#endregion
#region POST /api/v1/members
[Fact]
public async Task CreateMember_WithoutAuth_ShouldReturnUnauthorized()
{
// Arrange
var client = _factory.CreateClient();
var command = new CreateMemberCommand
{
UserId = Guid.NewGuid(),
CountryCode = "VN"
};
// Act
var response = await client.PostAsJsonAsync("/api/v1/members", command);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task CreateMember_ValidRequest_ShouldReturnCreated()
{
// Arrange
var client = _factory.CreateAuthenticatedClient();
var userId = Guid.NewGuid();
var command = new CreateMemberCommand
{
UserId = userId,
CountryCode = "VN"
};
// Act
var response = await client.PostAsJsonAsync("/api/v1/members", command);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Created);
var result = await response.Content.ReadFromJsonAsync<CreateMemberResult>();
result.Should().NotBeNull();
result!.MemberId.Should().Be(userId);
result.CurrentLevel.Should().Be(1);
}
[Fact]
public async Task CreateMember_DuplicateUserId_ShouldReturnConflict()
{
// Arrange
var client = _factory.CreateAuthenticatedClient();
var userId = Guid.NewGuid();
var command = new CreateMemberCommand
{
UserId = userId,
CountryCode = "VN"
};
// Create first member
await client.PostAsJsonAsync("/api/v1/members", command);
// Act - Try to create again
var response = await client.PostAsJsonAsync("/api/v1/members", command);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Conflict);
}
[Fact]
public async Task CreateMember_WithGender_ShouldSetGender()
{
// Arrange
var client = _factory.CreateAuthenticatedClient();
var command = new CreateMemberCommand
{
UserId = Guid.NewGuid(),
CountryCode = "VN",
Gender = "Female"
};
// Act
var response = await client.PostAsJsonAsync("/api/v1/members", command);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Created);
}
#endregion
#region Full Member Workflow
[Fact]
public async Task FullMemberWorkflow_CreateGetUpdate_ShouldSucceed()
{
// Arrange
var client = _factory.CreateAuthenticatedClient();
var userId = Guid.NewGuid();
// Step 1: Create member
var createCommand = new CreateMemberCommand
{
UserId = userId,
CountryCode = "VN",
Gender = "Male"
};
var createResponse = await client.PostAsJsonAsync("/api/v1/members", createCommand);
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
// Step 2: Get member
var getResponse = await client.GetAsync($"/api/v1/members/{userId}");
getResponse.StatusCode.Should().Be(HttpStatusCode.OK);
var member = await getResponse.Content.ReadFromJsonAsync<MemberDto>();
member.Should().NotBeNull();
member!.Id.Should().Be(userId);
member.CountryCode.Should().Be("VN");
member.Gender.Should().Be("Male");
member.CurrentLevel.Should().Be(1);
member.CurrentExp.Should().Be(0);
// Step 3: Update profile
var updateCommand = new UpdateMemberProfileCommand
{
MemberId = userId,
Gender = "Female",
CountryCode = "US",
Preferences = "{\"theme\": \"dark\"}"
};
var updateResponse = await client.PutAsJsonAsync($"/api/v1/members/{userId}", updateCommand);
updateResponse.StatusCode.Should().Be(HttpStatusCode.OK);
// Step 4: Verify update
var verifyResponse = await client.GetAsync($"/api/v1/members/{userId}");
var updatedMember = await verifyResponse.Content.ReadFromJsonAsync<MemberDto>();
updatedMember!.Gender.Should().Be("Female");
updatedMember.CountryCode.Should().Be("US");
updatedMember.Preferences.Should().Contain("dark");
}
#endregion
#region Experience Endpoints
[Fact]
public async Task AddExperience_WithoutAuth_ShouldReturnUnauthorized()
{
// Arrange
var client = _factory.CreateClient();
var command = new AddExperienceCommand
{
Points = 50,
SourceId = 1
};
// Act
var response = await client.PostAsJsonAsync($"/api/v1/members/{Guid.NewGuid()}/experience", command);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task GetProgress_WithoutAuth_ShouldReturnUnauthorized()
{
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync($"/api/v1/members/{Guid.NewGuid()}/progress");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task GetExperienceHistory_WithoutAuth_ShouldReturnUnauthorized()
{
// Arrange
var client = _factory.CreateClient();
// Act
var response = await client.GetAsync($"/api/v1/members/{Guid.NewGuid()}/experience");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
#endregion
}