dramaling-vocab-learning/backend/DramaLing.Api.Tests/Integration/Controllers/AuthControllerTests.cs

215 lines
6.6 KiB
C#

using DramaLing.Api.Tests.Integration.Fixtures;
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
namespace DramaLing.Api.Tests.Integration.Controllers;
/// <summary>
/// AuthController 整合測試
/// 測試用戶認證相關的 API 端點功能
/// </summary>
public class AuthControllerTests : IntegrationTestBase
{
public AuthControllerTests(DramaLingWebApplicationFactory factory) : base(factory)
{
}
[Fact]
public async Task Register_WithValidData_ShouldCreateUser()
{
// Arrange
var registerData = new
{
username = "newuser",
email = "newuser@example.com",
password = "password123",
displayName = "New Test User"
};
// Act
var response = await HttpClient.PostAsJsonAsync("/api/auth/register", registerData);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
content.Should().Contain("token");
}
[Fact]
public async Task Register_WithDuplicateEmail_ShouldReturn400()
{
// Arrange - 使用已存在的測試用戶 email
var registerData = new
{
username = "duplicateuser",
email = "test1@example.com", // 已存在的 email
password = "password123",
displayName = "Duplicate User"
};
// Act
var response = await HttpClient.PostAsJsonAsync("/api/auth/register", registerData);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.BadRequest);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("error");
}
[Fact]
public async Task Login_WithValidCredentials_ShouldReturnToken()
{
// Arrange
var loginData = new
{
email = "test1@example.com",
password = "password123" // 對應 TestDataSeeder 中的密碼
};
// Act
var response = await HttpClient.PostAsJsonAsync("/api/auth/login", loginData);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
content.Should().Contain("token");
// 驗證 JWT Token 格式
var jsonResponse = JsonSerializer.Deserialize<JsonElement>(content);
if (jsonResponse.TryGetProperty("data", out var data) &&
data.TryGetProperty("token", out var tokenElement))
{
var token = tokenElement.GetString();
token.Should().NotBeNullOrEmpty();
token.Should().StartWith("eyJ"); // JWT Token 格式
}
}
[Fact]
public async Task Login_WithInvalidCredentials_ShouldReturn401()
{
// Arrange
var loginData = new
{
email = "test1@example.com",
password = "wrongpassword"
};
// Act
var response = await HttpClient.PostAsJsonAsync("/api/auth/login", loginData);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("error");
}
[Fact]
public async Task GetProfile_WithValidAuth_ShouldReturnUserProfile()
{
// Arrange
var client = CreateTestUser1Client();
// Act
var response = await client.GetAsync("/api/auth/profile");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("Test User 1");
content.Should().Contain("testuser1");
content.Should().Contain("test1@example.com");
}
[Fact]
public async Task GetProfile_WithoutAuth_ShouldReturn401()
{
// Arrange
var client = HttpClient; // 未認證
// Act
var response = await client.GetAsync("/api/auth/profile");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task UpdateProfile_WithValidAuth_ShouldUpdateSuccessfully()
{
// Arrange
var client = CreateTestUser1Client();
var updateData = new
{
displayName = "Updated Display Name",
bio = "Updated bio information"
};
// Act
var response = await client.PutAsJsonAsync("/api/auth/profile", updateData);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
// 驗證更新是否生效
var profileResponse = await client.GetAsync("/api/auth/profile");
var profileContent = await profileResponse.Content.ReadAsStringAsync();
profileContent.Should().Contain("Updated Display Name");
}
[Fact]
public async Task GetSettings_WithValidAuth_ShouldReturnSettings()
{
// Arrange
var client = CreateTestUser1Client();
// Act
var response = await client.GetAsync("/api/auth/settings");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
}
[Fact]
public async Task UpdateSettings_WithValidAuth_ShouldUpdateSuccessfully()
{
// Arrange
var client = CreateTestUser1Client();
var settingsData = new
{
language = "zh-TW",
theme = "dark",
notifications = true
};
// Act
var response = await client.PutAsJsonAsync("/api/auth/settings", settingsData);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
}
[Fact]
public async Task GetStatus_ShouldReturnUserStatus()
{
// Arrange
var client = CreateTestUser1Client();
// Act
var response = await client.GetAsync("/api/auth/status");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
}
}