using SpdUp.Models;
using SpdUp.Services;
namespace SpdUp.Tests;
///
/// Tests for services that can be tested without admin/system access.
///
public class ServiceTests
{
// ── NetworkService.PingAsync ──────────────────────────────
[Fact]
public async Task PingAsync_Localhost_ReturnsPositive()
{
var ms = await NetworkService.PingAsync("127.0.0.1", 2000);
Assert.True(ms >= 0, $"Ping to localhost should succeed, got {ms}");
}
[Fact]
public async Task PingAsync_InvalidHost_ReturnsNegative()
{
var ms = await NetworkService.PingAsync("0.0.0.0", 500);
// 0.0.0.0 typically fails or returns -1
// On some machines it may succeed — accept either
Assert.True(ms >= -1);
}
// ── GameDetectionService ─────────────────────────────────
[Fact]
public void GameDetectionService_InitialState_NoGameDetected()
{
var settings = new AppSettings();
using var gds = new GameDetectionService(settings);
Assert.Null(gds.CurrentGameProcess);
}
[Fact]
public void GameDetectionService_AddGameProcess()
{
var settings = new AppSettings();
using var gds = new GameDetectionService(settings);
gds.AddGameProcess("TestGame");
// AddGameProcess should not throw
}
[Fact]
public void GameDetectionService_StartAndStop_DoesNotThrow()
{
var settings = new AppSettings();
using var gds = new GameDetectionService(settings);
gds.Start(60000); // very long interval so it doesn't actually poll during test
gds.Stop();
}
[Fact]
public void GameDetectionService_Dispose_DoesNotThrow()
{
var settings = new AppSettings();
var gds = new GameDetectionService(settings);
gds.Dispose();
// Double dispose should not throw
gds.Dispose();
}
// ── OptimizationService ──────────────────────────────────
[Fact]
public void OptimizationService_InitialState()
{
var settings = new AppSettings();
var svc = new OptimizationService(settings);
Assert.False(svc.IsBoosted);
Assert.Null(svc.BoostedProcessName);
}
[Fact]
public void OptimizationService_Events_CanSubscribe()
{
var settings = new AppSettings();
var svc = new OptimizationService(settings);
bool activated = false;
bool deactivated = false;
svc.BoostActivated += _ => activated = true;
svc.BoostDeactivated += () => deactivated = true;
// Just verify event subscription doesn't throw
Assert.False(activated);
Assert.False(deactivated);
}
// ── ServiceManagementService ─────────────────────────────
[Fact]
public void KnownNonCriticalServices_ContainsExpectedEntries()
{
var known = ServiceManagementService.KnownNonCriticalServices;
Assert.True(known.ContainsKey("SysMain"));
Assert.True(known.ContainsKey("WSearch"));
Assert.True(known.ContainsKey("DiagTrack"));
Assert.True(known.ContainsKey("XblAuthManager"));
Assert.True(known.Count >= 10, "Should have at least 10 known services");
}
[Fact]
public void GetServiceList_NonExistentService_ReturnsNotFound()
{
var entries = ServiceManagementService.GetServiceList(new[] { "SpdUpFakeService12345" });
Assert.Single(entries);
Assert.Equal("NotFound", entries[0].Status);
Assert.Equal("SpdUpFakeService12345", entries[0].ServiceName);
}
[Fact]
public void GetServiceList_EmptyInput_ReturnsEmpty()
{
var entries = ServiceManagementService.GetServiceList(Array.Empty());
Assert.Empty(entries);
}
// ── ShaderCleanResult ────────────────────────────────────
[Fact]
public void ShaderCleanResult_MBFreed_LargeValue()
{
var r = new ShaderCleanResult(100, 1_073_741_824); // 1 GB
Assert.Equal(1024.0, r.MBFreed, 0.1);
}
// ── RamOptimizationService ───────────────────────────────
[Fact]
public void RamOptimizationService_GetMemoryStatus_ReturnsValidValues()
{
var (totalMB, availMB, loadPercent) = RamOptimizationService.GetMemoryStatus();
Assert.True(totalMB > 0, "Total RAM should be > 0");
Assert.True(availMB > 0, "Available RAM should be > 0");
Assert.True(availMB <= totalMB, "Available should be <= total");
Assert.InRange(loadPercent, (uint)1, (uint)100);
}
}