using System.Security.Cryptography;
using System.Text.Json;
using System.Xml.Linq;
using XFEEDToolBox.Core.Galaxy;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public class GalaxyOriginalIconsTests
{
private static string DirectoryForAssets()
{
foreach(var start in new[]{Environment.CurrentDirectory,AppContext.BaseDirectory})
for(var directory=new DirectoryInfo(start);directory is not null;directory=directory.Parent)
{
var assets=Path.Combine(directory.FullName,"XFEEDToolBox","Assets","GalaxyIcons");
if(File.Exists(Path.Combine(assets,"source.json")))return assets;
}
throw new InvalidOperationException("Original galaxy icon manifest not found.");
}
[Test] public void SourceFramesHaveExactHashesAndNoMissingBitmapPlaceholders()
{
var directory=DirectoryForAssets();
using var document=JsonDocument.Parse(File.ReadAllText(Path.Combine(directory,"source.json")));
var root=document.RootElement;Check.That(root.GetProperty("exportBytesUnchanged").GetBoolean());
Check.That(!root.GetProperty("gameProcessAccess").GetBoolean());
var icons=root.GetProperty("icons").EnumerateArray().ToArray();
Check.Equal(198,icons.Length);
foreach(var icon in icons)
{
var file=Path.Combine(directory,icon.GetProperty("file").GetString()!);
var bytes=File.ReadAllBytes(file);
Check.Equal(icon.GetProperty("sha256").GetString(),Convert.ToHexStringLower(SHA256.HashData(bytes)));
if(Path.GetExtension(file)==".png")
{
Check.That(bytes.AsSpan(0,8).SequenceEqual(new byte[]{137,80,78,71,13,10,26,10}));
continue;
}
var svg=XDocument.Load(file);
Check.That(svg.Descendants().Any(x=>x.Name.LocalName=="path"));
Check.That(!svg.Descendants().Any(x=>x.Name.LocalName is "text" or "image"));
Check.That(!svg.Descendants().Attributes().Any(x=>x.Name.LocalName.Contains("bitmap",StringComparison.OrdinalIgnoreCase)),
"An unresolved Scaleform bitmap must never be packaged as a red placeholder.");
}
}
[Test] public void NativeBookmarkIdentifiersResolveToTheirOriginalNamedFrames()
{
using var document=JsonDocument.Parse(File.ReadAllText(Path.Combine(DirectoryForAssets(),"source.json")));
var root=document.RootElement;
var frames=root.GetProperty("icons").EnumerateArray().Where(x=>x.GetProperty("spriteId").GetInt32()==304).ToDictionary(x=>x.GetProperty("label").GetString()!);
foreach(var entry in root.GetProperty("nativeBookmarkMapping").GetProperty("values").EnumerateObject())
{
var native=uint.Parse(entry.Name);var name=entry.Value.GetString()!;var actual=GalaxyOriginalIcons.Bookmark(native);
Check.Equal(name,GalaxyOriginalIcons.BookmarkFrameName(native));Check.Equal(name,actual.FrameName);
if(name=="station_dodec")
{
Check.That(actual.UsesFallback);Check.Equal("Assets/GalaxyIcons/BookmarkDefault.svg",actual.AssetPath);
Check.That(!frames.ContainsKey(name),"Do not invent a station frame the original movie does not contain.");
continue;
}
Check.That(!actual.UsesFallback);
Check.Equal(frames[name].GetProperty("frame").GetInt32(),actual.Frame);
Check.Equal("Assets/GalaxyIcons/"+frames[name].GetProperty("file").GetString(),actual.AssetPath);
}
Check.Equal("default",GalaxyOriginalIcons.BookmarkFrameName(uint.MaxValue));
Check.Equal(GalaxyOriginalIcons.Bookmark(0),GalaxyOriginalIcons.Bookmark(uint.MaxValue));
}
[Test] public void ItemMarkersUseASeparateEnumAndUnknownTypesCannotBecomeCategoryPins()
{
Check.Equal("station_bernal",GalaxyOriginalIcons.Bookmark(2).FrameName);
Check.Equal("location",GalaxyOriginalIcons.ItemMarker(2)!.FrameName);
Check.Equal("locationThin",GalaxyOriginalIcons.ItemMarker(2,true)!.FrameName);
Check.That(GalaxyOriginalIcons.ItemMarker(5) is null&&GalaxyOriginalIcons.ItemMarker(uint.MaxValue) is null);
var directory=DirectoryForAssets();
for(uint type=0;type<=4;type++)foreach(var thin in new[]{false,true})
{
var icon=GalaxyOriginalIcons.ItemMarker(type,thin)!;
Check.Equal(41,icon.SpriteId);
Check.That(File.Exists(Path.Combine(directory,Path.GetFileName(icon.AssetPath))));
}
}
[Test] public void CurrentMapNamesResolveToVerifiedLegendFramesWithoutInventedFallbacks()
{
using var document=JsonDocument.Parse(File.ReadAllText(Path.Combine(DirectoryForAssets(),"source.json")));
var frames=document.RootElement.GetProperty("icons").EnumerateArray().Where(x=>x.GetProperty("resource").GetString()=="map").ToArray();
Check.Equal(170,frames.Length);Check.Equal(frames.Length,GalaxyOriginalIcons.MapFrames.Count);
foreach(var frame in frames)
{
var label=frame.GetProperty("label").GetString()!;
var key=label=="assets.CurrentLocationMarker"?"CurrentLocationMarker":label;
var icon=GalaxyOriginalIcons.Map(key);Check.That(icon is not null);
Check.Equal(frame.GetProperty("frame").GetInt32(),icon!.Frame);
Check.Equal("Assets/GalaxyIcons/"+frame.GetProperty("file").GetString(),icon.AssetPath);
}
Check.That(GalaxyOriginalIcons.Map("none") is null&&GalaxyOriginalIcons.Map("invented-bookmark-marker") is null);
Check.Equal("Assets/GalaxyIcons/Map_GM_DisplayOptions_Engineers.png",GalaxyOriginalIcons.Map("GM_DisplayOptions_Engineers")!.AssetPath);
Check.Equal("Assets/GalaxyIcons/Map_CurrentLocationMarker.svg",GalaxyOriginalIcons.Map("CurrentLocationMarker")!.AssetPath);
Check.That(GalaxyOriginalIcons.Map("GM_Marker_RescueMegaship")!.Frame!=GalaxyOriginalIcons.Bookmark(13).Frame,
"A rescue marker is not the legacy bookmark dockable-megaship icon.");
}
}
using System.Security.Cryptography;
using System.Text.Json;
using System.Xml.Linq;
using XFEEDToolBox.Core.Galaxy;
using XFEExtension.NetCore.XUnit.Attributes;
namespace XFEEDToolBox.Test;
[TestFixture]
public class GalaxyOriginalIconsTests
{
private static string DirectoryForAssets()
{
foreach(var start in new[]{Environment.CurrentDirectory,AppContext.BaseDirectory})
for(var directory=new DirectoryInfo(start);directory is not null;directory=directory.Parent)
{
var assets=Path.Combine(directory.FullName,"XFEEDToolBox","Assets","GalaxyIcons");
if(File.Exists(Path.Combine(assets,"source.json")))return assets;
}
throw new InvalidOperationException("Original galaxy icon manifest not found.");
}
[Test] public void SourceFramesHaveExactHashesAndNoMissingBitmapPlaceholders()
{
var directory=DirectoryForAssets();
using var document=JsonDocument.Parse(File.ReadAllText(Path.Combine(directory,"source.json")));
var root=document.RootElement;Check.That(root.GetProperty("exportBytesUnchanged").GetBoolean());
Check.That(!root.GetProperty("gameProcessAccess").GetBoolean());
var icons=root.GetProperty("icons").EnumerateArray().ToArray();
Check.Equal(198,icons.Length);
foreach(var icon in icons)
{
var file=Path.Combine(directory,icon.GetProperty("file").GetString()!);
var bytes=File.ReadAllBytes(file);
Check.Equal(icon.GetProperty("sha256").GetString(),Convert.ToHexStringLower(SHA256.HashData(bytes)));
if(Path.GetExtension(file)==".png")
{
Check.That(bytes.AsSpan(0,8).SequenceEqual(new byte[]{137,80,78,71,13,10,26,10}));
continue;
}
var svg=XDocument.Load(file);
Check.That(svg.Descendants().Any(x=>x.Name.LocalName=="path"));
Check.That(!svg.Descendants().Any(x=>x.Name.LocalName is "text" or "image"));
Check.That(!svg.Descendants().Attributes().Any(x=>x.Name.LocalName.Contains("bitmap",StringComparison.OrdinalIgnoreCase)),
"An unresolved Scaleform bitmap must never be packaged as a red placeholder.");
}
}
[Test] public void NativeBookmarkIdentifiersResolveToTheirOriginalNamedFrames()
{
using var document=JsonDocument.Parse(File.ReadAllText(Path.Combine(DirectoryForAssets(),"source.json")));
var root=document.RootElement;
var frames=root.GetProperty("icons").EnumerateArray().Where(x=>x.GetProperty("spriteId").GetInt32()==304).ToDictionary(x=>x.GetProperty("label").GetString()!);
foreach(var entry in root.GetProperty("nativeBookmarkMapping").GetProperty("values").EnumerateObject())
{
var native=uint.Parse(entry.Name);var name=entry.Value.GetString()!;var actual=GalaxyOriginalIcons.Bookmark(native);
Check.Equal(name,GalaxyOriginalIcons.BookmarkFrameName(native));Check.Equal(name,actual.FrameName);
if(name=="station_dodec")
{
Check.That(actual.UsesFallback);Check.Equal("Assets/GalaxyIcons/BookmarkDefault.svg",actual.AssetPath);
Check.That(!frames.ContainsKey(name),"Do not invent a station frame the original movie does not contain.");
continue;
}
Check.That(!actual.UsesFallback);
Check.Equal(frames[name].GetProperty("frame").GetInt32(),actual.Frame);
Check.Equal("Assets/GalaxyIcons/"+frames[name].GetProperty("file").GetString(),actual.AssetPath);
}
Check.Equal("default",GalaxyOriginalIcons.BookmarkFrameName(uint.MaxValue));
Check.Equal(GalaxyOriginalIcons.Bookmark(0),GalaxyOriginalIcons.Bookmark(uint.MaxValue));
}
[Test] public void ItemMarkersUseASeparateEnumAndUnknownTypesCannotBecomeCategoryPins()
{
Check.Equal("station_bernal",GalaxyOriginalIcons.Bookmark(2).FrameName);
Check.Equal("location",GalaxyOriginalIcons.ItemMarker(2)!.FrameName);
Check.Equal("locationThin",GalaxyOriginalIcons.ItemMarker(2,true)!.FrameName);
Check.That(GalaxyOriginalIcons.ItemMarker(5) is null&&GalaxyOriginalIcons.ItemMarker(uint.MaxValue) is null);
var directory=DirectoryForAssets();
for(uint type=0;type<=4;type++)foreach(var thin in new[]{false,true})
{
var icon=GalaxyOriginalIcons.ItemMarker(type,thin)!;
Check.Equal(41,icon.SpriteId);
Check.That(File.Exists(Path.Combine(directory,Path.GetFileName(icon.AssetPath))));
}
}
[Test] public void CurrentMapNamesResolveToVerifiedLegendFramesWithoutInventedFallbacks()
{
using var document=JsonDocument.Parse(File.ReadAllText(Path.Combine(DirectoryForAssets(),"source.json")));
var frames=document.RootElement.GetProperty("icons").EnumerateArray().Where(x=>x.GetProperty("resource").GetString()=="map").ToArray();
Check.Equal(170,frames.Length);Check.Equal(frames.Length,GalaxyOriginalIcons.MapFrames.Count);
foreach(var frame in frames)
{
var label=frame.GetProperty("label").GetString()!;
var key=label=="assets.CurrentLocationMarker"?"CurrentLocationMarker":label;
var icon=GalaxyOriginalIcons.Map(key);Check.That(icon is not null);
Check.Equal(frame.GetProperty("frame").GetInt32(),icon!.Frame);
Check.Equal("Assets/GalaxyIcons/"+frame.GetProperty("file").GetString(),icon.AssetPath);
}
Check.That(GalaxyOriginalIcons.Map("none") is null&&GalaxyOriginalIcons.Map("invented-bookmark-marker") is null);
Check.Equal("Assets/GalaxyIcons/Map_GM_DisplayOptions_Engineers.png",GalaxyOriginalIcons.Map("GM_DisplayOptions_Engineers")!.AssetPath);
Check.Equal("Assets/GalaxyIcons/Map_CurrentLocationMarker.svg",GalaxyOriginalIcons.Map("CurrentLocationMarker")!.AssetPath);
Check.That(GalaxyOriginalIcons.Map("GM_Marker_RescueMegaship")!.Frame!=GalaxyOriginalIcons.Bookmark(13).Frame,
"A rescue marker is not the legacy bookmark dockable-megaship icon.");
}
}