|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using Aspire.Hosting.Publishing;
using Microsoft.Extensions.Configuration.UserSecrets;
using Microsoft.Extensions.SecretManager.Tools.Internal;
using Xunit;
namespace Aspire.Hosting.Tests;
public class UserSecretsParameterDefaultTests
{
private static readonly ConstructorInfo s_userSecretsIdAttrCtor = typeof(UserSecretsIdAttribute).GetConstructor([typeof(string)])!;
[Fact]
public void UserSecretsParameterDefault_GetDefaultValue_SavesValueInAppHostUserSecrets()
{
var userSecretsId = Guid.NewGuid().ToString("N");
ClearUsersSecrets(userSecretsId);
var testAssembly = AssemblyBuilder.DefineDynamicAssembly(
new("TestAssembly"), AssemblyBuilderAccess.RunAndCollect, [new CustomAttributeBuilder(s_userSecretsIdAttrCtor, [userSecretsId])]);
var paramDefault = new TestParameterDefault();
var userSecretDefault = new UserSecretsParameterDefault(testAssembly, "TestApplication.AppHost", "param1", paramDefault);
var initialValue = userSecretDefault.GetDefaultValue();
var userSecrets = GetUserSecrets(userSecretsId);
Assert.Equal(initialValue, userSecrets["Parameters:param1"]);
DeleteUserSecretsFile(userSecretsId);
}
[Fact]
public void UserSecretsParameterDefault_GetDefaultValue_DoesntThrowIfValueCantBeSaved()
{
// Do not set a user secrets id attribute on the assembly
var testAssembly = AssemblyBuilder.DefineDynamicAssembly(new("TestAssembly"), AssemblyBuilderAccess.RunAndCollect, []);
var paramDefault = new TestParameterDefault();
var userSecretDefault = new UserSecretsParameterDefault(testAssembly, "TestApplication.AppHost", "param1", paramDefault);
var initialValue = userSecretDefault.GetDefaultValue();
Assert.NotNull(initialValue);
}
[Fact]
public void UserSecretsParameterDefault_GetDefaultValue_DoesntThrowIfSecretsFileContainsComments()
{
var userSecretsId = Guid.NewGuid().ToString("N");
DeleteUserSecretsFile(userSecretsId);
var userSecretsPath = PathHelper.GetSecretsPathFromSecretsId(userSecretsId);
if (File.Exists(userSecretsPath))
{
File.Delete(userSecretsPath);
}
var secretsFileContents = """
{
// This is a comment in a JSON file
"SomeConfigKey": "some value"
}
"""{
// This is a comment in a JSON file
"SomeConfigKey": "some value"
}
""";
EnsureUserSecretsDirectory(userSecretsPath);
File.WriteAllText(userSecretsPath, secretsFileContents, Encoding.UTF8);
var testAssembly = AssemblyBuilder.DefineDynamicAssembly(
new("TestAssembly"), AssemblyBuilderAccess.RunAndCollect, [new CustomAttributeBuilder(s_userSecretsIdAttrCtor, [userSecretsId])]);
var paramDefault = new TestParameterDefault();
var userSecretDefault = new UserSecretsParameterDefault(testAssembly, "TestApplication.AppHost", "param1", paramDefault);
var _ = userSecretDefault.GetDefaultValue();
}
private static void EnsureUserSecretsDirectory(string secretsFilePath)
{
var directoryName = Path.GetDirectoryName(secretsFilePath);
if (!string.IsNullOrEmpty(directoryName) && !Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
}
private static Dictionary<string, string?> GetUserSecrets(string userSecretsId)
{
var secretsStore = new SecretsStore(userSecretsId);
return secretsStore.AsEnumerable().ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}
private static void ClearUsersSecrets(string userSecretsId)
{
var secretsStore = new SecretsStore(userSecretsId);
secretsStore.Clear();
secretsStore.Save();
}
private static void DeleteUserSecretsFile(string userSecretsId)
{
var userSecretsPath = PathHelper.GetSecretsPathFromSecretsId(userSecretsId);
if (File.Exists(userSecretsPath))
{
File.Delete(userSecretsPath);
}
}
private sealed class TestParameterDefault : ParameterDefault
{
public override string GetDefaultValue()
{
return Guid.NewGuid().ToString("N");
}
public override void WriteToManifest(ManifestPublishingContext context)
{
throw new NotImplementedException();
}
}
}
|