using Microsoft.EntityFrameworkCore; using MoneyMap.Data; using MoneyMap.Models; namespace MoneyMap.Tests.Data; public class CategoryModelTests { // Model/query compilation only: never opens a connection or reads application configuration. private static MoneyMapContext CreateContext() => new( new DbContextOptionsBuilder() .UseSqlServer("Server=localhost;Database=ModelOnly;Integrated Security=true;TrustServerCertificate=true") .Options); [Theory] [InlineData(typeof(Transaction))] [InlineData(typeof(CategoryMapping))] public void StringCategoryEntities_DoNotHaveCategoryForeignKeys(Type entityType) { using var context = CreateContext(); var entity = context.Model.FindEntityType(entityType)!; Assert.Null(entity.FindProperty("CategoryId")); Assert.DoesNotContain(entity.GetProperties(), p => p.IsShadowProperty()); Assert.Equal(typeof(string), entity.FindProperty("Category")!.ClrType); Assert.DoesNotContain(entity.GetForeignKeys(), fk => fk.PrincipalEntityType.ClrType == typeof(Category)); } [Theory] [InlineData(true)] [InlineData(false)] public void ReceiptDuplicateQueries_DoNotSelectCategoryId(bool matchHash) { using var context = CreateContext(); var query = context.Receipts.Include(r => r.Transaction); var sql = (matchHash ? query.Where(r => r.FileHashSha256 == "test-hash") : query.Where(r => r.FileName == "receipt.png" && r.FileSizeBytes == 8)) .ToQueryString(); Assert.Contains("LEFT JOIN [Transactions]", sql); Assert.Contains("[Category]", sql); Assert.DoesNotContain("[CategoryId]", sql); } [Fact] public void CategoryMappingQuery_DoesNotSelectCategoryId() { using var context = CreateContext(); var sql = context.CategoryMappings.ToQueryString(); Assert.Contains("[Category]", sql); Assert.DoesNotContain("[CategoryId]", sql); } [Fact] public void IntendedCategoryRelationships_ArePreserved() { using var context = CreateContext(); var recurringPlace = context.Model.FindEntityType(typeof(RecurringPlace))!; Assert.Contains(recurringPlace.GetForeignKeys(), fk => fk.PrincipalEntityType.ClrType == typeof(Category) && fk.Properties.Single().Name == "CategoryId" && !fk.Properties.Single().IsShadowProperty()); var category = context.Model.FindEntityType(typeof(Category))!; Assert.Contains(category.GetForeignKeys(), fk => fk.PrincipalEntityType.ClrType == typeof(Category) && fk.Properties.Single().Name == "ParentCategoryId"); } }