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", "
Cache budget test"); } }