From ae17ff2d899c130da2a36cbc0e92b795f78cde62 Mon Sep 17 00:00:00 2001 From: Cinka Date: Thu, 3 Jul 2025 12:17:15 +0300 Subject: [PATCH] - add: Unit tests --- Nebula.Launcher/Assets/lang/en-US.ftl | 1 + Nebula.Launcher/Assets/lang/ru-RU.ftl | 1 + .../Pages/ConfigurationViewModel.cs | 12 +- .../Services/ConfigurationService.cs | 2 +- Nebula.Shared/Services/FileService.cs | 3 +- Nebula.Shared/Services/RestService.cs | 5 +- Nebula.UnitTest/Nebula.UnitTest.csproj | 31 +++++ .../NebulaSharedTests/BaseSharedTest.cs | 16 +++ .../ConfigurationServiceTests.cs | 90 +++++++++++++ .../NebulaSharedTests/FileServiceTests.cs | 123 ++++++++++++++++++ .../PopupMessageServiceTests.cs | 42 ++++++ .../NebulaSharedTests/RestServiceTests.cs | 77 +++++++++++ Nebula.UnitTest/TestServiceHelper.cs | 46 +++++++ Nebula.sln | 6 + Nebula.sln.DotSettings.user | 24 +++- 15 files changed, 467 insertions(+), 12 deletions(-) create mode 100644 Nebula.UnitTest/Nebula.UnitTest.csproj create mode 100644 Nebula.UnitTest/NebulaSharedTests/BaseSharedTest.cs create mode 100644 Nebula.UnitTest/NebulaSharedTests/ConfigurationServiceTests.cs create mode 100644 Nebula.UnitTest/NebulaSharedTests/FileServiceTests.cs create mode 100644 Nebula.UnitTest/NebulaSharedTests/PopupMessageServiceTests.cs create mode 100644 Nebula.UnitTest/NebulaSharedTests/RestServiceTests.cs create mode 100644 Nebula.UnitTest/TestServiceHelper.cs diff --git a/Nebula.Launcher/Assets/lang/en-US.ftl b/Nebula.Launcher/Assets/lang/en-US.ftl index 838d2a5..4384ab8 100644 --- a/Nebula.Launcher/Assets/lang/en-US.ftl +++ b/Nebula.Launcher/Assets/lang/en-US.ftl @@ -40,6 +40,7 @@ config-export-logs = Export logs config-open-data = Open data path config-reset = Reset to default config-save = Save changes +config-remove-content-all = Remove all content filter-roleplay = Roleplay filter-language = Language diff --git a/Nebula.Launcher/Assets/lang/ru-RU.ftl b/Nebula.Launcher/Assets/lang/ru-RU.ftl index 0fb7b7d..1974406 100644 --- a/Nebula.Launcher/Assets/lang/ru-RU.ftl +++ b/Nebula.Launcher/Assets/lang/ru-RU.ftl @@ -40,6 +40,7 @@ config-export-logs = Экспортировать логи config-open-data = Открыть путь данных config-reset = Сбросить к значениям по умолчанию config-save = Сохранить изменения +config-remove-content-all = Удалить весь контент filter-roleplay = Ролевая игра filter-language = Язык diff --git a/Nebula.Launcher/ViewModels/Pages/ConfigurationViewModel.cs b/Nebula.Launcher/ViewModels/Pages/ConfigurationViewModel.cs index b9172cc..0300285 100644 --- a/Nebula.Launcher/ViewModels/Pages/ConfigurationViewModel.cs +++ b/Nebula.Launcher/ViewModels/Pages/ConfigurationViewModel.cs @@ -32,16 +32,16 @@ public partial class ConfigurationViewModel : ViewModelBase [GenerateProperty] private FileService FileService { get; set; } = default!; [GenerateProperty] private ContentService ContentService { get; set; } = default!; [GenerateProperty] private CancellationService CancellationService { get; set; } = default!; - [GenerateProperty] private ViewHelperService ViewHelperService { get; set; } = default!; - public List<(object, Type)> ConVarList = new(); + + private readonly List<(object, Type)> _conVarList = new(); public void AddCvarConf(ConVar cvar) { ConfigurationVerbose.Add( ConfigControlHelper.GetConfigControl(cvar.Name, ConfigurationService.GetConfigValue(cvar)!)); - ConVarList.Add((cvar, cvar.Type)); + _conVarList.Add((cvar, cvar.Type)); } public void InvokeUpdateConfiguration() @@ -52,7 +52,7 @@ public partial class ConfigurationViewModel : ViewModelBase if(!conVarControl.Dirty) continue; - var conVar = ConVarList[i]; + var conVar = _conVarList[i]; var methodInfo = ConfigurationService.GetType().GetMethod("SetConfigValue")!.MakeGenericMethod(conVar.Item2); methodInfo.Invoke(ConfigurationService, [conVar.Item1, conVarControl.GetValue()]); } @@ -60,13 +60,13 @@ public partial class ConfigurationViewModel : ViewModelBase public void ResetConfig() { - foreach (var conVar in ConVarList) + foreach (var conVar in _conVarList) { var methodInfo = ConfigurationService.GetType().GetMethod("SetConfigValue")!.MakeGenericMethod(conVar.Item2); methodInfo.Invoke(ConfigurationService, [conVar.Item1, null]); } - ConVarList.Clear(); + _conVarList.Clear(); ConfigurationVerbose.Clear(); InitConfiguration(); diff --git a/Nebula.Shared/Services/ConfigurationService.cs b/Nebula.Shared/Services/ConfigurationService.cs index 013c088..3361962 100644 --- a/Nebula.Shared/Services/ConfigurationService.cs +++ b/Nebula.Shared/Services/ConfigurationService.cs @@ -112,7 +112,7 @@ public class ConfigurationService return false; } - public void SetConfigValue(ConVar conVar, T value) + public void SetConfigValue(ConVar conVar, T? value) { if (value == null) { diff --git a/Nebula.Shared/Services/FileService.cs b/Nebula.Shared/Services/FileService.cs index f0e862a..09831e4 100644 --- a/Nebula.Shared/Services/FileService.cs +++ b/Nebula.Shared/Services/FileService.cs @@ -1,5 +1,4 @@ using System.IO.Compression; -using System.Runtime.InteropServices; using Nebula.Shared.FileApis; using Nebula.Shared.FileApis.Interfaces; using Nebula.Shared.Models; @@ -11,7 +10,7 @@ namespace Nebula.Shared.Services; [ServiceRegister] public class FileService { - public static readonly string RootPath = Path.Join(Environment.GetFolderPath( + public static string RootPath = Path.Join(Environment.GetFolderPath( Environment.SpecialFolder.ApplicationData), "Datum"); private readonly ILogger _logger; diff --git a/Nebula.Shared/Services/RestService.cs b/Nebula.Shared/Services/RestService.cs index 1cf0cb4..adf5285 100644 --- a/Nebula.Shared/Services/RestService.cs +++ b/Nebula.Shared/Services/RestService.cs @@ -11,7 +11,7 @@ namespace Nebula.Shared.Services; [ServiceRegister] public class RestService { - private readonly HttpClient _client = new(); + private readonly HttpClient _client; private readonly ILogger _logger; private readonly JsonSerializerOptions _serializerOptions = new() @@ -20,8 +20,9 @@ public class RestService WriteIndented = true }; - public RestService(DebugService debug) + public RestService(DebugService debug, HttpClient? client = null) { + _client = client ?? new HttpClient(); _logger = debug.GetLogger(this); } diff --git a/Nebula.UnitTest/Nebula.UnitTest.csproj b/Nebula.UnitTest/Nebula.UnitTest.csproj new file mode 100644 index 0000000..4736546 --- /dev/null +++ b/Nebula.UnitTest/Nebula.UnitTest.csproj @@ -0,0 +1,31 @@ + + + + net9.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/Nebula.UnitTest/NebulaSharedTests/BaseSharedTest.cs b/Nebula.UnitTest/NebulaSharedTests/BaseSharedTest.cs new file mode 100644 index 0000000..bee5ebd --- /dev/null +++ b/Nebula.UnitTest/NebulaSharedTests/BaseSharedTest.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Nebula.UnitTest.NebulaSharedTests; + +public abstract class BaseSharedTest +{ + protected SharedUnit _sharedUnit = default!; + + public abstract void BeforeServiceBuild(IServiceCollection services); + + public virtual void Setup() + { + _sharedUnit = TestServiceHelper.GetSharedUnit(BeforeServiceBuild); + } +} + diff --git a/Nebula.UnitTest/NebulaSharedTests/ConfigurationServiceTests.cs b/Nebula.UnitTest/NebulaSharedTests/ConfigurationServiceTests.cs new file mode 100644 index 0000000..9f5e541 --- /dev/null +++ b/Nebula.UnitTest/NebulaSharedTests/ConfigurationServiceTests.cs @@ -0,0 +1,90 @@ +using Microsoft.Extensions.DependencyInjection; +using Nebula.Shared.Services; + +namespace Nebula.UnitTest.NebulaSharedTests; + +[TestFixture] +[TestOf(typeof(ConfigurationService))] +public sealed class ConfigurationServiceTests: BaseSharedTest +{ + private ConfigurationService _conVarService; + + public override void BeforeServiceBuild(IServiceCollection services) + { + TestServiceHelper.InitFileServiceTest(); + } + + [SetUp] + public override void Setup() + { + base.Setup(); + _conVarService = _sharedUnit.GetService(); + } + + [Test] + public void GetDefaultConVarTest() + { + var value = _conVarService.GetConfigValue(TestConVar.SimpleConvar); + Assert.NotNull(value); + Assert.That(value, Is.EqualTo(TestConVar.SimpleConvar.DefaultValue)); + } + + [Test] + public void GetNullConVarTest() + { + var value = _conVarService.GetConfigValue(TestConVar.NullConvar); + Assert.Null(value); + } + + [Test] + public void WriteConVarTest() + { + var value = _conVarService.GetConfigValue(TestConVar.SimpleConvar); + Assert.That(value, Is.EqualTo(TestConVar.SimpleConvar.DefaultValue)); + + _conVarService.SetConfigValue(TestConVar.SimpleConvar, "notdefault"); + value = _conVarService.GetConfigValue(TestConVar.SimpleConvar); + Assert.That(value, Is.Not.EqualTo(TestConVar.SimpleConvar.DefaultValue)); + Assert.That(value, Is.EqualTo("notdefault")); + + _conVarService.SetConfigValue(TestConVar.SimpleConvar, null); + + value = _conVarService.GetConfigValue(TestConVar.SimpleConvar); + Assert.That(value, Is.EqualTo(TestConVar.SimpleConvar.DefaultValue)); + } + + [Test] + public void WriteComplexConvarTest() + { + var testVar = new TestVarObject("Alex", 2); + _conVarService.SetConfigValue(TestConVar.TestVarObject, testVar); + var value = _conVarService.GetConfigValue(TestConVar.TestVarObject); + Assert.That(value, Is.EqualTo(testVar)); + + _conVarService.SetConfigValue(TestConVar.TestVarObject, default); + } + + [Test] + public void WriteArrayConvarTest() + { + var testVarArr = new[] { new TestVarObject("Alex", 2), new TestVarObject("Vitya", 3) }; + _conVarService.SetConfigValue(TestConVar.TestVarArray, testVarArr); + var value = _conVarService.GetConfigValue(TestConVar.TestVarArray); + Assert.NotNull(value); + Assert.That(testVarArr.SequenceEqual(value)); + _conVarService.SetConfigValue(TestConVar.TestVarArray, null); + } + + +} + +public static class TestConVar +{ + public static ConVar SimpleConvar = ConVarBuilder.Build("test.convarsimple", "test"); + public static ConVar NullConvar = ConVarBuilder.Build("test.convarsimplenull"); + + public static ConVar TestVarObject = ConVarBuilder.Build("test.convarobject", default); + public static ConVar TestVarArray = ConVarBuilder.Build("test.convarobject.array"); +} + +public record struct TestVarObject(string Name, int Count); \ No newline at end of file diff --git a/Nebula.UnitTest/NebulaSharedTests/FileServiceTests.cs b/Nebula.UnitTest/NebulaSharedTests/FileServiceTests.cs new file mode 100644 index 0000000..7dc0ee9 --- /dev/null +++ b/Nebula.UnitTest/NebulaSharedTests/FileServiceTests.cs @@ -0,0 +1,123 @@ +using System.IO.Compression; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using Nebula.Shared.Models; +using Nebula.Shared.Services; +using Robust.LoaderApi; + +namespace Nebula.UnitTest.NebulaSharedTests; + +[TestFixture] +[TestOf(typeof(FileService))] +public class FileServiceTests : BaseSharedTest +{ + private FileService _fileService = default!; + + public override void BeforeServiceBuild(IServiceCollection services) + { + TestServiceHelper.InitFileServiceTest(); + } + + [SetUp] + public override void Setup() + { + base.Setup(); + _fileService = _sharedUnit.GetService(); + } + + [Test] + public void CreateFileApi_CreatesCorrectPath() + { + var subPath = "test-folder"; + var fileApi = _fileService.CreateFileApi(subPath); + + using (var stream = new MemoryStream("test"u8.ToArray())) + { + fileApi.Save("test.txt", stream); + } + + var expectedPath = Path.Combine(FileService.RootPath, subPath); + + Assert.That(Directory.Exists(expectedPath), Is.True, $"Expected path to be created: {expectedPath}"); + } + + [Test] + public void EnsureTempDir_CreatesDirectoryAndReturnsApi() + { + var api = _fileService.EnsureTempDir(out var path); + + Assert.That(Directory.Exists(path), Is.True); + Assert.That(api, Is.Not.Null); + } + + [Test] + public void OpenZip_ReturnsZipFileApi_WhenValid() + { + var testZipPath = Path.Combine(FileService.RootPath, "test.zip"); + using (var archive = ZipFile.Open(testZipPath, ZipArchiveMode.Create)) + { + var entry = archive.CreateEntry("test.txt"); + using var streamWriter = new StreamWriter(entry.Open()); + streamWriter.Write(testZipPath); + streamWriter.Flush(); + } + + IDisposable? streamDisposable = null; + + var mockFileApi = new Mock(); + mockFileApi + .Setup(x => x.TryOpen(testZipPath, out It.Ref.IsAny)) + .Returns((string _, out Stream stream) => + { + stream = File.OpenRead(testZipPath); + streamDisposable = stream; + return true; + }); + + var zipApi = _fileService.OpenZip(testZipPath, mockFileApi.Object); + Assert.That(zipApi, Is.Not.Null); + + Assert.That(zipApi.TryOpen("test.txt", out var textStream), Is.True); + + using (var reader = new StreamReader(textStream!)) + { + Assert.That(reader.ReadToEnd(), Is.EqualTo(testZipPath)); + } + + textStream!.Dispose(); + streamDisposable?.Dispose(); + + File.Delete(testZipPath); + } + + [Test] + public void RemoveAllFiles_DeletesAllFilesAndDirectories() + { + var testDir = Path.Combine(FileService.RootPath, "cleanup-test"); + Directory.CreateDirectory(testDir); + + File.WriteAllText(Path.Combine(testDir, "test1.txt"), "data"); + Directory.CreateDirectory(Path.Combine(testDir, "subdir")); + + var mockHandler = new Mock(); + mockHandler.Setup(x => x.AppendJob(It.IsAny())).Verifiable(); + mockHandler.Setup(x => x.AppendResolvedJob(It.IsAny())).Verifiable(); + + _fileService.RemoveAllFiles("cleanup-test", mockHandler.Object, CancellationToken.None); + + Assert.That(Directory.Exists(testDir), Is.True); + Assert.That(Directory.GetFiles(testDir).Length, Is.EqualTo(0)); + Assert.That(Directory.GetDirectories(testDir).Length, Is.EqualTo(0)); + } + + [Test] + public void OpenZip_ThrowsException_WhenFileApiFails() + { + var mockFileApi = new Mock(); + mockFileApi.Setup(x => x.TryOpen(It.IsAny(), out It.Ref.IsAny)) + .Returns(false); + + var result = _fileService.OpenZip("invalid.zip", mockFileApi.Object); + Assert.That(result, Is.Null); + } +} diff --git a/Nebula.UnitTest/NebulaSharedTests/PopupMessageServiceTests.cs b/Nebula.UnitTest/NebulaSharedTests/PopupMessageServiceTests.cs new file mode 100644 index 0000000..11fbc45 --- /dev/null +++ b/Nebula.UnitTest/NebulaSharedTests/PopupMessageServiceTests.cs @@ -0,0 +1,42 @@ +using Microsoft.Extensions.DependencyInjection; +using Nebula.Shared.Services; + +namespace Nebula.UnitTest.NebulaSharedTests; + +[TestFixture] +[TestOf(nameof(PopupMessageService))] +public class PopupMessageServiceTests : BaseSharedTest +{ + public override void BeforeServiceBuild(IServiceCollection services) + { + } + + [SetUp] + public override void Setup() + { + base.Setup(); + + var popupService = _sharedUnit.GetService(); + + popupService.OnCloseRequired = (popup) => ((IDisposable)popup).Dispose(); + } + + [Test] + public void DisposeTest() + { + var popup = new TestPopup(); + var popupService = _sharedUnit.GetService(); + popupService.ClosePopup(popup); + Assert.That(popup.Disposed, Is.True); + } + + private sealed class TestPopup : IDisposable + { + public bool Disposed { get; private set; } + + public void Dispose() + { + Disposed = true; + } + } +} \ No newline at end of file diff --git a/Nebula.UnitTest/NebulaSharedTests/RestServiceTests.cs b/Nebula.UnitTest/NebulaSharedTests/RestServiceTests.cs new file mode 100644 index 0000000..d857501 --- /dev/null +++ b/Nebula.UnitTest/NebulaSharedTests/RestServiceTests.cs @@ -0,0 +1,77 @@ +using System.Net; +using System.Text; +using System.Text.Json; +using Microsoft.Extensions.DependencyInjection; +using Moq; +using Moq.Protected; +using Nebula.Shared.Services; + +namespace Nebula.UnitTest.NebulaSharedTests; + +[TestFixture] +[TestOf(typeof(RestService))] +public class RestServiceTests : BaseSharedTest +{ + public static readonly TestDto ExpectedObject = new() + { + Id = 1, + Name = "Test", + }; + + public static string ObjectString => JsonSerializer.Serialize(ExpectedObject, SerializerOptions); + + public static readonly JsonSerializerOptions SerializerOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + + public override void BeforeServiceBuild(IServiceCollection services) + { + var mockHandler = new Mock(); + mockHandler + .Protected() + .Setup>("SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(ObjectString, Encoding.UTF8, "application/json") + }); + + var client = new HttpClient(mockHandler.Object); + + services.AddSingleton(client); + } + + [SetUp] + public override void Setup() + { + base.Setup(); + } + + [Test] + public async Task GetTest() + { + var restService = _sharedUnit.GetService(); + var result = await restService.GetAsync(new Uri("http://localhost/test"), CancellationToken.None); + + Assert.NotNull(result); + Assert.That(result.Id, Is.EqualTo(ExpectedObject.Id)); + Assert.That(result.Name, Is.EqualTo(ExpectedObject.Name)); + } + + [Test] + public async Task PostTest() + { + var restService = _sharedUnit.GetService(); + var result = await restService.PostAsync(ExpectedObject,new Uri("http://localhost/test"), CancellationToken.None); + + Assert.NotNull(result); + Assert.That(result.Id, Is.EqualTo(ExpectedObject.Id)); + Assert.That(result.Name, Is.EqualTo(ExpectedObject.Name)); + } + + public class TestDto + { + public int Id { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/Nebula.UnitTest/TestServiceHelper.cs b/Nebula.UnitTest/TestServiceHelper.cs new file mode 100644 index 0000000..f864f8f --- /dev/null +++ b/Nebula.UnitTest/TestServiceHelper.cs @@ -0,0 +1,46 @@ +using Microsoft.Extensions.DependencyInjection; +using Nebula.Shared; +using Nebula.Shared.Services; + +namespace Nebula.UnitTest; + +public static class TestServiceHelper +{ + public static SharedUnit GetSharedUnit(Action beforeServiceBuild) + { + var services = new ServiceCollection(); + beforeServiceBuild.Invoke(services); + services.AddServices(); + + var serviceProvider = services.BuildServiceProvider(); + return new SharedUnit(serviceProvider); + } + + public static void InitFileServiceTest() + { + var path = Path.Combine(Path.GetTempPath(), "tempThink"+Path.GetRandomFileName()); + Directory.CreateDirectory(path); + FileService.RootPath = path; + Console.WriteLine("Change root path for file api: " + FileService.RootPath); + } +} + +public sealed class LauncherUnit : SharedUnit +{ + public LauncherUnit(IServiceProvider serviceProvider) : base(serviceProvider) + { + } +} + + +public class SharedUnit +{ + public SharedUnit(IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + public IServiceProvider ServiceProvider { get; } + + public T GetService() where T : notnull => ServiceProvider.GetRequiredService(); +} \ No newline at end of file diff --git a/Nebula.sln b/Nebula.sln index 1f9ef03..fcbb8fa 100644 --- a/Nebula.sln +++ b/Nebula.sln @@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nebula.UpdateResolver", "Ne EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nebula.Packager", "Nebula.Packager\Nebula.Packager.csproj", "{D444A5F9-4549-467F-9398-97DD6DB1E263}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nebula.UnitTest", "Nebula.UnitTest\Nebula.UnitTest.csproj", "{735691F8-949C-4476-B9E4-5DF6FF8D3D0B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -48,5 +50,9 @@ Global {D444A5F9-4549-467F-9398-97DD6DB1E263}.Debug|Any CPU.Build.0 = Debug|Any CPU {D444A5F9-4549-467F-9398-97DD6DB1E263}.Release|Any CPU.ActiveCfg = Release|Any CPU {D444A5F9-4549-467F-9398-97DD6DB1E263}.Release|Any CPU.Build.0 = Release|Any CPU + {735691F8-949C-4476-B9E4-5DF6FF8D3D0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {735691F8-949C-4476-B9E4-5DF6FF8D3D0B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {735691F8-949C-4476-B9E4-5DF6FF8D3D0B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {735691F8-949C-4476-B9E4-5DF6FF8D3D0B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Nebula.sln.DotSettings.user b/Nebula.sln.DotSettings.user index f6713a1..dbd1490 100644 --- a/Nebula.sln.DotSettings.user +++ b/Nebula.sln.DotSettings.user @@ -12,6 +12,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -23,6 +24,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -41,6 +43,7 @@ ForceIncluded ForceIncluded ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded @@ -66,4 +69,23 @@ <Assembly Path="C:\Users\Cinka\.nuget\packages\prometheus-net\0.0.2\lib\net40\prometheus-net.dll" /> <Assembly Path="C:\Users\Cinka\.nuget\packages\microsoft.extensions.objectpool\7.0.0\lib\net7.0\Microsoft.Extensions.ObjectPool.dll" /> <Assembly Path="C:\Users\Cinka\.nuget\packages\netstandard.library\2.0.3\build\netstandard2.0\ref\netstandard.dll" /> -</AssemblyExplorer> \ No newline at end of file +</AssemblyExplorer> + 735691F8-949C-4476-B9E4-5DF6FF8D3D0B + db4927dd-2e12-48a7-9a84-2b7e3e31b9c8 + <SessionState ContinuousTestingMode="0" IsActive="True" Name="RestServiceTests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <TestAncestor> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.RestServiceTests</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.PopupMessageServiceTests.PopupMessageServiceTest</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.PopupMessageServiceTests.DisposeTest</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.FileServiceTests.CreateFileApi_CreatesCorrectPath</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.FileServiceTests.EnsureTempDir_CreatesDirectoryAndReturnsApi</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.FileServiceTests.OpenZip_ReturnsZipFileApi_WhenValid</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.FileServiceTests.RemoveAllFiles_DeletesAllFilesAndDirectories</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.FileServiceTests.OpenZip_ThrowsException_WhenFileApiFails</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.EngineServiceTests.GetVersionInfo_ReturnsCorrectBuildInfo</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.EngineServiceTests.TryGetVersionInfo_ReturnsTrue</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.ConfigurationServiceTests.WriteConVarTest</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.ConfigurationServiceTests.WriteArrayConvarTest</TestId> + <TestId>NUnit3x::735691F8-949C-4476-B9E4-5DF6FF8D3D0B::net9.0::Nebula.UnitTest.NebulaSharedTests.ConfigurationServiceTests</TestId> + </TestAncestor> +</SessionState> \ No newline at end of file