Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions TradeOffStackAPI.Tests/Integration/CustomWebApplicationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@ namespace TradeOffStackAPI.Tests.Integration;

public class CustomWebApplicationFactory<TProgram> : WebApplicationFactory<TProgram> where TProgram : class
{
private readonly DbConnection _connection;
private readonly DbConnection _coreConnection;
private readonly DbConnection _assetConnection;

public CustomWebApplicationFactory()
{
_connection = new SqliteConnection("DataSource=:memory:");
_connection.Open();
_coreConnection = new SqliteConnection("DataSource=:memory:");
_coreConnection.Open();
_assetConnection = new SqliteConnection("DataSource=:memory:");
_assetConnection.Open();
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
Expand Down Expand Up @@ -55,22 +58,22 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)

services.AddDbContext<CoreDbContext, TestCoreDbContext>(options =>
{
options.UseSqlite(_connection);
options.UseSqlite(_coreConnection);
});

services.AddScoped<DbContextOptions<CoreDbContext>>(sp =>
new DbContextOptionsBuilder<CoreDbContext>()
.UseSqlite(_connection)
.UseSqlite(_coreConnection)
.Options);

services.AddDbContext<AssetDbContext, TestAssetDbContext>(options =>
{
options.UseSqlite(_connection);
options.UseSqlite(_assetConnection);
});

services.AddScoped<DbContextOptions<AssetDbContext>>(sp =>
new DbContextOptionsBuilder<AssetDbContext>()
.UseSqlite(_connection)
.UseSqlite(_assetConnection)
.Options);

var sp = services.BuildServiceProvider();
Expand All @@ -87,8 +90,10 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
_connection.Close();
_connection.Dispose();
_coreConnection.Close();
_coreConnection.Dispose();
_assetConnection.Close();
_assetConnection.Dispose();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ public async Task GetEquipment_AsEmployee_ShouldSucceed()
// Act
var response = await client.GetAsync("/api/equipment");

if (response.StatusCode != HttpStatusCode.OK)
{
var content = await response.Content.ReadAsStringAsync();
Assert.Fail($"Request failed with status {response.StatusCode} and body: {content}");
}

// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
Expand Down
20 changes: 18 additions & 2 deletions TradeOffStackAPI/Data/AssetDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,23 @@ public AssetDbContext(DbContextOptions<AssetDbContext> options, ICurrentUserServ
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Only apply configurations from this assembly that relate to AssetPortal
modelBuilder.ApplyConfigurationsFromAssembly(typeof(AssetDbContext).Assembly);

// Register PostgreSQL Enums with PascalCase translator to match runtime config
var translator = new Npgsql.NameTranslation.NpgsqlNullNameTranslator();
modelBuilder.HasPostgresEnum<AssetStatus>(name: "asset_status", nameTranslator: translator);
modelBuilder.HasPostgresEnum<AssetCategory>(name: "asset_category", nameTranslator: translator);
modelBuilder.HasPostgresEnum<ReservationStatus>(name: "reservation_status", nameTranslator: translator);
modelBuilder.HasPostgresEnum<MaintenanceStatus>(name: "maintenance_status", nameTranslator: translator);
modelBuilder.HasPostgresEnum<MaintenancePriority>(name: "maintenance_priority", nameTranslator: translator);
modelBuilder.HasPostgresEnum<AuditAction>(name: "audit_action", nameTranslator: translator);
modelBuilder.HasPostgresEnum<DepreciationMethod>(name: "depreciation_method", nameTranslator: translator);

// Register specific configurations to prevent configuration leakage between contexts
modelBuilder.ApplyConfiguration(new TradeOffStackAPI.Data.Configurations.EquipmentConfiguration());
modelBuilder.ApplyConfiguration(new TradeOffStackAPI.Data.Configurations.ReservationConfiguration());
modelBuilder.ApplyConfiguration(new TradeOffStackAPI.Data.Configurations.MaintenanceRequestConfiguration());
modelBuilder.ApplyConfiguration(new TradeOffStackAPI.Configurations.SoftwareLicenseConfiguration());
modelBuilder.ApplyConfiguration(new TradeOffStackAPI.Configurations.EquipmentLicenseConfiguration());
modelBuilder.ApplyConfiguration(new TradeOffStackAPI.Data.Configurations.AuditLogConfiguration());
}
}
18 changes: 14 additions & 4 deletions TradeOffStackAPI/Data/CoreDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,19 @@ public CoreDbContext(DbContextOptions<CoreDbContext> options, ICurrentUserServic
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Only apply configurations from this assembly that relate to Core
// For simplicity, we just apply all configurations since EF ignores irrelevant ones usually,
// but it's safer to only apply specific ones if we had them separated.
modelBuilder.ApplyConfigurationsFromAssembly(typeof(CoreDbContext).Assembly);

// Register PostgreSQL Enums with PascalCase translator to match runtime config
var translator = new Npgsql.NameTranslation.NpgsqlNullNameTranslator();
modelBuilder.HasPostgresEnum<UserRole>(name: "user_role", nameTranslator: translator);
modelBuilder.HasPostgresEnum<AuditAction>(name: "audit_action", nameTranslator: translator);

// Ignore asset-related navigation properties on User for CoreDbContext
modelBuilder.Entity<User>().Ignore(u => u.Reservations);
modelBuilder.Entity<User>().Ignore(u => u.MaintenanceRequests);

// Register specific configurations to prevent configuration leakage between contexts
modelBuilder.ApplyConfiguration(new Configurations.UserConfiguration());
modelBuilder.ApplyConfiguration(new Configurations.DepartmentConfiguration());
modelBuilder.ApplyConfiguration(new Configurations.AuditLogConfiguration());
}
}
2 changes: 1 addition & 1 deletion TradeOffStackAPI/Middleware/ExceptionHandlingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private async Task HandleAsync(HttpContext context, Exception exception)
Title = title,
// CORRECTION : On utilise exception.ToString() en développement pour avoir tous les détails,
// y compris les exceptions internes, ce qui est crucial pour le débogage.
Detail = _env.IsDevelopment() ? exception.ToString() : "An internal error occurred.",
Detail = (_env.IsDevelopment() || _env.IsEnvironment("Testing")) ? exception.ToString() : "An internal error occurred.",
Instance = context.Request.Path
};

Expand Down
102 changes: 0 additions & 102 deletions TradeOffStackAPI/Migrations/20260610202709_AddSaaSArchitecture.cs

This file was deleted.

Loading
Loading