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.
This commit is contained in:
goodolclint-claude[bot]
2026-09-02 19:21:16 +00:00
committed by GitHub
parent 21209fc7ad
commit ad19b14d1a
2 changed files with 103 additions and 0 deletions
@@ -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<string, string>? captured = null;
var mockClient = new Mock<IPveHttpClient>();
mockClient
.Setup(c => c.PostAsync(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
.Callback<string, Dictionary<string, string>>((_, 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<string, string>? captured = null;
var mockClient = new Mock<IPveHttpClient>();
mockClient
.Setup(c => c.PostAsync(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
.Callback<string, Dictionary<string, string>>((_, 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<string, string>? captured = null;
var mockClient = new Mock<IPveHttpClient>();
mockClient
.Setup(c => c.PostAsync(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
.Callback<string, Dictionary<string, string>>((_, 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"]);
}
}
}
@@ -217,5 +217,56 @@ namespace PSProxmoxVE.Core.Tests.Services
Assert.Contains("skiplock=1", resource!);
}
[Fact]
public void CloneVm_WithStorage_IncludesStorageInFormBody()
{
Dictionary<string, string>? captured = null;
var mockClient = new Mock<IPveHttpClient>();
mockClient
.Setup(c => c.PostAsync(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
.Callback<string, Dictionary<string, string>>((_, 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<string, string>? captured = null;
var mockClient = new Mock<IPveHttpClient>();
mockClient
.Setup(c => c.PostAsync(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
.Callback<string, Dictionary<string, string>>((_, 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<string, string>? captured = null;
var mockClient = new Mock<IPveHttpClient>();
mockClient
.Setup(c => c.PostAsync(It.IsAny<string>(), It.IsAny<Dictionary<string, string>>()))
.Callback<string, Dictionary<string, string>>((_, 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"]);
}
}
}