Files
Yaojia Wang 4359c9f08f feat(backend): Add ProjectManagement integration test infrastructure + fix API controller
Created comprehensive integration test infrastructure for ProjectManagement module:
- PMWebApplicationFactory with in-memory database support
- TestAuthHelper for JWT token generation
- Test project with all necessary dependencies

Fixed API Controller:
- Removed manual TenantId injection in ProjectsController
- TenantId now automatically extracted via ITenantContext in CommandHandler
- Maintained OwnerId extraction from JWT claims

Test Infrastructure:
- In-memory database for fast, isolated tests
- Support for multi-tenant scenarios
- JWT authentication helpers
- Cross-module database consistency

Next Steps:
- Write multi-tenant isolation tests (Phase 3.2)
- Write CRUD integration tests (Phase 3.3)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 19:56:49 +01:00

58 lines
2.2 KiB
C#

using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
namespace ColaFlow.Modules.ProjectManagement.IntegrationTests.Infrastructure;
/// <summary>
/// Helper class for generating JWT tokens in tests
/// </summary>
public static class TestAuthHelper
{
private const string SecretKey = "test-secret-key-for-integration-tests-minimum-32-characters";
private const string Issuer = "ColaFlow.Test";
private const string Audience = "ColaFlow.Test";
public static string GenerateJwtToken(Guid userId, Guid tenantId, string tenantSlug, string email, string role = "Member")
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(SecretKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.NameIdentifier, userId.ToString()),
new Claim("sub", userId.ToString()),
new Claim("tenant_id", tenantId.ToString()),
new Claim("tenantId", tenantId.ToString()),
new Claim("tenantSlug", tenantSlug),
new Claim("email", email),
new Claim("role", role)
}),
Expires = DateTime.UtcNow.AddHours(1),
Issuer = Issuer,
Audience = Audience,
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
public static void AddAuthHeader(this HttpClient client, string token)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
public static void AddAuthHeader(this HttpClient client, Guid userId, Guid tenantId, string tenantSlug, string email, string role = "Member")
{
var token = GenerateJwtToken(userId, tenantId, tenantSlug, email, role);
client.AddAuthHeader(token);
}
}