using System.Security.Cryptography;
using System.Text;
namespace XFESystem.Browser.Tests;
public sealed class PackagedResourceCacheTests
{
[Fact]
public void PrewarmKeepsOriginalEmbeddedTextAndSharesItAcrossCatalogInstances()
{
int warmed = PackagedBrowserResources.PrewarmTextResources();
var first = new PackagedBrowserResources(); var second = new PackagedBrowserResources();
int checkedResources = 0;
foreach (string name in typeof(PackagedBrowserResources).Assembly.GetManifestResourceNames())
{
string normalized = name.Replace('\\', '/');
string? path = normalized.StartsWith("MonacoCore/", StringComparison.Ordinal) ? PackagedBrowserResources.MonacoCoreRoot + normalized[11..] :
normalized.StartsWith("WebsiteCode/", StringComparison.Ordinal) ? PackagedBrowserResources.WebsiteCodeRoot + normalized[12..] : null;
if (path is null || Path.GetExtension(path) is not (".js" or ".css" or ".json")) continue;
using var original = typeof(PackagedBrowserResources).Assembly.GetManifestResourceStream(name)!;
using var reader = new StreamReader(original, Encoding.UTF8, true);
string expected = reader.ReadToEnd();
Assert.True(first.TryGet(new(path), out var a)); Assert.True(second.TryGet(new(path), out var b));
Assert.NotSame(a, b); Assert.Same(a.Body, b.Body);
Assert.Equal(expected, a.Body);
Assert.Equal(SHA256.HashData(Encoding.UTF8.GetBytes(expected)), SHA256.HashData(Encoding.UTF8.GetBytes(a.Body)));
Assert.Equal(Path.GetExtension(path) switch { ".css" => "text/css", ".json" => "application/json", _ => "application/javascript" }, a.ContentType);
checkedResources++;
}
Assert.True(checkedResources > 5);
Assert.Equal(checkedResources, warmed);
Assert.Equal(warmed, PackagedBrowserResources.PrewarmTextResources());
}
[Fact]
public void LargeCoreCacheIsConcurrentAndRepeatedHitsDoNotDecodeAnotherLargeString()
{
PackagedBrowserResources.PrewarmTextResources();
var resources = new PackagedBrowserResources();
var address = new Uri(PackagedBrowserResources.MonacoCoreRoot + "EditorCore.js");
Assert.True(resources.TryGet(address, out var original));
var strings = new string[32];
Parallel.For(0, strings.Length, index =>
{
Assert.True(new PackagedBrowserResources().TryGet(address, out var response)); strings[index] = response.Body;
});
Assert.All(strings, value => Assert.Same(original.Body, value));
long characters = 0;
long allocatedBefore = GC.GetAllocatedBytesForCurrentThread();
for (int index = 0; index < 64; index++)
{
if (!resources.TryGet(address, out var response)) throw new IOException("The cached core disappeared.");
characters += response.Body.Length;
}
long allocated = GC.GetAllocatedBytesForCurrentThread() - allocatedBefore;
Assert.Equal((long)original.Body.Length * 64, characters);
Assert.InRange(allocated, 0, 1_048_576);
}
[Fact]
public void CachedScriptStillConsumesTheFullNavigationBudgetOnEveryFetch()
{
var resources = new PackagedBrowserResources();
string path = PackagedBrowserResources.WebsiteCodeRoot + "CodePalette.js";
Assert.True(resources.TryGet(new(path), out var script));
var browser = new BrowserService(new PageTransport(path), new BrowserLimits { MaximumTotalResourceCharacters = script.Body.Length * 2 - 1 }, resources);
var page = browser.Navigate("http://cache-budget.test/Index.html");
var receipt = Assert.Single(browser.LoadedResources, resource => resource.Kind == "script");
Assert.Equal(script.Body.Length, receipt.Characters);
Assert.Contains("character budget", page.Text, StringComparison.Ordinal);
Assert.Equal("object", browser.ExecuteJavaScript("typeof xfeWebsiteCodePalette"));
}
[Fact]
public void CacheRetainsOriginAllowlistAndReturnsTheCurrentRequestAddress()
{
var resources = new PackagedBrowserResources();
var address = new Uri(PackagedBrowserResources.MonacoCoreRoot + "EditorCore.js?first=1");
Assert.True(resources.TryGet(address, out var first));
var other = new Uri(PackagedBrowserResources.MonacoCoreRoot + "EditorCore.js?second=2");
Assert.True(resources.TryGet(other, out var second));
Assert.Same(first.Body, second.Body); Assert.Equal(address, first.Address); Assert.Equal(other, second.Address);
Assert.False(resources.TryGet(new("file:///C:/Secret.js"), out _));
Assert.False(resources.TryGet(new("http://foreign.test/Browser/Monaco/0.52.2/Core/EditorCore.js"), out _));
Assert.False(resources.TryGet(new(PackagedBrowserResources.MonacoCoreRoot + "Missing.js"), out _));
}
private sealed class PageTransport(string script) : IWebTransport
{
public WebResponse Get(Uri address, BrowserLimits limits) => new(address, 200, "text/html",
"<body>Cache budget test</body><script src='" + script + "'></script><script src='" + script + "'></script>");
}
}
using System.Security.Cryptography;
using System.Text;
namespace XFESystem.Browser.Tests;
public sealed class PackagedResourceCacheTests
{
[Fact]
public void PrewarmKeepsOriginalEmbeddedTextAndSharesItAcrossCatalogInstances()
{
int warmed = PackagedBrowserResources.PrewarmTextResources();
var first = new PackagedBrowserResources(); var second = new PackagedBrowserResources();
int checkedResources = 0;
foreach (string name in typeof(PackagedBrowserResources).Assembly.GetManifestResourceNames())
{
string normalized = name.Replace('\\', '/');
string? path = normalized.StartsWith("MonacoCore/", StringComparison.Ordinal) ? PackagedBrowserResources.MonacoCoreRoot + normalized[11..] :
normalized.StartsWith("WebsiteCode/", StringComparison.Ordinal) ? PackagedBrowserResources.WebsiteCodeRoot + normalized[12..] : null;
if (path is null || Path.GetExtension(path) is not (".js" or ".css" or ".json")) continue;
using var original = typeof(PackagedBrowserResources).Assembly.GetManifestResourceStream(name)!;
using var reader = new StreamReader(original, Encoding.UTF8, true);
string expected = reader.ReadToEnd();
Assert.True(first.TryGet(new(path), out var a)); Assert.True(second.TryGet(new(path), out var b));
Assert.NotSame(a, b); Assert.Same(a.Body, b.Body);
Assert.Equal(expected, a.Body);
Assert.Equal(SHA256.HashData(Encoding.UTF8.GetBytes(expected)), SHA256.HashData(Encoding.UTF8.GetBytes(a.Body)));
Assert.Equal(Path.GetExtension(path) switch { ".css" => "text/css", ".json" => "application/json", _ => "application/javascript" }, a.ContentType);
checkedResources++;
}
Assert.True(checkedResources > 5);
Assert.Equal(checkedResources, warmed);
Assert.Equal(warmed, PackagedBrowserResources.PrewarmTextResources());
}
[Fact]
public void LargeCoreCacheIsConcurrentAndRepeatedHitsDoNotDecodeAnotherLargeString()
{
PackagedBrowserResources.PrewarmTextResources();
var resources = new PackagedBrowserResources();
var address = new Uri(PackagedBrowserResources.MonacoCoreRoot + "EditorCore.js");
Assert.True(resources.TryGet(address, out var original));
var strings = new string[32];
Parallel.For(0, strings.Length, index =>
{
Assert.True(new PackagedBrowserResources().TryGet(address, out var response)); strings[index] = response.Body;
});
Assert.All(strings, value => Assert.Same(original.Body, value));
long characters = 0;
long allocatedBefore = GC.GetAllocatedBytesForCurrentThread();
for (int index = 0; index < 64; index++)
{
if (!resources.TryGet(address, out var response)) throw new IOException("The cached core disappeared.");
characters += response.Body.Length;
}
long allocated = GC.GetAllocatedBytesForCurrentThread() - allocatedBefore;
Assert.Equal((long)original.Body.Length * 64, characters);
Assert.InRange(allocated, 0, 1_048_576);
}
[Fact]
public void CachedScriptStillConsumesTheFullNavigationBudgetOnEveryFetch()
{
var resources = new PackagedBrowserResources();
string path = PackagedBrowserResources.WebsiteCodeRoot + "CodePalette.js";
Assert.True(resources.TryGet(new(path), out var script));
var browser = new BrowserService(new PageTransport(path), new BrowserLimits { MaximumTotalResourceCharacters = script.Body.Length * 2 - 1 }, resources);
var page = browser.Navigate("http://cache-budget.test/Index.html");
var receipt = Assert.Single(browser.LoadedResources, resource => resource.Kind == "script");
Assert.Equal(script.Body.Length, receipt.Characters);
Assert.Contains("character budget", page.Text, StringComparison.Ordinal);
Assert.Equal("object", browser.ExecuteJavaScript("typeof xfeWebsiteCodePalette"));
}
[Fact]
public void CacheRetainsOriginAllowlistAndReturnsTheCurrentRequestAddress()
{
var resources = new PackagedBrowserResources();
var address = new Uri(PackagedBrowserResources.MonacoCoreRoot + "EditorCore.js?first=1");
Assert.True(resources.TryGet(address, out var first));
var other = new Uri(PackagedBrowserResources.MonacoCoreRoot + "EditorCore.js?second=2");
Assert.True(resources.TryGet(other, out var second));
Assert.Same(first.Body, second.Body); Assert.Equal(address, first.Address); Assert.Equal(other, second.Address);
Assert.False(resources.TryGet(new("file:///C:/Secret.js"), out _));
Assert.False(resources.TryGet(new("http://foreign.test/Browser/Monaco/0.52.2/Core/EditorCore.js"), out _));
Assert.False(resources.TryGet(new(PackagedBrowserResources.MonacoCoreRoot + "Missing.js"), out _));
}
private sealed class PageTransport(string script) : IWebTransport
{
public WebResponse Get(Uri address, BrowserLimits limits) => new(address, 200, "text/html",
"<body>Cache budget test</body><script src='" + script + "'></script><script src='" + script + "'></script>");
}
}