mirror of https://github.com/dapr/dotnet-sdk.git
186 lines
6.6 KiB
C#
186 lines
6.6 KiB
C#
// ------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT License.
|
|
// ------------------------------------------------------------
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Xunit;
|
|
|
|
#nullable enable
|
|
|
|
namespace Dapr.Client
|
|
{
|
|
public class InvocationHandlerTests
|
|
{
|
|
[Fact]
|
|
public void DaprEndpoint_InvalidScheme()
|
|
{
|
|
var handler = new InvocationHandler();
|
|
var ex = Assert.Throws<ArgumentException>(() =>
|
|
{
|
|
handler.DaprEndpoint = "ftp://localhost:3500";
|
|
});
|
|
|
|
Assert.Contains("The URI scheme of the Dapr endpoint must be http or https.", ex.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public void DaprEndpoint_InvalidUri()
|
|
{
|
|
var handler = new InvocationHandler();
|
|
Assert.Throws<UriFormatException>(() =>
|
|
{
|
|
handler.DaprEndpoint = "";
|
|
});
|
|
|
|
// Exception message comes from the runtime, not validating it here
|
|
}
|
|
|
|
[Fact]
|
|
public void TryRewriteUri_FailsForNullUri()
|
|
{
|
|
var handler = new InvocationHandler();
|
|
Assert.False(handler.TryRewriteUri(null!, out var rewritten));
|
|
Assert.Null(rewritten);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryRewriteUri_FailsForBadScheme()
|
|
{
|
|
var uri = new Uri("ftp://test", UriKind.Absolute);
|
|
|
|
var handler = new InvocationHandler();
|
|
Assert.False(handler.TryRewriteUri(uri, out var rewritten));
|
|
Assert.Null(rewritten);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryRewriteUri_FailsForRelativeUris()
|
|
{
|
|
var uri = new Uri("test", UriKind.Relative);
|
|
|
|
var handler = new InvocationHandler();
|
|
Assert.False(handler.TryRewriteUri(uri, out var rewritten));
|
|
Assert.Null(rewritten);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("http://bank", "https://some.host:3499/v1.0/invoke/bank/method/")]
|
|
[InlineData("http://bank:3939", "https://some.host:3499/v1.0/invoke/bank/method/")]
|
|
[InlineData("http://app-id.with.dots", "https://some.host:3499/v1.0/invoke/app-id.with.dots/method/")]
|
|
[InlineData("http://bank:3939/", "https://some.host:3499/v1.0/invoke/bank/method/")]
|
|
[InlineData("http://bank:3939/some/path", "https://some.host:3499/v1.0/invoke/bank/method/some/path")]
|
|
[InlineData("http://bank:3939/some/path?q=test&p=another#fragment", "https://some.host:3499/v1.0/invoke/bank/method/some/path?q=test&p=another#fragment")]
|
|
public void TryRewriteUri_RewritesUriToDaprInvoke(string uri, string expected)
|
|
{
|
|
var handler = new InvocationHandler()
|
|
{
|
|
DaprEndpoint = "https://some.host:3499",
|
|
};
|
|
|
|
Assert.True(handler.TryRewriteUri(new Uri(uri), out var rewritten));
|
|
Assert.Equal(expected, rewritten!.OriginalString);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SendAsync_InvalidUri_ThrowsException()
|
|
{
|
|
var handler = new InvocationHandler();
|
|
var ex = await Assert.ThrowsAsync<ArgumentException>(async () =>
|
|
{
|
|
await CallSendAsync(handler, new HttpRequestMessage(){ }); // No URI set
|
|
});
|
|
|
|
Assert.Contains("The request URI '' is not a valid Dapr service invocation destination.", ex.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SendAsync_RewritesUri()
|
|
{
|
|
var uri = "http://bank/accounts/17?";
|
|
|
|
var capture = new CaptureHandler();
|
|
var handler = new InvocationHandler()
|
|
{
|
|
InnerHandler = capture,
|
|
|
|
DaprEndpoint = "https://localhost:5000",
|
|
DaprApiToken = null,
|
|
};
|
|
|
|
var request = new HttpRequestMessage(HttpMethod.Post, uri);
|
|
var response = await CallSendAsync(handler, request);
|
|
|
|
Assert.Equal("https://localhost:5000/v1.0/invoke/bank/method/accounts/17?", capture.RequestUri?.OriginalString);
|
|
Assert.Null(capture.DaprApiToken);
|
|
|
|
Assert.Equal(uri, request.RequestUri?.OriginalString);
|
|
Assert.False(request.Headers.TryGetValues("dapr-api-token", out _));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SendAsync_RewritesUri_AndAddsApiToken()
|
|
{
|
|
var uri = "http://bank/accounts/17?";
|
|
|
|
var capture = new CaptureHandler();
|
|
var handler = new InvocationHandler()
|
|
{
|
|
InnerHandler = capture,
|
|
|
|
DaprEndpoint = "https://localhost:5000",
|
|
DaprApiToken = "super-duper-secure",
|
|
};
|
|
|
|
var request = new HttpRequestMessage(HttpMethod.Post, uri);
|
|
var response = await CallSendAsync(handler, request);
|
|
|
|
Assert.Equal("https://localhost:5000/v1.0/invoke/bank/method/accounts/17?", capture.RequestUri?.OriginalString);
|
|
Assert.Equal("super-duper-secure", capture.DaprApiToken);
|
|
|
|
Assert.Equal(uri, request.RequestUri?.OriginalString);
|
|
Assert.False(request.Headers.TryGetValues("dapr-api-token", out _));
|
|
}
|
|
|
|
private async Task<HttpResponseMessage> CallSendAsync(InvocationHandler handler, HttpRequestMessage message, CancellationToken cancellationToken = default)
|
|
{
|
|
// SendAsync is protected, can't call it directly.
|
|
var method = handler.GetType().GetMethod("SendAsync", BindingFlags.Instance | BindingFlags.NonPublic);
|
|
Assert.NotNull(method);
|
|
|
|
try
|
|
{
|
|
return await (Task<HttpResponseMessage>)method!.Invoke(handler, new object[]{ message, cancellationToken, })!;
|
|
}
|
|
catch (TargetInvocationException tie) // reflection always adds an extra layer of exceptions.
|
|
{
|
|
throw tie.InnerException!;
|
|
}
|
|
}
|
|
|
|
private class CaptureHandler : HttpMessageHandler
|
|
{
|
|
public Uri? RequestUri { get; private set; }
|
|
|
|
public string? DaprApiToken { get; private set; }
|
|
|
|
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
|
{
|
|
RequestUri = request.RequestUri;
|
|
if (request.Headers.TryGetValues("dapr-api-token", out var tokens))
|
|
{
|
|
DaprApiToken = tokens.SingleOrDefault();
|
|
}
|
|
|
|
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK));
|
|
}
|
|
}
|
|
}
|
|
}
|