using System.Text.Json; using XFEExtension.NetCore.XUnit.Attributes; using XFEEDToolBox.Core.Models; using XFEEDToolBox.Core.Outfitting; namespace XFEEDToolBox.Test; [TestFixture] public class EdsyTests { private static JsonElement[] Fixtures=>JsonDocument.Parse(File.ReadAllText(Path.Combine(AppContext.BaseDirectory,"Fixtures","edsy-oracle.json"))).RootElement.EnumerateArray().Select(e=>e.Clone()).ToArray(); [Test] public void AllOfficialStockShipsAndEngineeringFixtureRoundTripExactly() { foreach(var fixture in Fixtures) { var hash=fixture.GetProperty("hash").GetString()!; var doc=EdsyLinkCodec.Import("https://edsy.org/#/L="+hash); Check.Equal(fixture.GetProperty("ship").GetString(),doc.ShipType); Check.Equal("https://edsy.org/#/L="+hash,EdsyLinkCodec.Export(doc)); foreach(var expected in fixture.GetProperty("loadout").GetProperty("Modules").EnumerateArray().Where(m=>m.GetProperty("Slot").GetString()!="CargoHatch")) { var slot=doc.Slots.Single(s=>s.Slot==expected.GetProperty("Slot").GetString()); Check.Equal(expected.GetProperty("Item").GetString(),slot.Module?.Item); Check.Equal(expected.GetProperty("On").GetBoolean(),slot.Module!.Enabled); Check.Equal(expected.GetProperty("Priority").GetInt32(),slot.Module.Priority); } } } [Test] public void EngineeredFieldsAndPartialProgressArePreserved() { var fixture=Fixtures.Last();var doc=EdsyLinkCodec.Import(fixture.GetProperty("hash").GetString()!); Check.That(doc.Slots.Any(s=>s.Module?.Engineering?.ExperimentalEffectId.Length>0)); var module=doc.Slots.First(s=>s.Module?.Engineering is not null).Module!; Check.Equal(3,module.Engineering!.Level);Check.That(Math.Abs(module.Engineering.Quality!.Value-.435)<.0003);Check.That(module.Engineering.Modifiers.Count>0); Check.Equal("XFE Test - 42",doc.Name);Check.Equal("XF-42",doc.Ident); } [Test] public void ReplacementAndUninstallationSurviveLinkRoundTrip() { var doc=EdsyLinkCodec.Import(Fixtures[0].GetProperty("hash").GetString()!); var slot=doc.Slots.First(s=>s.Category=="hardpoint"&&s.Module is not null); var removed=ShipRefit.Install(doc,slot.Slot,null,OutfittingCatalog.Default); var imported=EdsyLinkCodec.Import(EdsyLinkCodec.Export(removed)); Check.That(imported.Slots.Single(s=>s.Slot==slot.Slot).Module is null); Check.That(doc.Slots.Single(s=>s.Slot==slot.Slot).Module is not null); var definition=OutfittingCatalog.Default.Modules.First(m=>m.Category=="hardpoint"&&m.Size==slot.Capacity&&m.Item!=slot.Module!.Item&&m.Ship.Length==0); var replacement=ShipRefit.Install(doc,slot.Slot,new("","计划购入",new(){Slot=slot.Slot,Item=definition.Item,Enabled=true},definition),OutfittingCatalog.Default); Check.Equal(definition.Item,EdsyLinkCodec.Import(EdsyLinkCodec.Export(replacement)).Slots.Single(s=>s.Slot==slot.Slot).Module?.Item); } [Test] public void NewEngineeringTargetReplacesOldModifiersInExport() { var doc=EdsyLinkCodec.Import(Fixtures.Last().GetProperty("hash").GetString()!); var target=doc.Slots.Single(s=>s.Slot=="PowerPlant"); doc=ShipRefit.SetTarget(doc,target.Slot,new("Overcharged",5,1,"special_powerplant_cooled",0,false,true)); var exported=EdsyLinkCodec.Import(EdsyLinkCodec.Export(doc)); var module=exported.Slots.Single(s=>s.Slot==target.Slot).Module!; Check.Equal(5,module.Engineering!.Level);Check.That(module.Engineering.Quality>.999); Check.Equal("PowerPlant_Boosted",module.Engineering.Blueprint); Check.That(module.Engineering.Modifiers.Count>0); } [Test] public void ExplicitNoExperimentalEffectDoesNotReappearAfterEdsyExport() { var doc=EdsyLinkCodec.Import(Fixtures.Last().GetProperty("hash").GetString()!); var slot=doc.Slots.First(s=>s.Module?.Engineering?.ExperimentalEffectId.Length>0); var engineering=slot.Module!.Engineering!; var none=ShipRefit.SetTarget(doc,slot.Slot,new(engineering.Blueprint,engineering.Level,engineering.Quality??1,"",0,false,true)); var restored=EdsyLinkCodec.Import(EdsyLinkCodec.Export(none)).Slots.Single(s=>s.Slot==slot.Slot).Module!; Check.That(restored.Engineering is not null&&restored.Engineering.ExperimentalEffectId.Length==0); Check.Equal(engineering.Level,restored.Engineering!.Level); Check.That(doc.Slots.Single(s=>s.Slot==slot.Slot).Module!.Engineering!.ExperimentalEffectId.Length>0); } [Test] public void IncompleteCoreConfigurationIsRejectedInsteadOfInventingStockModules() { var doc=EdsyLinkCodec.Import(Fixtures[0].GetProperty("hash").GetString()!); doc=ShipRefit.Install(doc,"PowerPlant",null,OutfittingCatalog.Default); Check.Throws(()=>EdsyLinkCodec.Export(doc)); } [Test] public void UnsupportedOrInvalidLinksAreRejected() { foreach(var value in new[]{"https://evil.example/#/L=K100000,xxx","https://edsy.org.evil.example/#/L=K100000,xxx","https://edsy.org/#/L=Z123456,,,","garbage","https://edsy.org/#/L=K!!!!,xx","https://edsy.org/#/L=K100000,xxx