| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- // 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.Http;
- using System.Net.Http.Headers;
- using System.Text;
- using System.Text.Json;
- using Grpc.Core;
- using IntegrationTestsWebsite;
- using Microsoft.AspNetCore.Grpc.JsonTranscoding.IntegrationTests.Infrastructure;
- using Microsoft.AspNetCore.Grpc.JsonTranscoding.Internal;
- using Microsoft.AspNetCore.Grpc.JsonTranscoding.Tests.Infrastructure;
- using Microsoft.AspNetCore.InternalTesting;
- using Xunit.Abstractions;
- namespace Microsoft.AspNetCore.Grpc.JsonTranscoding.IntegrationTests;
- public class UnaryTests : IntegrationTestBase
- {
- public UnaryTests(GrpcTestFixture<Startup> fixture, ITestOutputHelper outputHelper)
- : base(fixture, outputHelper)
- {
- }
- [Fact]
- public async Task GetWithRouteParameter_MatchUrl_SuccessResult()
- {
- // Arrange
- Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
- {
- return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}!" });
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHello"));
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- // Act
- var response = await client.GetAsync("/v1/greeter/test").DefaultTimeout();
- var responseStream = await response.Content.ReadAsStreamAsync();
- using var result = await JsonDocument.ParseAsync(responseStream);
- // Assert
- Assert.Equal("Hello test!", result.RootElement.GetProperty("message").GetString());
- }
- [Fact]
- public async Task WriteResponseHeadersAsync_SendHeaders_HeadersSentBeforeResult()
- {
- // Arrange
- var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- async Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
- {
- await context.WriteResponseHeadersAsync(new Metadata
- {
- new Metadata.Entry("test", "value!")
- });
- await tcs.Task;
- return new HelloReply { Message = $"Hello {request.Name}!" };
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHello"));
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- // Act
- var response = await client.GetAsync("/v1/greeter/test", HttpCompletionOption.ResponseHeadersRead).DefaultTimeout();
- var responseStream = await response.Content.ReadAsStreamAsync();
- var resultTask = JsonDocument.ParseAsync(responseStream);
- // Assert
- Assert.Equal("value!", response.Headers.GetValues("test").Single());
- Assert.False(resultTask.IsCompleted);
- tcs.SetResult();
- using var result = await resultTask.DefaultTimeout();
- Assert.Equal("Hello test!", result.RootElement.GetProperty("message").GetString());
- }
- [Fact]
- public async Task WriteResponseHeadersAsync_CallTwice_Error()
- {
- // Arrange
- var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- async Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
- {
- await context.WriteResponseHeadersAsync(new Metadata
- {
- new Metadata.Entry("test", "value!")
- });
- await tcs.Task;
- await context.WriteResponseHeadersAsync(new Metadata
- {
- new Metadata.Entry("test", "value 2!")
- });
- return new HelloReply { Message = $"Hello {request.Name}!" };
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHello"));
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- // Act
- var response = await client.GetAsync("/v1/greeter/test", HttpCompletionOption.ResponseHeadersRead).DefaultTimeout();
- var responseStream = await response.Content.ReadAsStreamAsync();
- var resultTask = JsonDocument.ParseAsync(responseStream);
- // Assert
- Assert.Equal("value!", response.Headers.GetValues("test").Single());
- Assert.False(resultTask.IsCompleted);
- tcs.SetResult();
- using var result = await resultTask.DefaultTimeout();
- Assert.Equal("Exception was thrown by handler. InvalidOperationException: Response headers can only be sent once per call.", result.RootElement.GetProperty("message").GetString());
- }
- [Fact]
- public async Task AuthContext_BasicRequest_Unauthenticated()
- {
- // Arrange
- AuthContext? authContext = null;
- Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
- {
- authContext = context.AuthContext;
- return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}!" });
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHello"));
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- // Act
- var response = await client.GetAsync("/v1/greeter/test").DefaultTimeout();
- var responseStream = await response.Content.ReadAsStreamAsync();
- using var result = await JsonDocument.ParseAsync(responseStream);
- // Assert
- Assert.False(authContext!.IsPeerAuthenticated);
- Assert.Equal("Hello test!", result.RootElement.GetProperty("message").GetString());
- }
- [Theory]
- [InlineData(null)]
- [InlineData("utf-8")]
- [InlineData("utf-16")]
- [InlineData("latin1")]
- public async Task Request_SupportedCharset_Success(string? charset)
- {
- // Arrange
- Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
- {
- return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}!" });
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHelloPost"));
- var encoding = JsonRequestHelpers.GetEncodingFromCharset(charset);
- var contentType = charset != null
- ? "application/json; charset=" + charset
- : "application/json";
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- var requestMessage = new HelloRequest { Name = "test" };
- var content = new ByteArrayContent((encoding ?? Encoding.UTF8).GetBytes(requestMessage.ToString()));
- content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
- // Act
- var response = await client.PostAsync("/v1/greeter", content).DefaultTimeout();
- var responseText = await response.Content.ReadAsStringAsync();
- using var result = JsonDocument.Parse(responseText);
- // Assert
- Assert.Equal("application/json", response.Content.Headers.ContentType!.MediaType);
- Assert.Equal(encoding?.WebName ?? "utf-8", response.Content.Headers.ContentType!.CharSet);
- Assert.Equal("Hello test!", result.RootElement.GetProperty("message").GetString());
- }
- [Theory]
- [InlineData("FAKE", "InvalidOperationException: Unable to read the request as JSON because the request content type charset 'FAKE' is not a known encoding.")]
- [InlineData("UTF-7", "InvalidOperationException: Unable to read the request as JSON because the request content type charset 'UTF-7' is not a known encoding.")]
- public async Task Request_UnsupportedCharset_Error(string? charset, string errorMessage)
- {
- // Arrange
- Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
- {
- return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}!" });
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<HelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHelloPost"));
- var contentType = "application/json; charset=" + charset;
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- var requestMessage = new HelloRequest { Name = "test" };
- var content = new ByteArrayContent(Encoding.UTF8.GetBytes(requestMessage.ToString()));
- content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
- // Act
- var response = await client.PostAsync("/v1/greeter", content).DefaultTimeout();
- var responseText = await response.Content.ReadAsStringAsync();
- using var result = JsonDocument.Parse(responseText);
- // Assert
- Assert.Equal("application/json", response.Content.Headers.ContentType!.MediaType);
- Assert.Equal("utf-8", response.Content.Headers.ContentType!.CharSet);
- Assert.Contains(errorMessage, result.RootElement.GetProperty("message").GetString());
- }
- [Fact]
- public async Task Request_SendEnumString_Success()
- {
- // Arrange
- Task<HelloReply> UnaryMethod(EnumHelloRequest request, ServerCallContext context)
- {
- return Task.FromResult(new HelloReply { Message = $"Hello {request.Name}!" });
- }
- var method = Fixture.DynamicGrpc.AddUnaryMethod<EnumHelloRequest, HelloReply>(
- UnaryMethod,
- Greeter.Descriptor.FindMethodByName("SayHelloPostEnum"));
- var client = new HttpClient(Fixture.Handler) { BaseAddress = new Uri("http://localhost") };
- var requestMessage = new EnumHelloRequest { Name = NameOptions.Jane };
- var content = new ByteArrayContent(Encoding.UTF8.GetBytes(requestMessage.ToString()));
- content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
- // Act
- var response = await client.PostAsync("/v1/greeter_enum", content).DefaultTimeout();
- var responseText = await response.Content.ReadAsStringAsync();
- using var result = JsonDocument.Parse(responseText);
- // Assert
- Assert.Equal("application/json", response.Content.Headers.ContentType!.MediaType);
- Assert.Equal("utf-8", response.Content.Headers.ContentType!.CharSet);
- Assert.Equal("Hello Jane!", result.RootElement.GetProperty("message").GetString());
- }
- }
|