Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 0 additions & 73 deletions src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1314,79 +1314,6 @@ void TestAction(HttpResponse httpResponse)
Assert.Equal(httpContext.Response, httpResponseArgument);
}

public static IEnumerable<object[]> ComplexResult
{
get
{
Todo originalTodo = new()
{
Name = "Write even more tests!"
};

Todo TestAction() => originalTodo;
Task<Todo> TaskTestAction() => Task.FromResult(originalTodo);
ValueTask<Todo> ValueTaskTestAction() => ValueTask.FromResult(originalTodo);

static Todo StaticTestAction() => new Todo { Name = "Write even more tests!" };
static Task<Todo> StaticTaskTestAction() => Task.FromResult(new Todo { Name = "Write even more tests!" });
static ValueTask<Todo> StaticValueTaskTestAction() => ValueTask.FromResult(new Todo { Name = "Write even more tests!" });

return new List<object[]>
{
new object[] { (Func<Todo>)TestAction },
new object[] { (Func<Task<Todo>>)TaskTestAction},
new object[] { (Func<ValueTask<Todo>>)ValueTaskTestAction},
new object[] { (Func<Todo>)StaticTestAction},
new object[] { (Func<Task<Todo>>)StaticTaskTestAction},
new object[] { (Func<ValueTask<Todo>>)StaticValueTaskTestAction},
};
}
}

[Theory]
[MemberData(nameof(ComplexResult))]
public async Task RequestDelegateWritesComplexReturnValueAsJsonResponseBody(Delegate @delegate)
{
var httpContext = CreateHttpContext();
var responseBodyStream = new MemoryStream();
httpContext.Response.Body = responseBodyStream;

var factoryResult = RequestDelegateFactory.Create(@delegate);
var requestDelegate = factoryResult.RequestDelegate;

await requestDelegate(httpContext);

var deserializedResponseBody = JsonSerializer.Deserialize<Todo>(responseBodyStream.ToArray(), new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});

Assert.NotNull(deserializedResponseBody);
Assert.Equal("Write even more tests!", deserializedResponseBody!.Name);
}

[Fact]
public async Task RequestDelegateWritesComplexStructReturnValueAsJsonResponseBody()
{
var httpContext = CreateHttpContext();
var responseBodyStream = new MemoryStream();
httpContext.Response.Body = responseBodyStream;

var factoryResult = RequestDelegateFactory.Create(() => new TodoStruct(42, "Bob", true));
var requestDelegate = factoryResult.RequestDelegate;

await requestDelegate(httpContext);

var deserializedResponseBody = JsonSerializer.Deserialize<TodoStruct>(responseBodyStream.ToArray(), new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});

Assert.Equal(42, deserializedResponseBody.Id);
Assert.Equal("Bob", deserializedResponseBody.Name);
Assert.True(deserializedResponseBody.IsComplete);
}

public static IEnumerable<object[]> ChildResult
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using System.Text.Json;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Http.Json;
using Microsoft.AspNetCore.Http.RequestDelegateGenerator;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Testing;
Expand All @@ -21,7 +20,6 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.DependencyModel.Resolution;
using Microsoft.Extensions.Options;

namespace Microsoft.AspNetCore.Http.Generators.Tests;

Expand Down Expand Up @@ -218,12 +216,29 @@ internal HttpContext CreateHttpContextWithBody(Todo requestData, IServiceProvide
return httpContext;
}

internal static async Task VerifyResponseBodyAsync(HttpContext httpContext, string expectedBody, int expectedStatusCode = 200)
internal static async Task<string> GetResponseBodyAsync(HttpContext httpContext)
{
var httpResponse = httpContext.Response;
httpResponse.Body.Seek(0, SeekOrigin.Begin);
var streamReader = new StreamReader(httpResponse.Body);
var body = await streamReader.ReadToEndAsync();
return await streamReader.ReadToEndAsync();
}

internal static async Task VerifyResponseJsonBodyAsync<T>(HttpContext httpContext, Action<T> check, int expectedStatusCode = 200)
{
var body = await GetResponseBodyAsync(httpContext);
var deserializedObject = JsonSerializer.Deserialize<T>(body, new JsonSerializerOptions()
{
PropertyNameCaseInsensitive = true
});

Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode);
check(deserializedObject);
}

internal static async Task VerifyResponseBodyAsync(HttpContext httpContext, string expectedBody, int expectedStatusCode = 200)
{
var body = await GetResponseBodyAsync(httpContext);
Assert.Equal(expectedStatusCode, httpContext.Response.StatusCode);
Assert.Equal(expectedBody, body);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,4 +357,88 @@ public async Task SupportsIResultWithExplicitInterfaceImplementation()

await VerifyResponseBodyAsync(httpContext, "Already gone!", StatusCodes.Status410Gone);
}

public static IEnumerable<object[]> ComplexResult
{
get
{
var testAction = """
app.MapPost("/", () => new Todo() { Name = "Write even more tests!" });
""";

var taskTestAction = """
app.MapPost("/", () => Task.FromResult(new Todo() { Name = "Write even more tests!" }));
""";

var valueTaskTestAction = """
app.MapPost("/", () => ValueTask.FromResult(new Todo() { Name = "Write even more tests!" }));
""";

var staticTestAction = """
app.MapPost("/", StaticTestAction);
static Todo StaticTestAction() => new Todo() { Name = "Write even more tests!" };
""";

var staticTaskTestAction = """
app.MapPost("/", StaticTaskTestAction);
static Task<Todo> StaticTaskTestAction() => Task.FromResult(new Todo() { Name = "Write even more tests!" });
""";

var staticValueTaskTestAction = """
app.MapPost("/", StaticValueTaskTestAction);
static ValueTask<Todo> StaticValueTaskTestAction() => ValueTask.FromResult(new Todo() { Name = "Write even more tests!" });
""";

return new List<object[]>
{
new object[] { testAction },
new object[] { taskTestAction },
new object[] { valueTaskTestAction },
new object[] { staticTestAction },
new object[] { staticTaskTestAction },
new object[] { staticValueTaskTestAction }
};
}
}

[Theory]
[MemberData(nameof(ComplexResult))]
public async Task RequestDelegateWritesComplexReturnValueAsJsonResponseBody(string source)
{
var (_, compilation) = await RunGeneratorAsync(source);
var endpoint = GetEndpointFromCompilation(compilation);

var httpContext = CreateHttpContext();

await endpoint.RequestDelegate(httpContext);

await VerifyResponseJsonBodyAsync<Todo>(httpContext, (todo) =>
{
Assert.NotNull(todo);
Assert.Equal("Write even more tests!", todo!.Name);
});
}

[Fact]
public async Task RequestDelegateWritesComplexStructReturnValueAsJsonResponseBody()
{
var source = """
app.MapPost("/", () => new TodoStruct(42, "Bob", true, TodoStatus.Done));
""";

var (_, compilation) = await RunGeneratorAsync(source);
var endpoint = GetEndpointFromCompilation(compilation);

var httpContext = CreateHttpContext();

await endpoint.RequestDelegate(httpContext);

await VerifyResponseJsonBodyAsync<TodoStruct>(httpContext, (todo) =>
{
Assert.Equal(42, todo.Id);
Assert.Equal("Bob", todo.Name);
Assert.True(todo.IsComplete);
Assert.Equal(TodoStatus.Done, todo.Status);
});
}
}