|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Sockets;
namespace Aspire.Hosting.Tests;
public class ConditionalReferenceExpressionTests
{
[Fact]
public async Task GetValueAsync_ReturnsTrueValue_WhenConditionIsTrue()
{
var condition = new TestValueProvider(bool.TrueString);
var whenTrue = ReferenceExpression.Create($",ssl=true");
var whenFalse = ReferenceExpression.Empty;
var expr = ReferenceExpression.CreateConditional(condition, bool.TrueString, whenTrue, whenFalse);
var value = await expr.GetValueAsync(default);
Assert.Equal(",ssl=true", value);
}
[Fact]
public async Task GetValueAsync_ReturnsFalseValue_WhenConditionIsFalse()
{
var condition = new TestValueProvider(bool.FalseString);
var whenTrue = ReferenceExpression.Create($",ssl=true");
var whenFalse = ReferenceExpression.Empty;
var expr = ReferenceExpression.CreateConditional(condition, bool.TrueString, whenTrue, whenFalse);
var value = await expr.GetValueAsync(default);
Assert.Null(value);
}
[Fact]
public void ValueExpression_ReturnsManifestParameterReference()
{
var condition = new TestValueProvider(bool.TrueString);
var whenTrue = ReferenceExpression.Create($",ssl=true");
var whenFalse = ReferenceExpression.Empty;
var expr = ReferenceExpression.CreateConditional(condition, bool.TrueString, whenTrue, whenFalse);
Assert.StartsWith("{cond-", expr.ValueExpression);
Assert.EndsWith(".connectionString}", expr.ValueExpression);
}
[Fact]
public async Task ConditionalReferenceExpression_WorksInReferenceExpressionBuilder()
{
var condition = new TestValueProvider(bool.FalseString);
var whenTrue = ReferenceExpression.Create($",ssl=true");
var whenFalse = ReferenceExpression.Empty;
var conditional = ReferenceExpression.CreateConditional(condition, bool.TrueString, whenTrue, whenFalse);
var builder = new ReferenceExpressionBuilder();
builder.AppendLiteral("localhost:6379");
builder.Append($"{conditional}");
var expression = builder.Build();
// Before enabling: runtime value does not include TLS
var valueBefore = await expression.GetValueAsync(new(), default);
Assert.Equal("localhost:6379", valueBefore);
// After enabling: runtime value includes TLS dynamically
condition.Value = bool.TrueString;
var valueAfter = await expression.GetValueAsync(new(), default);
Assert.Equal("localhost:6379,ssl=true", valueAfter);
}
[Fact]
public void References_IncludesConditionAndBranchReferences()
{
var resource = new TestResourceWithEndpoints("test");
var annotation = new EndpointAnnotation(ProtocolType.Tcp, uriScheme: "http", name: "http");
resource.Annotations.Add(annotation);
var endpointRef = new EndpointReference(resource, annotation);
var condition = endpointRef.Property(EndpointProperty.TlsEnabled);
var whenTrue = ReferenceExpression.Create($",ssl=true");
var whenFalse = ReferenceExpression.Empty;
var expr = ReferenceExpression.CreateConditional(condition, bool.TrueString, whenTrue, whenFalse);
var references = ((IValueWithReferences)expr).References.ToList();
Assert.Contains(endpointRef, references);
}
[Fact]
public void Name_IsAutoGeneratedFromCondition()
{
var expr = ReferenceExpression.CreateConditional(new TestValueProvider(bool.TrueString), bool.TrueString, ReferenceExpression.Empty, ReferenceExpression.Empty);
Assert.StartsWith("cond-", expr.Name);
}
private sealed class TestResourceWithEndpoints(string name) : Resource(name), IResourceWithEndpoints
{
}
private sealed class TestValueProvider(string value) : IValueProvider, IManifestExpressionProvider
{
public string Value { get; set; } = value;
public string ValueExpression => "test-condition";
public ValueTask<string?> GetValueAsync(CancellationToken cancellationToken = default)
{
return new ValueTask<string?>(Value);
}
public ValueTask<string?> GetValueAsync(ValueProviderContext context, CancellationToken cancellationToken = default)
{
return new ValueTask<string?>(Value);
}
}
}
public class EndpointPropertyTlsEnabledTests
{
[Fact]
public async Task TlsEnabled_ReturnsFalseString_WhenTlsNotEnabled()
{
var resource = new TestResourceWithEndpoints("test");
var annotation = new EndpointAnnotation(ProtocolType.Tcp, uriScheme: "http", name: "tcp");
resource.Annotations.Add(annotation);
var endpointRef = new EndpointReference(resource, annotation);
var tlsExpr = endpointRef.Property(EndpointProperty.TlsEnabled);
var value = await tlsExpr.GetValueAsync();
Assert.Equal(bool.FalseString, value);
}
[Fact]
public async Task TlsEnabled_ReturnsTrueString_WhenTlsEnabled()
{
var resource = new TestResourceWithEndpoints("test");
var annotation = new EndpointAnnotation(ProtocolType.Tcp, uriScheme: "https", name: "tcp")
{
TlsEnabled = true
};
resource.Annotations.Add(annotation);
var endpointRef = new EndpointReference(resource, annotation);
var tlsExpr = endpointRef.Property(EndpointProperty.TlsEnabled);
var value = await tlsExpr.GetValueAsync();
Assert.Equal(bool.TrueString, value);
}
[Fact]
public void ValueExpression_ReturnsEndpointTlsExpression()
{
var resource = new TestResourceWithEndpoints("myresource");
var annotation = new EndpointAnnotation(ProtocolType.Tcp, uriScheme: "http", name: "tcp");
resource.Annotations.Add(annotation);
var endpointRef = new EndpointReference(resource, annotation);
var tlsExpr = endpointRef.Property(EndpointProperty.TlsEnabled);
Assert.Equal("{myresource.bindings.tcp.tlsEnabled}", tlsExpr.ValueExpression);
}
[Fact]
public async Task TlsEnabled_ResolvesLazilyFromCurrentState()
{
var resource = new TestResourceWithEndpoints("test");
var annotation = new EndpointAnnotation(ProtocolType.Tcp, uriScheme: "http", name: "tcp");
resource.Annotations.Add(annotation);
var endpointRef = new EndpointReference(resource, annotation);
var tlsExpr = endpointRef.Property(EndpointProperty.TlsEnabled);
Assert.Equal(bool.FalseString, await tlsExpr.GetValueAsync());
annotation.TlsEnabled = true;
Assert.Equal(bool.TrueString, await tlsExpr.GetValueAsync());
}
private sealed class TestResourceWithEndpoints(string name) : Resource(name), IResourceWithEndpoints
{
}
}
|