249 lines
7.4 KiB
C#
249 lines
7.4 KiB
C#
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using FluentAssertions;
|
|
using MembershipService.API.Application.Commands;
|
|
using Xunit;
|
|
|
|
namespace MembershipService.FunctionalTests.Controllers;
|
|
|
|
/// <summary>
|
|
/// EN: Functional tests for Admin Level endpoints.
|
|
/// VI: Functional tests cho Admin Level endpoints.
|
|
/// </summary>
|
|
[Collection("Sequential")]
|
|
public class AdminLevelsControllerTests : IClassFixture<CustomWebApplicationFactory>
|
|
{
|
|
private readonly CustomWebApplicationFactory _factory;
|
|
|
|
public AdminLevelsControllerTests(CustomWebApplicationFactory factory)
|
|
{
|
|
_factory = factory;
|
|
}
|
|
|
|
#region POST /api/v1/levels - Create Level
|
|
|
|
[Fact]
|
|
public async Task CreateLevel_WithAuth_ShouldReturn201()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateAuthenticatedClient();
|
|
var command = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 10,
|
|
Name = "Test Level",
|
|
RequiredExp = 5000,
|
|
Description = "Test level for functional tests",
|
|
BadgeColor = "#FF5733"
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/v1/levels", command);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.Created);
|
|
|
|
var result = await response.Content.ReadFromJsonAsync<CreateLevelDefinitionResult>();
|
|
result.Should().NotBeNull();
|
|
result!.LevelNumber.Should().Be(10);
|
|
result.Name.Should().Be("Test Level");
|
|
result.RequiredExp.Should().Be(5000);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateLevel_WithoutAuth_ShouldReturn401()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateClient(); // No auth
|
|
var command = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 11,
|
|
Name = "Unauthorized Level",
|
|
RequiredExp = 6000
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/v1/levels", command);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CreateLevel_DuplicateLevelNumber_ShouldReturn409()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateAuthenticatedClient();
|
|
|
|
// First create a level
|
|
var firstCommand = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 50, // Use unique number to avoid conflicts with other tests
|
|
Name = "First Level",
|
|
RequiredExp = 500
|
|
};
|
|
var firstResponse = await client.PostAsJsonAsync("/api/v1/levels", firstCommand);
|
|
firstResponse.StatusCode.Should().Be(HttpStatusCode.Created);
|
|
|
|
// Now try to create duplicate
|
|
var duplicateCommand = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 50, // Same level number - should conflict
|
|
Name = "Duplicate",
|
|
RequiredExp = 500
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync("/api/v1/levels", duplicateCommand);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.Conflict);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region PUT /api/v1/levels/{id} - Update Level
|
|
|
|
[Fact]
|
|
public async Task UpdateLevel_WithAuth_ShouldReturn200()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateAuthenticatedClient();
|
|
|
|
// First create a level to update
|
|
var createCommand = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 60,
|
|
Name = "ToUpdate",
|
|
RequiredExp = 6000,
|
|
Description = "Original description"
|
|
};
|
|
var createResponse = await client.PostAsJsonAsync("/api/v1/levels", createCommand);
|
|
createResponse.StatusCode.Should().Be(HttpStatusCode.Created);
|
|
var createdLevel = await createResponse.Content.ReadFromJsonAsync<CreateLevelDefinitionResult>();
|
|
|
|
var updateCommand = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = createdLevel!.Id,
|
|
Name = "Updated Level",
|
|
Description = "Updated description"
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PutAsJsonAsync($"/api/v1/levels/{createdLevel.Id}", updateCommand);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
|
|
|
var result = await response.Content.ReadFromJsonAsync<UpdateLevelDefinitionResult>();
|
|
result.Should().NotBeNull();
|
|
result!.Name.Should().Be("Updated Level");
|
|
result.Description.Should().Be("Updated description");
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateLevel_WithoutAuth_ShouldReturn401()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateClient(); // No auth
|
|
var randomId = Guid.NewGuid();
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = randomId,
|
|
Name = "Unauthorized Update"
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PutAsJsonAsync($"/api/v1/levels/{randomId}", command);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task UpdateLevel_NotFound_ShouldReturn404()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateAuthenticatedClient();
|
|
var nonExistentId = Guid.NewGuid();
|
|
var command = new UpdateLevelDefinitionCommand
|
|
{
|
|
Id = nonExistentId,
|
|
Name = "NonExistent"
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PutAsJsonAsync($"/api/v1/levels/{nonExistentId}", command);
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region DELETE /api/v1/levels/{id} - Deactivate Level
|
|
|
|
[Fact]
|
|
public async Task DeactivateLevel_WithAuth_ShouldReturn204()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateAuthenticatedClient();
|
|
|
|
// First create a level to deactivate
|
|
var createCommand = new CreateLevelDefinitionCommand
|
|
{
|
|
LevelNumber = 99,
|
|
Name = "ToDeactivate",
|
|
RequiredExp = 9999
|
|
};
|
|
var createResponse = await client.PostAsJsonAsync("/api/v1/levels", createCommand);
|
|
var createdLevel = await createResponse.Content.ReadFromJsonAsync<CreateLevelDefinitionResult>();
|
|
|
|
// Act
|
|
var response = await client.DeleteAsync($"/api/v1/levels/{createdLevel!.Id}");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.NoContent);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeactivateLevel_WithoutAuth_ShouldReturn401()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateClient(); // No auth
|
|
var randomId = Guid.NewGuid();
|
|
|
|
// Act
|
|
var response = await client.DeleteAsync($"/api/v1/levels/{randomId}");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DeactivateLevel_NotFound_ShouldReturn404()
|
|
{
|
|
// Arrange
|
|
var client = _factory.CreateAuthenticatedClient();
|
|
var nonExistentId = Guid.NewGuid();
|
|
|
|
// Act
|
|
var response = await client.DeleteAsync($"/api/v1/levels/{nonExistentId}");
|
|
|
|
// Assert
|
|
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Helper DTOs
|
|
|
|
private class LevelDto
|
|
{
|
|
public Guid Id { get; set; }
|
|
public int LevelNumber { get; set; }
|
|
public string Name { get; set; } = string.Empty;
|
|
}
|
|
|
|
#endregion
|
|
}
|