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

140 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DramaLing.Api.Tests.Integration.Fixtures;
using System.Net;
namespace DramaLing.Api.Tests.Integration.Controllers;
/// <summary>
/// FlashcardsController 整合測試
/// 測試詞卡相關的 API 端點功能
/// </summary>
public class FlashcardsControllerTests : IntegrationTestBase
{
public FlashcardsControllerTests(DramaLingWebApplicationFactory factory) : base(factory)
{
}
[Fact]
public async Task GetDueFlashcards_WithValidUser_ShouldReturnFlashcards()
{
// Arrange
var client = CreateTestUser1Client();
// Act
var response = await client.GetAsync("/api/flashcards/due");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().NotBeNullOrEmpty();
content.Should().Contain("flashcards");
}
[Fact]
public async Task GetDueFlashcards_WithoutAuth_ShouldReturn401()
{
// Arrange
var client = HttpClient; // 未認證的 client
// Act
var response = await client.GetAsync("/api/flashcards/due");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);
}
[Fact]
public async Task GetAllFlashcards_WithValidUser_ShouldReturnUserFlashcards()
{
// Arrange
var client = CreateTestUser1Client();
// Act
var response = await client.GetAsync("/api/flashcards");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().NotBeNullOrEmpty();
}
[Fact]
public async Task GetFlashcardById_WithValidUserAndId_ShouldReturnFlashcard()
{
// Arrange
var client = CreateTestUser1Client();
var flashcardId = TestDataSeeder.TestFlashcard1Id;
// Act
var response = await client.GetAsync($"/api/flashcards/{flashcardId}");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("hello"); // 測試資料中的詞彙
}
[Fact]
public async Task GetFlashcardById_WithDifferentUser_ShouldReturn404()
{
// Arrange - TestUser2 嘗試存取 TestUser1 的詞卡
var client = CreateTestUser2Client();
var user1FlashcardId = TestDataSeeder.TestFlashcard1Id; // 屬於 TestUser1
// Act
var response = await client.GetAsync($"/api/flashcards/{user1FlashcardId}");
// Assert
response.StatusCode.Should().Be(HttpStatusCode.NotFound);
}
[Fact]
public async Task MarkWordMastered_WithValidFlashcard_ShouldUpdateReview()
{
// Arrange
var client = CreateTestUser1Client();
var flashcardId = TestDataSeeder.TestFlashcard1Id;
// Act
var response = await client.PostAsync($"/api/flashcards/{flashcardId}/mastered", null);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.OK);
var content = await response.Content.ReadAsStringAsync();
content.Should().Contain("success");
// 驗證資料庫中的複習記錄是否更新
using var context = GetDbContext();
var review = context.FlashcardReviews
.First(r => r.FlashcardId == flashcardId && r.UserId == TestDataSeeder.TestUser1Id);
review.SuccessCount.Should().BeGreaterThan(0);
}
[Fact]
public async Task UserDataIsolation_ShouldBeEnforced()
{
// Arrange
var user1Client = CreateTestUser1Client();
var user2Client = CreateTestUser2Client();
// Act - 兩個用戶分別取得詞卡
var user1Response = await user1Client.GetAsync("/api/flashcards");
var user2Response = await user2Client.GetAsync("/api/flashcards");
// Assert
user1Response.StatusCode.Should().Be(HttpStatusCode.OK);
user2Response.StatusCode.Should().Be(HttpStatusCode.OK);
var user1Content = await user1Response.Content.ReadAsStringAsync();
var user2Content = await user2Response.Content.ReadAsStringAsync();
// TestUser1 有 2 張詞卡TestUser2 有 1 張詞卡
user1Content.Should().Contain("hello");
user1Content.Should().Contain("beautiful");
user2Content.Should().Contain("sophisticated");
// 確保用戶間資料隔離
user1Content.Should().NotContain("sophisticated");
user2Content.Should().NotContain("hello");
user2Content.Should().NotContain("beautiful");
}
}