test(harness): stabilize backend+frontend QA test suite (12/12+63/63 unit+integration, 45/45 frontend)

Stabilize test harness across full stack:

Backend integration tests:
- Fix Auth/Club/Migration/RLS/Member/Tenant/RLS Isolation/Shift/Task test suites
- Add AssemblyInfo.cs for test configuration
- Enhance CustomWebApplicationFactory + TestAuthHandler for stable test environment
- Expand RlsIsolationTests with comprehensive multi-tenant RLS verification

Frontend test harness:
- Align vitest.config.ts with backend API changes
- Add bunfig.toml for bun test environment stability
- Enhance api.test.ts with proper test setup integration
- Expand test/setup.ts with fixture initialization

All tests now passing: backend 12/12 unit + 63/63 integration, frontend 45/45
This commit is contained in:
WorkClub Automation
2026-03-06 09:19:32 +01:00
parent 9950185213
commit f8f3e0f01e
18 changed files with 489 additions and 428 deletions

View File

@@ -16,6 +16,9 @@ public class ClubEndpointsTests : IntegrationTestBase
{
}
private static readonly string Tenant1Id = Guid.Parse("00000000-0000-0000-0000-000000000001").ToString();
private static readonly string Tenant2Id = Guid.Parse("00000000-0000-0000-0000-000000000002").ToString();
public override async Task InitializeAsync()
{
using var scope = Factory.Services.CreateScope();
@@ -26,14 +29,14 @@ public class ClubEndpointsTests : IntegrationTestBase
context.Members.RemoveRange(context.Members);
await context.SaveChangesAsync();
// Create test clubs
// Create test clubs with Guid-format tenant IDs
var club1Id = Guid.NewGuid();
var club2Id = Guid.NewGuid();
var club1 = new Club
{
Id = club1Id,
TenantId = "tenant1",
TenantId = Tenant1Id,
Name = "Test Tennis Club",
SportType = SportType.Tennis,
Description = "Test club 1",
@@ -44,7 +47,7 @@ public class ClubEndpointsTests : IntegrationTestBase
var club2 = new Club
{
Id = club2Id,
TenantId = "tenant2",
TenantId = Tenant2Id,
Name = "Test Cycling Club",
SportType = SportType.Cycling,
Description = "Test club 2",
@@ -62,7 +65,7 @@ public class ClubEndpointsTests : IntegrationTestBase
context.Members.Add(new Member
{
Id = Guid.NewGuid(),
TenantId = "tenant1",
TenantId = Tenant1Id,
ExternalUserId = adminUserId,
DisplayName = "Admin User",
Email = "admin@test.com",
@@ -75,7 +78,7 @@ public class ClubEndpointsTests : IntegrationTestBase
context.Members.Add(new Member
{
Id = Guid.NewGuid(),
TenantId = "tenant2",
TenantId = Tenant2Id,
ExternalUserId = adminUserId,
DisplayName = "Admin User",
Email = "admin@test.com",
@@ -89,7 +92,7 @@ public class ClubEndpointsTests : IntegrationTestBase
context.Members.Add(new Member
{
Id = Guid.NewGuid(),
TenantId = "tenant1",
TenantId = Tenant1Id,
ExternalUserId = managerUserId,
DisplayName = "Manager User",
Email = "manager@test.com",
@@ -105,18 +108,15 @@ public class ClubEndpointsTests : IntegrationTestBase
[Fact]
public async Task GetClubsMe_ReturnsOnlyUserClubs()
{
// Arrange - admin is member of 2 clubs
SetTenant("tenant1");
SetTenant(Tenant1Id);
AuthenticateAs("admin@test.com", new Dictionary<string, string>
{
["tenant1"] = "Admin",
["tenant2"] = "Member"
[Tenant1Id] = "Admin",
[Tenant2Id] = "Member"
}, userId: "admin-user-id");
// Act
var response = await Client.GetAsync("/api/clubs/me");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var clubs = await response.Content.ReadFromJsonAsync<List<ClubListResponse>>();
@@ -129,17 +129,14 @@ public class ClubEndpointsTests : IntegrationTestBase
[Fact]
public async Task GetClubsMe_ForManagerUser_ReturnsOnlyOneClub()
{
// Arrange - manager is only member of club1
SetTenant("tenant1");
SetTenant(Tenant1Id);
AuthenticateAs("manager@test.com", new Dictionary<string, string>
{
["tenant1"] = "Manager"
[Tenant1Id] = "Manager"
}, userId: "manager-user-id");
// Act
var response = await Client.GetAsync("/api/clubs/me");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var clubs = await response.Content.ReadFromJsonAsync<List<ClubListResponse>>();
@@ -151,17 +148,14 @@ public class ClubEndpointsTests : IntegrationTestBase
[Fact]
public async Task GetClubsCurrent_ReturnsCurrentTenantClub()
{
// Arrange
SetTenant("tenant1");
SetTenant(Tenant1Id);
AuthenticateAs("admin@test.com", new Dictionary<string, string>
{
["tenant1"] = "Admin"
[Tenant1Id] = "Admin"
}, userId: "admin-user-id");
// Act
var response = await Client.GetAsync("/api/clubs/current");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var club = await response.Content.ReadFromJsonAsync<ClubDetailResponse>();
@@ -174,17 +168,14 @@ public class ClubEndpointsTests : IntegrationTestBase
[Fact]
public async Task GetClubsCurrent_DifferentTenant_ReturnsDifferentClub()
{
// Arrange
SetTenant("tenant2");
SetTenant(Tenant2Id);
AuthenticateAs("admin@test.com", new Dictionary<string, string>
{
["tenant2"] = "Member"
[Tenant2Id] = "Member"
}, userId: "admin-user-id");
// Act
var response = await Client.GetAsync("/api/clubs/current");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var club = await response.Content.ReadFromJsonAsync<ClubDetailResponse>();
@@ -196,16 +187,13 @@ public class ClubEndpointsTests : IntegrationTestBase
[Fact]
public async Task GetClubsCurrent_NoTenantContext_ReturnsBadRequest()
{
// Arrange - no tenant header set
AuthenticateAs("admin@test.com", new Dictionary<string, string>
{
["tenant1"] = "Admin"
[Tenant1Id] = "Admin"
}, userId: "admin-user-id");
// Act
var response = await Client.GetAsync("/api/clubs/current");
// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}