using Microsoft.EntityFrameworkCore; using RadicadeServer.DB; using RadicadeServer.RecNet.Accounts; using RadicadeServer.RecNet.Enums; using RadicadeServer.RecNet.Enums.Rooms; using RadicadeServer.RecNet.Rooms; using RadicadeServer.Utils; using Xunit; namespace RadicadeServer.Tests; [Collection(DbFactoryCollection.Name)] public class DormVisitTests { private const long PlayerId = 701; private const long DormRoomId = 81; private const long DormInstanceId = 901; private sealed class TestDbContextFactory : IDbContextFactory { private readonly DbContextOptions options = TestDbOptions.Create() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; public RecDBContext CreateDbContext() => new(options); } private static async Task<(TestDbContextFactory Factory, RecDBContext Db)> CreateContextAsync() { var factory = new TestDbContextFactory(); RoomUtils.DbFactory = factory; MatchmakingUtils.DbFactory = factory; var db = factory.CreateDbContext(); db.Rooms.Add(new RoomData { RoomId = DormRoomId, Name = "DormRoom", IsDorm = true, CreatorAccountId = PlayerId, Accessibility = Accessibility.Private, CreatedAt = DateTime.UtcNow }); db.SubRooms.Add(new SubRoom { SubRoomId = 81, RoomId = DormRoomId, Name = "Home", UnitySceneId = "cbad71af-0831-44d8-b8ef-69edafa841f6", MaxPlayers = 4, Accessibility = Accessibility.Private }); db.RoomInstances.Add(new RoomInstance { roomInstanceId = DormInstanceId, roomId = DormRoomId, subRoomId = 81, roomInstanceType = RoomInstanceType.Dormroom, isPrivate = true, name = "@tester's Dorm", maxCapacity = 4 }); await db.SaveChangesAsync(); return (factory, db); } [Fact] public async Task DormEntryCountsOneVisitAndHeartbeatRehydrationDoesNotAddMore() { var (factory, db) = await CreateContextAsync(); await using var _db = db; var presence = new RealPresence { playerId = PlayerId }; db.Presences.Add(presence); await db.SaveChangesAsync(); await MatchmakingUtils.EnsureDormPresenceAsync(db, PlayerId, presence); await MatchmakingUtils.EnsureDormPresenceAsync(db, PlayerId, presence); await db.SaveChangesAsync(); await using var verify = factory.CreateDbContext(); var interaction = await verify.RoomInteractions.SingleAsync(x => x.RoomId == DormRoomId && x.PlayerId == PlayerId); var stats = await verify.RoomStats.SingleAsync(x => x.RoomId == DormRoomId); Assert.True(interaction.Visited); Assert.Equal(1, interaction.VisitCount); Assert.Equal(1, stats.VisitCount); Assert.Equal(1, stats.VisitorCount); } [Fact] public async Task ReturningToDormCountsASecondVisit() { var (factory, db) = await CreateContextAsync(); await using var _db = db; var presence = new RealPresence { playerId = PlayerId }; db.Presences.Add(presence); await db.SaveChangesAsync(); await MatchmakingUtils.EnsureDormPresenceAsync(db, PlayerId, presence); presence.roomInstance = null; await db.SaveChangesAsync(); await MatchmakingUtils.EnsureDormPresenceAsync(db, PlayerId, presence); await db.SaveChangesAsync(); await using var verify = factory.CreateDbContext(); var interaction = await verify.RoomInteractions.SingleAsync(x => x.RoomId == DormRoomId && x.PlayerId == PlayerId); var stats = await verify.RoomStats.SingleAsync(x => x.RoomId == DormRoomId); Assert.Equal(2, interaction.VisitCount); Assert.Equal(2, stats.VisitCount); Assert.Equal(1, stats.VisitorCount); } }