namespace MBN_STOCK_WEBVIEW.LegacyWeb.Tests; public sealed class LegacyInteractionMetricsNativeContractTests { private static readonly string RepositoryRoot = FindRepositoryRoot(); private static readonly string AppRoot = Path.Combine( RepositoryRoot, "src", "MBN_STOCK_WEBVIEW.LegacyParityApp"); private static readonly string Window = File.ReadAllText( Path.Combine(AppRoot, "MainWindow.xaml.cs")); [Fact] public void NativeWindowReadsBothWindowsDragThresholdsInCssDipCoordinates() { Assert.Contains("private const int SmCxDrag = 68;", Window, StringComparison.Ordinal); Assert.Contains("private const int SmCyDrag = 69;", Window, StringComparison.Ordinal); Assert.Contains("[DllImport(\"user32.dll\", ExactSpelling = true)]", Window, StringComparison.Ordinal); Assert.Contains( "GetSystemMetricsForDpi(\n" + " SmCxDrag,\n" + " LegacyInteractionMetrics.CssPixelsPerInch)", Window.Replace("\r\n", "\n", StringComparison.Ordinal), StringComparison.Ordinal); Assert.Contains( "GetSystemMetricsForDpi(\n" + " SmCyDrag,\n" + " LegacyInteractionMetrics.CssPixelsPerInch)", Window.Replace("\r\n", "\n", StringComparison.Ordinal), StringComparison.Ordinal); Assert.DoesNotContain("GetSystemMetrics(", Window, StringComparison.Ordinal); Assert.Contains("LegacyInteractionMetrics.FromPixelsAtDpi(", Window, StringComparison.Ordinal); Assert.Contains("private static extern uint GetDoubleClickTime();", Window, StringComparison.Ordinal); Assert.Contains( "doubleClickTimeMilliseconds: (int)GetDoubleClickTime()", Window, StringComparison.Ordinal); Assert.Equal(2, CountOccurrences( Window, "[DllImport(\"user32.dll\", ExactSpelling = true)]")); Assert.Contains("logical DIP coordinate space used by XAML", Window, StringComparison.Ordinal); Assert.Contains("Root.XamlRoot?.RasterizationScale", Window, StringComparison.Ordinal); } [Fact] public void NativeWindowRefreshesMetricsAfterRuntimeSettingsAndDpiChanges() { Assert.Contains("interactionMetrics: _interactionMetrics", Window, StringComparison.Ordinal); Assert.Contains("private const uint WmSettingChange = 0x001A;", Window, StringComparison.Ordinal); Assert.Contains("private const uint WmDisplayChange = 0x007E;", Window, StringComparison.Ordinal); Assert.Contains("private const uint WmDpiChanged = 0x02E0;", Window, StringComparison.Ordinal); Assert.Contains("AttachInteractionMetricsRefresh();", Window, StringComparison.Ordinal); Assert.Contains("DetachInteractionMetricsRefresh();", Window, StringComparison.Ordinal); Assert.Contains("SetWindowSubclass(", Window, StringComparison.Ordinal); Assert.Contains("RemoveWindowSubclass(", Window, StringComparison.Ordinal); Assert.Contains( "message is WmSettingChange or WmDisplayChange or WmDpiChanged", Window, StringComparison.Ordinal); Assert.Contains("QueueInteractionMetricsRefresh();", Window, StringComparison.Ordinal); Assert.Contains("DispatcherQueuePriority.High", Window, StringComparison.Ordinal); Assert.True( CountOccurrences(Window, "RefreshInteractionMetrics();") >= 3, "Metrics must be refreshed at setup, runtime change, and state posting."); Assert.DoesNotContain( "private readonly LegacyInteractionMetrics _interactionMetrics", Window, StringComparison.Ordinal); } [Fact] public void NativeWindowDisablesFutureWebZoomAndFallsBackWithoutPrivateApis() { Assert.Contains( "coreWebView.Settings.AreBrowserAcceleratorKeysEnabled = false;", Window, StringComparison.Ordinal); Assert.Contains("coreWebView.Settings.IsZoomControlEnabled = false;", Window, StringComparison.Ordinal); Assert.Contains("coreWebView.Settings.IsPinchZoomEnabled = false;", Window, StringComparison.Ordinal); Assert.DoesNotContain("CoreWebView2Controller.ZoomFactor", Window, StringComparison.Ordinal); Assert.Contains("catch (DllNotFoundException)", Window, StringComparison.Ordinal); Assert.Contains("catch (EntryPointNotFoundException)", Window, StringComparison.Ordinal); Assert.Contains("catch (BadImageFormatException)", Window, StringComparison.Ordinal); Assert.Contains("catch (PlatformNotSupportedException)", Window, StringComparison.Ordinal); Assert.Equal( 4, CountOccurrences(Window, "return CreateFallbackInteractionMetrics();")); Assert.Contains( "LegacyInteractionMetrics.Default with\n" + " {\n" + " HostRasterizationScale = ReadHostRasterizationScale()", Window.Replace("\r\n", "\n", StringComparison.Ordinal), StringComparison.Ordinal); } private static int CountOccurrences(string value, string search) { var count = 0; var index = 0; while ((index = value.IndexOf(search, index, StringComparison.Ordinal)) >= 0) { count++; index += search.Length; } return count; } private static string FindRepositoryRoot() { var current = new DirectoryInfo(AppContext.BaseDirectory); while (current is not null) { if (File.Exists(Path.Combine(current.FullName, "MBN_STOCK_WEBVIEW.sln"))) { return current.FullName; } current = current.Parent; } throw new DirectoryNotFoundException("Repository root was not found."); } }