using System.Net;
using System.Net.Sockets;
using MijnBesluit.ServiceBeheer;
namespace MijnBesluit.SelfCheck;
///
/// Controleert wat het installatieschermpje doet met het poortnummer. Het aanmaken van de
/// service zelf kan alleen op Windows en met beheerdersrechten; dat valt hier buiten.
///
public static class ServiceChecks
{
public static void Register(Runner runner)
{
runner.Test("Poortnummer: onmogelijke waarden worden geweigerd", () =>
{
Assert.True(ServiceInstellingen.ControleerPoort(0) is not null, "0 is geen poort");
Assert.True(ServiceInstellingen.ControleerPoort(70000) is not null, "70000 bestaat niet");
Assert.True(ServiceInstellingen.ControleerPoort(-1) is not null, "negatief kan niet");
Assert.True(ServiceInstellingen.ControleerPoort(80)!.Contains("gereserveerd"),
"onder 1024 wordt uitgelegd waarom het niet mag");
Assert.True(ServiceInstellingen.ControleerPoort(5200) is null, "5200 mag gewoon");
Assert.True(ServiceInstellingen.ControleerPoort(65535) is null, "de hoogste poort mag");
});
runner.Test("Poortnummer opslaan laat de rest van appsettings.json met rust", () =>
{
var map = Path.Combine(Path.GetTempPath(), "mb-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(map);
var pad = Path.Combine(map, "appsettings.json");
File.WriteAllText(pad, """
{
"ConnectionStrings": { "MijnBesluit": "Server=localhost;Database=mijnbesluit" },
"Socket": { "Port": 5200, "CertificateFile": "D:\\cert.pfx" },
"Smtp": { "Host": "mail.example.nl" }
}
""");
var instellingen = new ServiceInstellingen(pad);
Assert.True(instellingen.LeesPoort() == 5200, "de bestaande poort wordt gelezen");
instellingen.SchrijfPoort(5300);
var opnieuw = new ServiceInstellingen(pad);
Assert.True(opnieuw.LeesPoort() == 5300, "de nieuwe poort staat erin");
var inhoud = File.ReadAllText(pad);
Assert.True(inhoud.Contains("Server=localhost"), "de connectiereeks staat er nog");
Assert.True(inhoud.Contains("cert.pfx"), "het certificaatpad staat er nog");
Assert.True(inhoud.Contains("mail.example.nl"), "de e-mailinstellingen staan er nog");
Assert.True(!File.Exists(pad + ".tmp"), "er blijft geen tijdelijk bestand achter");
Directory.Delete(map, true);
});
runner.Test("Poortnummer opslaan werkt ook zonder bestaand bestand", () =>
{
var map = Path.Combine(Path.GetTempPath(), "mb-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(map);
var pad = Path.Combine(map, "appsettings.json");
var instellingen = new ServiceInstellingen(pad);
Assert.True(instellingen.LeesPoort() == ServiceInstellingen.StandaardPoort,
"zonder bestand geldt de standaardpoort");
instellingen.SchrijfPoort(5400);
Assert.True(new ServiceInstellingen(pad).LeesPoort() == 5400, "en daarna staat het er netjes in");
Directory.Delete(map, true);
});
runner.Test("Een onmogelijke poort wordt niet weggeschreven", () =>
{
var map = Path.Combine(Path.GetTempPath(), "mb-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(map);
var pad = Path.Combine(map, "appsettings.json");
Assert.Throws(
() => new ServiceInstellingen(pad).SchrijfPoort(80),
"poort 80 wordt geweigerd");
Assert.True(!File.Exists(pad), "en er wordt niets opgeslagen");
Directory.Delete(map, true);
});
runner.Test("Een bezette poort wordt herkend", () =>
{
var bezet = new TcpListener(IPAddress.Any, 0);
bezet.Start();
var poort = ((IPEndPoint)bezet.LocalEndpoint).Port;
try
{
Assert.True(!ServiceInstellingen.PoortIsVrij(poort), "de bezette poort wordt als bezet gezien");
}
finally { bezet.Stop(); }
Assert.True(ServiceInstellingen.PoortIsVrij(poort), "en na afloop weer als vrij");
});
runner.Test("Een beschadigd appsettings.json wordt niet stilzwijgend gewist", () =>
{
var map = Path.Combine(Path.GetTempPath(), "mb-" + Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(map);
var pad = Path.Combine(map, "appsettings.json");
File.WriteAllText(pad, "{ dit is geen geldige json");
var instellingen = new ServiceInstellingen(pad);
Assert.True(instellingen.LeesPoort() == ServiceInstellingen.StandaardPoort,
"onleesbare inhoud levert de standaardpoort op in plaats van een fout");
Directory.Delete(map, true);
});
}
}