namespace MBN_STOCK_WEBVIEW.Playout.Tests; internal sealed class EnvironmentScope : IDisposable { private readonly Dictionary _originalValues = new(StringComparer.Ordinal); public EnvironmentScope Set(string name, string? value) { if (!_originalValues.ContainsKey(name)) { _originalValues.Add(name, Environment.GetEnvironmentVariable(name)); } Environment.SetEnvironmentVariable(name, value); return this; } public void Dispose() { foreach (var pair in _originalValues) { Environment.SetEnvironmentVariable(pair.Key, pair.Value); } } } internal sealed class TemporaryJsonFile : IDisposable { private TemporaryJsonFile(string path) { Path = path; } public string Path { get; } public static TemporaryJsonFile Create(string json) { var directory = System.IO.Path.Combine( System.IO.Path.GetTempPath(), "MBN_STOCK_WEBVIEW.Playout.Tests", Guid.NewGuid().ToString("N")); Directory.CreateDirectory(directory); var path = System.IO.Path.Combine(directory, "playout.local.json"); File.WriteAllText(path, json); return new TemporaryJsonFile(path); } public static TemporaryJsonFile Missing() { var directory = System.IO.Path.Combine( System.IO.Path.GetTempPath(), "MBN_STOCK_WEBVIEW.Playout.Tests", Guid.NewGuid().ToString("N")); return new TemporaryJsonFile( System.IO.Path.Combine(directory, "missing-playout.local.json")); } public void Dispose() { var directory = System.IO.Path.GetDirectoryName(Path); if (directory is not null && Directory.Exists(directory)) { Directory.Delete(directory, recursive: true); } } } internal sealed class TemporarySceneDirectory : IDisposable { private TemporarySceneDirectory(string path) { Path = path; } public string Path { get; } public static TemporarySceneDirectory Create(params string[] relativeFiles) { var path = System.IO.Path.Combine( System.IO.Path.GetTempPath(), "MBN_STOCK_WEBVIEW.Playout.Tests", Guid.NewGuid().ToString("N"), "Scenes"); Directory.CreateDirectory(path); var result = new TemporarySceneDirectory(path); foreach (var relativeFile in relativeFiles) { result.AddFile(relativeFile); } return result; } public string AddFile(string relativePath) { var fullPath = System.IO.Path.GetFullPath(System.IO.Path.Combine(Path, relativePath)); var rootPrefix = Path.EndsWith(System.IO.Path.DirectorySeparatorChar) ? Path : Path + System.IO.Path.DirectorySeparatorChar; if (!fullPath.StartsWith(rootPrefix, StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("Test file must remain under the temporary scene directory.", nameof(relativePath)); } Directory.CreateDirectory(System.IO.Path.GetDirectoryName(fullPath)!); File.WriteAllText(fullPath, "fake test scene; never loaded by a real COM server"); return fullPath; } public void Dispose() { var parent = Directory.GetParent(Path)?.FullName; if (parent is not null && Directory.Exists(parent)) { Directory.Delete(parent, recursive: true); } } }