feat: add modern app icon

This commit is contained in:
2026-07-21 10:36:02 +09:00
parent d9b477e543
commit 5ccf8b8ffd
16 changed files with 138 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
using System.Buffers.Binary;
namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests;
public sealed class LegacyAppIconContractTests
{
private static readonly string RepositoryRoot = FindRepositoryRoot();
private static readonly string AssetsRoot = Path.Combine(RepositoryRoot, "Assets");
private static readonly string AppRoot = Path.Combine(
RepositoryRoot,
"src",
"MBN_STOCK_WEBVIEW.LegacyParityApp");
public static TheoryData<string, int, int> PackagePngAssets => new()
{
{ "LockScreenLogo.scale-200.png", 48, 48 },
{ "SplashScreen.scale-200.png", 1240, 600 },
{ "Square150x150Logo.scale-200.png", 300, 300 },
{ "Square44x44Logo.scale-200.png", 88, 88 },
{ "Square44x44Logo.targetsize-16_altform-unplated.png", 16, 16 },
{ "Square44x44Logo.targetsize-24_altform-unplated.png", 24, 24 },
{ "Square44x44Logo.targetsize-32_altform-unplated.png", 32, 32 },
{ "Square44x44Logo.targetsize-48_altform-unplated.png", 48, 48 },
{ "Square44x44Logo.targetsize-256_altform-unplated.png", 256, 256 },
{ "StoreLogo.png", 50, 50 },
{ "Wide310x150Logo.scale-200.png", 620, 300 }
};
[Theory]
[MemberData(nameof(PackagePngAssets))]
public void PackageIconsAreExactRgbaPngAssets(string fileName, int width, int height)
{
var bytes = File.ReadAllBytes(Path.Combine(AssetsRoot, fileName));
Assert.True(
bytes.Length > Math.Max(500, (width * height) / 10),
$"{fileName} still resembles an unrendered placeholder asset.");
Assert.Equal(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 }, bytes[..8]);
Assert.Equal("IHDR", System.Text.Encoding.ASCII.GetString(bytes, 12, 4));
Assert.Equal(width, BinaryPrimitives.ReadInt32BigEndian(bytes.AsSpan(16, 4)));
Assert.Equal(height, BinaryPrimitives.ReadInt32BigEndian(bytes.AsSpan(20, 4)));
Assert.Equal(8, bytes[24]);
Assert.Equal(6, bytes[25]);
}
[Fact]
public void ExecutableIconContainsEveryRequiredWindowsSize()
{
var bytes = File.ReadAllBytes(Path.Combine(AssetsRoot, "AppIcon.ico"));
Assert.True(bytes.Length > 1000);
Assert.Equal((ushort)0, BinaryPrimitives.ReadUInt16LittleEndian(bytes.AsSpan(0, 2)));
Assert.Equal((ushort)1, BinaryPrimitives.ReadUInt16LittleEndian(bytes.AsSpan(2, 2)));
var count = BinaryPrimitives.ReadUInt16LittleEndian(bytes.AsSpan(4, 2));
Assert.Equal(6, count);
var sizes = new List<int>();
for (var index = 0; index < count; index++)
{
var width = bytes[6 + (index * 16)];
var height = bytes[7 + (index * 16)];
Assert.Equal(width, height);
sizes.Add(width == 0 ? 256 : width);
}
Assert.Equal(new[] { 16, 24, 32, 48, 64, 256 }, sizes.Order());
}
[Fact]
public void ProjectAndWindowUseTheSharedIconWithoutPackagingTheMasterArtwork()
{
var project = File.ReadAllText(Path.Combine(
AppRoot,
"MBN_STOCK_WEBVIEW.LegacyParityApp.csproj"));
var window = File.ReadAllText(Path.Combine(AppRoot, "MainWindow.xaml.cs"));
var manifest = File.ReadAllText(Path.Combine(AppRoot, "Package.appxmanifest"));
Assert.Contains("<ApplicationIcon>..\\..\\Assets\\AppIcon.ico</ApplicationIcon>",
project,
StringComparison.Ordinal);
Assert.Contains("Link=\"Assets\\AppIcon.ico\"", project, StringComparison.Ordinal);
foreach (var targetSize in new[] { 16, 24, 32, 48, 256 })
{
Assert.Contains(
$"Square44x44Logo.targetsize-{targetSize}_altform-unplated.png",
project,
StringComparison.Ordinal);
}
Assert.DoesNotContain("AppIconMaster.png", project, StringComparison.Ordinal);
Assert.Contains(
"Path.Combine(AppContext.BaseDirectory, \"Assets\", \"AppIcon.ico\")",
window,
StringComparison.Ordinal);
Assert.Contains("appWindow.SetIcon(iconPath)", window, StringComparison.Ordinal);
Assert.Contains("Square150x150Logo=\"Assets\\Square150x150Logo.png\"",
manifest,
StringComparison.Ordinal);
Assert.Contains("Square44x44Logo=\"Assets\\Square44x44Logo.png\"",
manifest,
StringComparison.Ordinal);
Assert.Contains("Wide310x150Logo=\"Assets\\Wide310x150Logo.png\"",
manifest,
StringComparison.Ordinal);
Assert.Contains("<uap:SplashScreen Image=\"Assets\\SplashScreen.png\" />",
manifest,
StringComparison.Ordinal);
}
private static string FindRepositoryRoot()
{
var directory = new DirectoryInfo(AppContext.BaseDirectory);
while (directory is not null)
{
if (File.Exists(Path.Combine(directory.FullName, "MBN_STOCK_WEBVIEW.sln")))
{
return directory.FullName;
}
directory = directory.Parent;
}
throw new DirectoryNotFoundException("Repository root could not be located.");
}
}