using System.Security.Claims; using System.Text.Json; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using RadicadeServer.API.Avatars; using RadicadeServer.DB; using RadicadeServer.RecNet.Accounts.Local; using Xunit; namespace RadicadeServer.Tests; public class QuestOutfitsTests { [Fact] public async Task CurrentOutfitUsesAuthenticatedAccountsSavedAppearance() { await using var db = NewDatabase(); const string stored = """ {"OutfitSelections":"body,material","HairColor":"hair","SkinColor":"skin","FaceFeatures":"{}"} """; db.Avatars.AddRange( new PlayerAvatar { AccountId = 12, Avatar = stored, Outfits = "[]" }, new PlayerAvatar { AccountId = 99, Avatar = "{}", Outfits = "[]" }); await db.SaveChangesAsync(); var api = CreateApi(db, 12); var result = Assert.IsType(await api.GetCurrentOutfit()); var dto = Assert.IsType(result.Value); var json = JsonSerializer.SerializeToElement(dto); Assert.Equal(0, json.GetProperty("DataVersion").GetInt64()); Assert.Equal(0, json.GetProperty("Slot").GetInt32()); Assert.Equal(0, json.GetProperty("Accessibility").GetInt32()); Assert.Empty(json.GetProperty("Selections").EnumerateArray()); var legacy = json.GetProperty("LegacyData"); Assert.Equal("body,material", legacy.GetProperty("SelectionsV1").GetString()); Assert.Equal("hair", legacy.GetProperty("HairColor").GetString()); Assert.Equal("skin", legacy.GetProperty("SkinColor").GetString()); Assert.Equal("{}", legacy.GetProperty("FaceFeatures").GetString()); Assert.Equal(JsonValueKind.Null, legacy.GetProperty("SelectionsV2").ValueKind); Assert.Equal(stored, (await db.Avatars.FindAsync(12L))!.Avatar); Assert.Equal("{}", (await db.Avatars.FindAsync(99L))!.Avatar); } [Fact] public async Task CurrentOutfitRequiresAnAuthenticatedAccount() { await using var db = NewDatabase(); Assert.IsType(await CreateApi(db, null).GetCurrentOutfit()); Assert.False(await db.Avatars.AnyAsync()); Assert.NotEmpty(typeof(OutfitsAPI).GetCustomAttributes(typeof(AuthorizeAttribute), true)); } [Fact] public async Task CurrentOutfitInitializesMissingAvatarThroughExistingLoader() { await using var db = NewDatabase(); var result = Assert.IsType(await CreateApi(db, 12).GetCurrentOutfit()); var dto = Assert.IsType(result.Value); var stored = Assert.Single(await db.Avatars.ToListAsync()); Assert.Equal(12, stored.AccountId); Assert.Equal(stored.DeserializeAvatar()!.OutfitSelections, dto.LegacyData.SelectionsV1); } private static RecDBContext NewDatabase() => new(TestDbOptions.Create() .UseInMemoryDatabase(Guid.NewGuid().ToString()).Options); private static OutfitsAPI CreateApi(RecDBContext db, long? accountId) => new(db) { ControllerContext = new ControllerContext { HttpContext = new DefaultHttpContext { User = accountId.HasValue ? new ClaimsPrincipal(new ClaimsIdentity( [new Claim(ClaimTypes.NameIdentifier, accountId.Value.ToString())], "test")) : new ClaimsPrincipal(new ClaimsIdentity()) } } }; }