From ad19b14d1a6950505f637ebe62bc9bd36704fc9f Mon Sep 17 00:00:00 2001 From: "goodolclint-claude[bot]" <323206664+goodolclint-claude[bot]@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:21:16 +0000 Subject: [PATCH] test: pin CloneVm/CloneContainer storage and newid form-body behavior Offline xUnit coverage per ADR 0021: storage present in the clone form body when supplied, absent when omitted, and newid forwarded verbatim (never coerced to 0) by the service layer. --- .../Services/ContainerServiceTests.cs | 52 +++++++++++++++++++ .../Services/VmServiceTests.cs | 51 ++++++++++++++++++ 2 files changed, 103 insertions(+) diff --git a/tests/PSProxmoxVE.Core.Tests/Services/ContainerServiceTests.cs b/tests/PSProxmoxVE.Core.Tests/Services/ContainerServiceTests.cs index 7f6b176..1e99458 100644 --- a/tests/PSProxmoxVE.Core.Tests/Services/ContainerServiceTests.cs +++ b/tests/PSProxmoxVE.Core.Tests/Services/ContainerServiceTests.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Moq; using PSProxmoxVE.Core.Authentication; using PSProxmoxVE.Core.Client; @@ -61,5 +62,56 @@ namespace PSProxmoxVE.Core.Tests.Services Assert.Equal($"nodes/{TestNode}/lxc/{TestVmId}?purge=1&force=1", resource); } + + [Fact] + public void CloneContainer_WithStorage_IncludesStorageInFormBody() + { + Dictionary? captured = null; + var mockClient = new Mock(); + mockClient + .Setup(c => c.PostAsync(It.IsAny(), It.IsAny>())) + .Callback>((_, data) => captured = data) + .ReturnsAsync("{\"data\":\"UPID:pve1:00001234:00005678:6A970AAB:vzclone:100:root@pam:\"}"); + + var service = new ContainerService(mockClient.Object); + service.CloneContainer(CreateSession(), TestNode, TestVmId, 200, storage: "local-zfs"); + + Assert.NotNull(captured); + Assert.Equal("local-zfs", captured!["storage"]); + } + + [Fact] + public void CloneContainer_WithoutStorage_OmitsStorageFromFormBody() + { + Dictionary? captured = null; + var mockClient = new Mock(); + mockClient + .Setup(c => c.PostAsync(It.IsAny(), It.IsAny>())) + .Callback>((_, data) => captured = data) + .ReturnsAsync("{\"data\":\"UPID:pve1:00001234:00005678:6A970AAB:vzclone:100:root@pam:\"}"); + + var service = new ContainerService(mockClient.Object); + service.CloneContainer(CreateSession(), TestNode, TestVmId, 200); + + Assert.NotNull(captured); + Assert.False(captured!.ContainsKey("storage")); + } + + [Fact] + public void CloneContainer_SendsAllocatedNewidNeverZero() + { + Dictionary? captured = null; + var mockClient = new Mock(); + mockClient + .Setup(c => c.PostAsync(It.IsAny(), It.IsAny>())) + .Callback>((_, data) => captured = data) + .ReturnsAsync("{\"data\":\"UPID:pve1:00001234:00005678:6A970AAB:vzclone:100:root@pam:\"}"); + + var service = new ContainerService(mockClient.Object); + service.CloneContainer(CreateSession(), TestNode, TestVmId, 305); + + Assert.NotNull(captured); + Assert.Equal("305", captured!["newid"]); + } } } diff --git a/tests/PSProxmoxVE.Core.Tests/Services/VmServiceTests.cs b/tests/PSProxmoxVE.Core.Tests/Services/VmServiceTests.cs index 2c0147d..be05cbb 100644 --- a/tests/PSProxmoxVE.Core.Tests/Services/VmServiceTests.cs +++ b/tests/PSProxmoxVE.Core.Tests/Services/VmServiceTests.cs @@ -217,5 +217,56 @@ namespace PSProxmoxVE.Core.Tests.Services Assert.Contains("skiplock=1", resource!); } + [Fact] + public void CloneVm_WithStorage_IncludesStorageInFormBody() + { + Dictionary? captured = null; + var mockClient = new Mock(); + mockClient + .Setup(c => c.PostAsync(It.IsAny(), It.IsAny>())) + .Callback>((_, data) => captured = data) + .ReturnsAsync("{\"data\":\"UPID:pve1:00001234:00005678:6A970AAB:qmclone:100:root@pam:\"}"); + + var service = new VmService(mockClient.Object); + service.CloneVm(CreateSession(), TestNode, TestVmId, 200, storage: "local-zfs"); + + Assert.NotNull(captured); + Assert.Equal("local-zfs", captured!["storage"]); + } + + [Fact] + public void CloneVm_WithoutStorage_OmitsStorageFromFormBody() + { + Dictionary? captured = null; + var mockClient = new Mock(); + mockClient + .Setup(c => c.PostAsync(It.IsAny(), It.IsAny>())) + .Callback>((_, data) => captured = data) + .ReturnsAsync("{\"data\":\"UPID:pve1:00001234:00005678:6A970AAB:qmclone:100:root@pam:\"}"); + + var service = new VmService(mockClient.Object); + service.CloneVm(CreateSession(), TestNode, TestVmId, 200); + + Assert.NotNull(captured); + Assert.False(captured!.ContainsKey("storage")); + } + + [Fact] + public void CloneVm_SendsAllocatedNewidNeverZero() + { + Dictionary? captured = null; + var mockClient = new Mock(); + mockClient + .Setup(c => c.PostAsync(It.IsAny(), It.IsAny>())) + .Callback>((_, data) => captured = data) + .ReturnsAsync("{\"data\":\"UPID:pve1:00001234:00005678:6A970AAB:qmclone:100:root@pam:\"}"); + + var service = new VmService(mockClient.Object); + service.CloneVm(CreateSession(), TestNode, TestVmId, 305); + + Assert.NotNull(captured); + Assert.Equal("305", captured!["newid"]); + } + } }