// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Linq; using EFCore.Jet.CustomBaseTests.GearsOfWarModel; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; namespace EFCore.Jet.CustomBaseTests.GearsOfWarModel; public abstract class GearsOfWarQueryFixtureBase : SharedStoreFixtureBase, IQueryFixtureBase { protected override string StoreName => "GearsOfWarQueryTest"; public Func GetContextCreator() => () => CreateContext(); public virtual ISetSource GetExpectedData() => GearsOfWarData.Instance; public virtual Dictionary<(Type, string), Func> GetShadowPropertyMappings() => new() { { (typeof(Gear), "AssignedCityName"), e => GetExpectedData().Set().AsEnumerable() .SingleOrDefault(g => g.Nickname == ((Gear)e)?.Nickname)?.AssignedCity ?.Name }, }; public IReadOnlyDictionary EntitySorters { get; } = new Dictionary> { { typeof(City), e => ((City)e)?.Name }, { typeof(CogTag), e => ((CogTag)e)?.Id }, { typeof(Faction), e => ((Faction)e)?.Id }, { typeof(LocustHorde), e => ((LocustHorde)e)?.Id }, { typeof(Gear), e => (((Gear)e)?.SquadId, ((Gear)e)?.Nickname) }, { typeof(Officer), e => (((Officer)e)?.SquadId, ((Officer)e)?.Nickname) }, { typeof(LocustLeader), e => ((LocustLeader)e)?.Name }, { typeof(LocustCommander), e => ((LocustCommander)e)?.Name }, { typeof(Mission), e => ((Mission)e)?.Id }, { typeof(Squad), e => ((Squad)e)?.Id }, { typeof(SquadMission), e => (((SquadMission)e)?.SquadId, ((SquadMission)e)?.MissionId) }, { typeof(Weapon), e => ((Weapon)e)?.Id }, { typeof(LocustHighCommand), e => ((LocustHighCommand)e)?.Id } }.ToDictionary(e => e.Key, e => (object)e.Value); public IReadOnlyDictionary EntityAsserters { get; } = new Dictionary> { { typeof(City), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (City)e; var aa = (City)a; Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.Location, aa.Location); Assert.Equal(ee.Nation, aa.Nation); } } }, { typeof(CogTag), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (CogTag)e; var aa = (CogTag)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.Note, aa.Note); Assert.Equal(ee.GearNickName, aa.GearNickName); Assert.Equal(ee.GearSquadId, aa.GearSquadId); } } }, { typeof(Faction), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (Faction)e; var aa = (Faction)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.CapitalName, aa.CapitalName); if (ee is LocustHorde locustHorde) { var actualLocustHorde = (LocustHorde)aa; Assert.Equal(locustHorde.CommanderName, actualLocustHorde.CommanderName); Assert.Equal(locustHorde.Eradicated, actualLocustHorde.Eradicated); } } } }, { typeof(LocustHorde), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (LocustHorde)e; var aa = (LocustHorde)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.CapitalName, aa.CapitalName); Assert.Equal(ee.CommanderName, aa.CommanderName); Assert.Equal(ee.Eradicated, aa.Eradicated); } } }, { typeof(Gear), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (Gear)e; var aa = (Gear)a; Assert.Equal(ee.Nickname, aa.Nickname); Assert.Equal(ee.SquadId, aa.SquadId); Assert.Equal(ee.CityOfBirthName, aa.CityOfBirthName); Assert.Equal(ee.FullName, aa.FullName); Assert.Equal(ee.HasSoulPatch, aa.HasSoulPatch); Assert.Equal(ee.LeaderNickname, aa.LeaderNickname); Assert.Equal(ee.LeaderSquadId, aa.LeaderSquadId); Assert.Equal(ee.Rank, aa.Rank); } } }, { typeof(Officer), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (Officer)e; var aa = (Officer)a; Assert.Equal(ee.Nickname, aa.Nickname); Assert.Equal(ee.SquadId, aa.SquadId); Assert.Equal(ee.CityOfBirthName, aa.CityOfBirthName); Assert.Equal(ee.FullName, aa.FullName); Assert.Equal(ee.HasSoulPatch, aa.HasSoulPatch); Assert.Equal(ee.LeaderNickname, aa.LeaderNickname); Assert.Equal(ee.LeaderSquadId, aa.LeaderSquadId); Assert.Equal(ee.Rank, aa.Rank); } } }, { typeof(LocustLeader), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (LocustLeader)e; var aa = (LocustLeader)a; Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.ThreatLevel, aa.ThreatLevel); Assert.Equal(ee.ThreatLevelByte, aa.ThreatLevelByte); Assert.Equal(ee.ThreatLevelNullableByte, aa.ThreatLevelNullableByte); if (e is LocustCommander locustCommander) { var actualLocustCommander = (LocustCommander)aa; Assert.Equal(locustCommander.DefeatedByNickname, actualLocustCommander.DefeatedByNickname); Assert.Equal(locustCommander.DefeatedBySquadId, actualLocustCommander.DefeatedBySquadId); } } } }, { typeof(LocustCommander), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (LocustCommander)e; var aa = (LocustCommander)a; Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.ThreatLevel, aa.ThreatLevel); Assert.Equal(ee.ThreatLevelByte, aa.ThreatLevelByte); Assert.Equal(ee.ThreatLevelNullableByte, aa.ThreatLevelNullableByte); Assert.Equal(ee.DefeatedByNickname, aa.DefeatedByNickname); Assert.Equal(ee.DefeatedBySquadId, aa.DefeatedBySquadId); } } }, { typeof(Mission), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (Mission)e; var aa = (Mission)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.CodeName, aa.CodeName); Assert.Equal(ee.Rating, aa.Rating); //TODO: Turn this back on when we can round trip DateTimeOffset properly //Assert.Equal(ee.Timeline, aa.Timeline); } } }, { typeof(Squad), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (Squad)e; var aa = (Squad)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.Banner == null, aa.Banner == null); if (ee.Banner != null) { Assert.True(ee.Banner.SequenceEqual(aa.Banner)); } Assert.Equal(ee.Banner5 == null, aa.Banner5 == null); if (ee.Banner5 != null) { Assert.True(ee.Banner5.SequenceEqual(aa.Banner5)); } } } }, { typeof(SquadMission), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (SquadMission)e; var aa = (SquadMission)a; Assert.Equal(ee.SquadId, aa.SquadId); Assert.Equal(ee.MissionId, aa.MissionId); } } }, { typeof(Weapon), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (Weapon)e; var aa = (Weapon)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.IsAutomatic, aa.IsAutomatic); Assert.Equal(ee.Name, aa.Name); Assert.Equal(ee.OwnerFullName, aa.OwnerFullName); Assert.Equal(ee.SynergyWithId, aa.SynergyWithId); } } }, { typeof(LocustHighCommand), (e, a) => { Assert.Equal(e == null, a == null); if (a != null) { var ee = (LocustHighCommand)e; var aa = (LocustHighCommand)a; Assert.Equal(ee.Id, aa.Id); Assert.Equal(ee.IsOperational, aa.IsOperational); Assert.Equal(ee.Name, aa.Name); } } } }.ToDictionary(e => e.Key, e => (object)e.Value); protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context) { modelBuilder.Entity( b => { b.HasKey(c => c.Name); }); modelBuilder.Entity( b => { b.HasKey( g => new { g.Nickname, g.SquadId }); b.HasOne(g => g.CityOfBirth).WithMany(c => c.BornGears).HasForeignKey(g => g.CityOfBirthName).IsRequired(); b.HasOne(g => g.Tag).WithOne(t => t.Gear).HasForeignKey( t => new { t.GearNickName, t.GearSquadId }); b.HasOne(g => g.AssignedCity).WithMany(c => c.StationedGears).IsRequired(false); }); modelBuilder.Entity().HasMany(o => o.Reports).WithOne().HasForeignKey( o => new { o.LeaderNickname, o.LeaderSquadId }); modelBuilder.Entity( b => { b.HasKey(s => s.Id); b.Property(s => s.Id).ValueGeneratedNever(); b.Property(s => s.Banner5).HasMaxLength(5); b.HasMany(s => s.Members).WithOne(g => g.Squad).HasForeignKey(g => g.SquadId); }); modelBuilder.Entity( b => { b.Property(w => w.Id).ValueGeneratedNever(); b.HasOne(w => w.SynergyWith).WithOne().HasForeignKey(w => w.SynergyWithId); b.HasOne(w => w.Owner).WithMany(g => g.Weapons).HasForeignKey(w => w.OwnerFullName).HasPrincipalKey(g => g.FullName); }); modelBuilder.Entity().Property(m => m.Id).ValueGeneratedNever(); modelBuilder.Entity( b => { b.HasKey( sm => new { sm.SquadId, sm.MissionId }); b.HasOne(sm => sm.Mission).WithMany(m => m.ParticipatingSquads).HasForeignKey(sm => sm.MissionId); b.HasOne(sm => sm.Squad).WithMany(s => s.Missions).HasForeignKey(sm => sm.SquadId); }); modelBuilder.Entity().HasKey(f => f.Id); modelBuilder.Entity().Property(f => f.Id).ValueGeneratedNever(); modelBuilder.Entity().HasBaseType(); modelBuilder.Entity().HasMany(h => h.Leaders).WithOne(); modelBuilder.Entity().HasOne(h => h.Commander).WithOne(c => c.CommandingFaction); modelBuilder.Entity().HasKey(l => l.Name); modelBuilder.Entity().HasBaseType(); modelBuilder.Entity().HasOne(c => c.DefeatedBy).WithOne().HasForeignKey( c => new { c.DefeatedByNickname, c.DefeatedBySquadId }); modelBuilder.Entity().HasKey(l => l.Id); modelBuilder.Entity().Property(l => l.Id).ValueGeneratedNever(); } protected override void Seed(GearsOfWarContext context) => GearsOfWarContext.Seed(context); public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder) => base.AddOptions(builder).ConfigureWarnings( w => w.Log(CoreEventId.RowLimitingOperationWithoutOrderByWarning)); public override GearsOfWarContext CreateContext() { var context = base.CreateContext(); context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; return context; } }