Sfoglia il codice sorgente

Added Switch usecase tests

Tim Jones 2 mesi fa
parent
commit
a2630a6c93

+ 50 - 0
Tests/Hardware/Switches/AddSwitchUseCaseTests.cs

@@ -0,0 +1,50 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Hardware;
+using RackPeek.Domain.Resources.Hardware.Models;
+using RackPeek.Domain.Resources.Hardware.Switchs;
+
+namespace Tests.Hardware.Switches;
+
+public class AddSwitchUseCaseTests
+{
+    [Fact]
+    public async Task ExecuteAsync_Adds_new_switch_when_not_exists()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns((RackPeek.Domain.Resources.Hardware.Models.Hardware?)null);
+
+        var sut = new AddSwitchUseCase(repo);
+
+        // Act
+        await sut.ExecuteAsync(
+            name: "sw01"
+        );
+
+        // Assert
+        await repo.Received(1).AddAsync(Arg.Is<Switch>(s =>
+            s.Name == "sw01"
+        ));
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Throws_if_switch_already_exists()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns(new Switch { Name = "sw01" });
+
+        var sut = new AddSwitchUseCase(repo);
+
+        // Act
+        var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
+            await sut.ExecuteAsync(
+                name: "sw01"
+            )
+        );
+
+        // Assert
+        Assert.Equal("Switch 'sw01' already exists.", ex.Message);
+        await repo.DidNotReceive().AddAsync(Arg.Any<Switch>());
+    }
+}

+ 48 - 0
Tests/Hardware/Switches/DeleteSwitchUseCaseTests.cs

@@ -0,0 +1,48 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Hardware;
+using RackPeek.Domain.Resources.Hardware.Models;
+using RackPeek.Domain.Resources.Hardware.Switchs;
+
+namespace Tests.Hardware.Switches;
+
+public class DeleteSwitchUseCaseTests
+{
+    [Fact]
+    public async Task ExecuteAsync_Deletes_switch_when_exists()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns(new Switch { Name = "sw01" });
+
+        var sut = new DeleteSwitchUseCase(repo);
+
+        // Act
+        await sut.ExecuteAsync(
+            name: "sw01"
+        );
+
+        // Assert
+        await repo.Received(1).DeleteAsync("sw01");
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Throws_if_switch_not_found()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns((RackPeek.Domain.Resources.Hardware.Models.Hardware?)null);
+
+        var sut = new DeleteSwitchUseCase(repo);
+
+        // Act
+        var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
+            await sut.ExecuteAsync(
+                name: "sw01"
+            )
+        );
+
+        // Assert
+        Assert.Equal("Switch 'sw01' not found.", ex.Message);
+        await repo.DidNotReceive().DeleteAsync(Arg.Any<string>());
+    }
+}

+ 94 - 0
Tests/Hardware/Switches/DescribeSwitchUseCaseTests.cs

@@ -0,0 +1,94 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Hardware;
+using RackPeek.Domain.Resources.Hardware.Models;
+using RackPeek.Domain.Resources.Hardware.Switchs;
+
+namespace Tests.Hardware.Switches;
+
+public class DescribeSwitchUseCaseTests
+{
+    [Fact]
+    public async Task ExecuteAsync_Returns_null_when_switch_not_found()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns((RackPeek.Domain.Resources.Hardware.Models.Hardware?)null);
+
+        var sut = new DescribeSwitchUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync("sw01");
+
+        // Assert
+        Assert.Null(result);
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Returns_defaults_when_switch_has_no_ports()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns(new Switch
+        {
+            Name = "sw01",
+            Model = "TestModel",
+            Managed = true,
+            Poe = false,
+            Ports = null
+        });
+
+        var sut = new DescribeSwitchUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync("sw01");
+
+        // Assert
+        Assert.NotNull(result);
+        Assert.Equal("sw01", result.Name);
+        Assert.Equal("TestModel", result.Model);
+        Assert.True(result.Managed);
+        Assert.False(result.Poe);
+        Assert.Equal(0, result.TotalPorts);
+        Assert.Equal(0, result.TotalSpeedGb);
+        Assert.Equal(string.Empty, result.PortSummary);
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Calculates_totals_and_summary_from_ports()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns(new Switch
+        {
+            Name = "sw01",
+            Model = "CoreSwitch",
+            Managed = true,
+            Poe = true,
+            Ports = new List<Port>
+            {
+                new() { Type = "RJ45", Speed = 1, Count = 24 },
+                new() { Type = "SFP+", Speed = 10, Count = 4 }
+            }
+        });
+
+        var sut = new DescribeSwitchUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync("sw01");
+
+        // Assert
+        Assert.NotNull(result);
+        Assert.Equal("sw01", result.Name);
+        Assert.Equal("CoreSwitch", result.Model);
+        Assert.True(result.Managed);
+        Assert.True(result.Poe);
+
+        Assert.Equal(28, result.TotalPorts);          // 24 + 4
+        Assert.Equal(64, result.TotalSpeedGb);        // (24 * 1) + (4 * 10)
+
+        Assert.Equal(
+            "RJ45: 24 ports (24 Gb total), SFP+: 4 ports (40 Gb total)",
+            result.PortSummary
+        );
+    }
+}

+ 43 - 0
Tests/Hardware/Switches/GetSwitchUseCaseTests.cs

@@ -0,0 +1,43 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Hardware;
+using RackPeek.Domain.Resources.Hardware.Models;
+using RackPeek.Domain.Resources.Hardware.Switchs;
+
+namespace Tests.Hardware.Switches;
+
+public class GetSwitchUseCaseTests
+{
+    [Fact]
+    public async Task ExecuteAsync_Returns_switch_when_it_exists()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        var sw = new Switch { Name = "sw01" };
+        repo.GetByNameAsync("sw01").Returns(sw);
+
+        var sut = new GetSwitchUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync("sw01");
+
+        // Assert
+        Assert.NotNull(result);
+        Assert.Same(sw, result);
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Returns_null_when_hardware_is_not_switch()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("node01").Returns(new Server { Name = "node01" });
+
+        var sut = new GetSwitchUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync("node01");
+
+        // Assert
+        Assert.Null(result);
+    }
+}

+ 50 - 0
Tests/Hardware/Switches/GetSwitchesUseCaseTests.cs

@@ -0,0 +1,50 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Hardware;
+using RackPeek.Domain.Resources.Hardware.Models;
+using RackPeek.Domain.Resources.Hardware.Switchs;
+
+namespace Tests.Hardware.Switches;
+
+public class GetSwitchesUseCaseTests
+{
+    [Fact]
+    public async Task ExecuteAsync_Returns_only_switches()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetAllAsync().Returns([
+            new Switch { Name = "sw01" },
+            new Server { Name = "node01" },
+            new Switch { Name = "sw02" }
+        ]);
+
+        var sut = new GetSwitchesUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync();
+
+        // Assert
+        Assert.Equal(2, result.Count);
+        Assert.All(result, s => Assert.IsType<Switch>(s));
+        Assert.Contains(result, s => s.Name == "sw01");
+        Assert.Contains(result, s => s.Name == "sw02");
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Returns_empty_list_when_no_switches_exist()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetAllAsync().Returns([
+            new Server { Name = "node01" }
+        ]);
+
+        var sut = new GetSwitchesUseCase(repo);
+
+        // Act
+        var result = await sut.ExecuteAsync();
+
+        // Assert
+        Assert.Empty(result);
+    }
+}

+ 90 - 0
Tests/Hardware/Switches/UpdateSwitchUseCaseTests.cs

@@ -0,0 +1,90 @@
+using NSubstitute;
+using RackPeek.Domain.Resources.Hardware;
+using RackPeek.Domain.Resources.Hardware.Models;
+using RackPeek.Domain.Resources.Hardware.Switchs;
+
+namespace Tests.Hardware.Switches;
+
+public class UpdateSwitchUseCaseTests
+{
+    [Fact]
+    public async Task ExecuteAsync_Throws_when_switch_not_found()
+    {
+        // Arrange
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns((RackPeek.Domain.Resources.Hardware.Models.Hardware?)null);
+
+        var sut = new UpdateSwitchUseCase(repo);
+
+        // Act
+        var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () =>
+            await sut.ExecuteAsync("sw01")
+        );
+
+        // Assert
+        Assert.Equal("Switch 'sw01' not found.", ex.Message);
+        await repo.DidNotReceive().UpdateAsync(Arg.Any<Switch>());
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Updates_only_provided_fields()
+    {
+        // Arrange
+        var existing = new Switch
+        {
+            Name = "sw01",
+            Model = "OldModel",
+            Managed = false,
+            Poe = false
+        };
+
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns(existing);
+
+        var sut = new UpdateSwitchUseCase(repo);
+
+        // Act
+        await sut.ExecuteAsync(
+            name: "sw01",
+            model: "NewModel",
+            poe: true
+        );
+
+        // Assert
+        await repo.Received(1).UpdateAsync(Arg.Is<Switch>(s =>
+            s.Name == "sw01" &&
+            s.Model == "NewModel" &&   // updated
+            s.Managed == false &&      // unchanged
+            s.Poe == true              // updated
+        ));
+    }
+
+    [Fact]
+    public async Task ExecuteAsync_Does_not_update_model_when_empty_or_whitespace()
+    {
+        // Arrange
+        var existing = new Switch
+        {
+            Name = "sw01",
+            Model = "KeepMe",
+            Managed = true,
+            Poe = true
+        };
+
+        var repo = Substitute.For<IHardwareRepository>();
+        repo.GetByNameAsync("sw01").Returns(existing);
+
+        var sut = new UpdateSwitchUseCase(repo);
+
+        // Act
+        await sut.ExecuteAsync(
+            name: "sw01",
+            model: "   "
+        );
+
+        // Assert
+        await repo.Received(1).UpdateAsync(Arg.Is<Switch>(s =>
+            s.Model == "KeepMe"
+        ));
+    }
+}

+ 0 - 4
Tests/Tests.csproj

@@ -23,8 +23,4 @@
       <ProjectReference Include="..\RackPeek\RackPeek.csproj" />
     </ItemGroup>
 
-    <ItemGroup>
-      <Folder Include="Hardware\Switches\" />
-    </ItemGroup>
-
 </Project>