Add BulkSecretsTransformationAttribute for -Secrets parameter normalization
Publish to PowerShell Gallery / build (pull_request) Failing after 37s
Publish to PowerShell Gallery / release (pull_request) Has been skipped
Publish to PowerShell Gallery / publish (pull_request) Has been skipped

Normalizes Hashtable, OrderedDictionary, PSObject-wrapped, and typed generic dictionaries into IDictionary<string,string>[] before parameter binding, enabling native PowerShell @{...} and [ordered]@{...} literals against the strongly-typed -Secrets parameter on New-/Update-InfisicalSecret. Adds 8 transformation tests; 174/174 passing.
This commit is contained in:
GraceSolutions
2026-06-03 20:21:00 -04:00
parent 211fbcf34d
commit 2cbd5c2008
7 changed files with 221 additions and 3 deletions
@@ -1,4 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Management.Automation;
using PSInfisicalAPI.Cmdlets;
using PSInfisicalAPI.Errors;
using PSInfisicalAPI.Secrets;
using Xunit;
@@ -90,4 +94,116 @@ namespace PSInfisicalAPI.Tests
Assert.Empty(items);
}
}
public class BulkSecretsTransformationAttributeTests
{
private static IDictionary<string, string>[] Transform(object input)
{
BulkSecretsTransformationAttribute attribute = new BulkSecretsTransformationAttribute();
object result = attribute.Transform(null, input);
return (IDictionary<string, string>[])result;
}
[Fact]
public void Transform_Single_Hashtable_Wraps_Into_Array()
{
Hashtable input = new Hashtable { { "SecretName", "API_KEY" }, { "SecretValue", "abc" } };
IDictionary<string, string>[] result = Transform(input);
Assert.Single(result);
Assert.Equal("API_KEY", result[0]["SecretName"]);
Assert.Equal("abc", result[0]["SecretValue"]);
}
[Fact]
public void Transform_Hashtable_Array_Preserves_Order()
{
Hashtable a = new Hashtable { { "SecretName", "A" }, { "SecretValue", "1" } };
Hashtable b = new Hashtable { { "SecretName", "B" }, { "SecretValue", "2" } };
IDictionary<string, string>[] result = Transform(new object[] { a, b });
Assert.Equal(2, result.Length);
Assert.Equal("A", result[0]["SecretName"]);
Assert.Equal("B", result[1]["SecretName"]);
}
[Fact]
public void Transform_OrderedDictionary_Converts_To_StringString()
{
OrderedDictionary input = new OrderedDictionary();
input.Add("SecretName", "API_KEY");
input.Add("SkipMultilineEncoding", true);
IDictionary<string, string>[] result = Transform(input);
Assert.Single(result);
Assert.Equal("API_KEY", result[0]["SecretName"]);
Assert.Equal("true", result[0]["SkipMultilineEncoding"]);
}
[Fact]
public void Transform_Array_Values_Are_Joined_Comma_Separated()
{
Hashtable input = new Hashtable
{
{ "SecretName", "API_KEY" },
{ "TagIds", new[] { "tag-1", "tag-2" } }
};
IDictionary<string, string>[] result = Transform(input);
Assert.Equal("tag-1,tag-2", result[0]["TagIds"]);
}
[Fact]
public void Transform_Already_Typed_Array_Passes_Through()
{
IDictionary<string, string>[] input = new IDictionary<string, string>[]
{
new Dictionary<string, string> { { "SecretName", "A" }, { "SecretValue", "1" } }
};
IDictionary<string, string>[] result = Transform(input);
Assert.Same(input, result);
}
[Fact]
public void Transform_Null_Input_Returns_Null()
{
BulkSecretsTransformationAttribute attribute = new BulkSecretsTransformationAttribute();
Assert.Null(attribute.Transform(null, null));
}
[Fact]
public void Transform_Invalid_Element_Throws_ArgumentTransformationMetadataException()
{
BulkSecretsTransformationAttribute attribute = new BulkSecretsTransformationAttribute();
Assert.Throws<ArgumentTransformationMetadataException>(() =>
attribute.Transform(null, new object[] { "not-a-dictionary" }));
}
[Fact]
public void Transform_End_To_End_With_Converter_Produces_Bulk_Items()
{
Hashtable entry = new Hashtable
{
{ "SecretName", "API_KEY" },
{ "SecretValue", "abc" },
{ "TagIds", new[] { "tag-1", "tag-2" } },
{ "SkipMultilineEncoding", true }
};
IDictionary<string, string>[] transformed = Transform(new object[] { entry });
InfisicalBulkCreateSecretItem[] items = InfisicalBulkSecretConverter.ToCreateItems(transformed);
Assert.Single(items);
Assert.Equal("API_KEY", items[0].SecretName);
Assert.Equal("abc", items[0].SecretValue);
Assert.Equal(new[] { "tag-1", "tag-2" }, items[0].TagIds);
Assert.True(items[0].SkipMultilineEncoding);
}
}
}