aspnetcore/test/Microsoft.AspNetCore.Mvc.Fu.../WebApiCompatShimBasicTest.cs

470 lines
18 KiB
C#

// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.AspNetCore.Testing;
using Microsoft.AspNetCore.Testing.xunit;
using Newtonsoft.Json;
using Xunit;
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
{
public class WebApiCompatShimBasicTest : IClassFixture<MvcTestFixture<WebApiCompatShimWebSite.Startup>>
{
public WebApiCompatShimBasicTest(MvcTestFixture<WebApiCompatShimWebSite.Startup> fixture)
{
Client = fixture.Client;
}
public HttpClient Client { get; }
[Fact]
public async Task ApiController_Activates_HttpContextAndUser()
{
// Arrange & Act
var response = await Client.GetAsync("http://localhost/api/Blog/BasicApi/WriteToHttpContext");
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(
"Hello, Anonymous User from WebApiCompatShimWebSite.BasicApiController.WriteToHttpContext (WebApiCompatShimWebSite)",
content);
}
[Fact]
public async Task ApiController_Activates_UrlHelper()
{
// Arrange & Act
var response = await Client.GetAsync("http://localhost/api/Blog/BasicApi/GenerateUrl");
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(
"Visited: /api/Blog/BasicApi/GenerateUrl",
content);
}
[Fact]
public async Task Options_SetsDefaultFormatters()
{
// Arrange
var expected = new string[]
{
typeof(JsonMediaTypeFormatter).FullName,
typeof(XmlMediaTypeFormatter).FullName,
#if !NETCOREAPP1_1
typeof(FormUrlEncodedMediaTypeFormatter).FullName,
#endif
};
// Act
var response = await Client.GetAsync("http://localhost/api/Blog/BasicApi/GetFormatters");
var content = await response.Content.ReadAsStringAsync();
var formatters = JsonConvert.DeserializeObject<string[]>(content);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(expected, formatters);
}
[Fact]
public async Task ActionThrowsHttpResponseException_WithStatusCode()
{
// Arrange & Act
var response = await Client.GetAsync(
"http://localhost/api/Blog/HttpResponseException/ThrowsHttpResponseExceptionWithHttpStatusCode");
// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal(string.Empty, content);
}
[Fact]
public async Task ActionThrowsHttpResponseException_WithResponse()
{
// Arrange & Act
var response = await Client.GetAsync(
"http://localhost/api/Blog/HttpResponseException" +
"/ThrowsHttpResponseExceptionWithHttpResponseMessage?message=send some message");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal("send some message", content);
}
[Fact]
public async Task ActionThrowsHttpResponseException_EnsureGlobalHttpresponseExceptionActionFilter_IsInvoked()
{
// Arrange & Act
var response = await Client.GetAsync(
"http://localhost/api/Blog/HttpResponseException/ThrowsHttpResponseExceptionEnsureGlobalFilterRunsLast");
// Assert
// Ensure we do not get a no content result.
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal(string.Empty, content);
}
[Fact]
public async Task ActionThrowsHttpResponseException_EnsureGlobalFilterConvention_IsApplied()
{
// Arrange & Act
var response = await Client.GetAsync(
"http://localhost/api/Blog/" +
"HttpResponseException/ThrowsHttpResponseExceptionInjectAFilterToHandleHttpResponseException");
// Assert
// Ensure we do get a no content result.
Assert.Equal(HttpStatusCode.NoContent, response.StatusCode);
var content = await response.Content.ReadAsStringAsync();
Assert.Equal(string.Empty, content);
}
[Fact]
public async Task ApiController_CanValidateCustomObjectWithPrefix_Fails()
{
// Arrange & Act
var response = await Client.GetStringAsync(
"http://localhost/api/Blog/BasicApi/ValidateObjectWithPrefixFails?prefix=prefix");
// Assert
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
Assert.Equal(1, json.Count);
Assert.Equal("The field ID must be between 0 and 100.", json["prefix.ID"]);
}
[Fact]
public async Task ApiController_CanValidateCustomObject_IsSuccessFul()
{
// Arrange & Act
var response = await Client.GetStringAsync("http://localhost/api/Blog/BasicApi/ValidateObject_Passes");
// Assert
Assert.Equal("true", response);
}
[Fact]
public async Task ApiController_CanValidateCustomObject_Fails()
{
// Arrange & Act
var response = await Client.GetStringAsync("http://localhost/api/Blog/BasicApi/ValidateObjectFails");
// Assert
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(response);
Assert.Equal(1, json.Count);
Assert.Equal("The field ID must be between 0 and 100.", json["ID"]);
}
[ConditionalFact]
// Mono issue - https://github.com/aspnet/External/issues/24
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
public async Task ApiController_RequestProperty()
{
// Arrange
var expected = "POST http://localhost/api/Blog/HttpRequestMessage/EchoProperty localhost " +
"13 Hello, world!";
// Act
var response = await Client.PostAsync(
"http://localhost/api/Blog/HttpRequestMessage/EchoProperty",
new StringContent("Hello, world!"));
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(expected, content);
}
[ConditionalFact]
// Mono issue - https://github.com/aspnet/External/issues/24
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
public async Task ApiController_RequestParameter()
{
// Arrange
var expected =
"POST http://localhost/api/Blog/HttpRequestMessage/EchoParameter localhost " +
"17 Hello, the world!";
// Act
var response = await Client.PostAsync(
"http://localhost/api/Blog/HttpRequestMessage/EchoParameter",
new StringContent("Hello, the world!"));
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(expected, content);
}
[Fact]
public async Task ApiController_ResponseReturned()
{
// Arrange
var expected = "POST Hello, HttpResponseMessage world!";
// Act
var response = await Client.PostAsync(
"http://localhost/api/Blog/HttpRequestMessage/EchoWithResponseMessage",
new StringContent("Hello, HttpResponseMessage world!"));
var content = await response.Content.ReadAsStringAsync();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal(expected, content);
IEnumerable<string> values;
Assert.True(response.Headers.TryGetValues("X-Test", out values));
Assert.Equal(new string[] { "Hello!" }, values);
Assert.Equal(38, response.Content.Headers.ContentLength);
}
[Fact]
public async Task ApiController_ExplicitChunkedEncoding_IsIgnored()
{
// Arrange
var expected = "POST Hello, HttpResponseMessage world!";
var request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri("http://localhost/api/Blog/HttpRequestMessage/EchoWithResponseMessageChunked");
request.Content = new StringContent("Hello, HttpResponseMessage world!");
// Act
// HttpClient buffers the response by default and this would set the Content-Length header and so
// this will not provide us accurate information as to whether the server set the header or
// the client. So here we explicitly mention to only read the headers and not the body.
var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
if (!TestPlatformHelper.IsMono)
{
// Mono issue - https://github.com/aspnet/External/issues/20
Assert.NotNull(response.Content.Headers.ContentLength);
}
Assert.Null(response.Headers.TransferEncodingChunked);
// When HttpClient by default reads and buffers the response body, it disposes the
// response stream for us. But since we are reading the content explicitly, we need
// to close it.
var responseStream = await response.Content.ReadAsStreamAsync();
using (var streamReader = new StreamReader(responseStream))
{
Assert.Equal(expected, streamReader.ReadToEnd());
}
IEnumerable<string> values;
Assert.True(response.Headers.TryGetValues("X-Test", out values));
Assert.Equal(new string[] { "Hello!" }, values);
}
[Theory]
[InlineData("application/json", "application/json")]
[InlineData("text/xml", "text/xml")]
[InlineData("text/plain, text/xml; q=0.5", "text/xml")]
[InlineData("application/*", "application/json")]
public async Task ApiController_CreateResponse_Conneg(string accept, string mediaType)
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Get,
"http://localhost/api/Blog/HttpRequestMessage/GetUser");
request.Headers.Accept.ParseAdd(accept);
// Act
var response = await Client.SendAsync(request);
var user = await response.Content.ReadAsAsync<WebApiCompatShimWebSite.User>();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("Test User", user.Name);
Assert.Equal(mediaType, response.Content.Headers.ContentType.MediaType);
}
[Theory]
[InlineData("application/json")]
[InlineData("text/xml")]
public async Task ApiController_CreateResponse_HardcodedMediaType(string mediaType)
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Get,
"http://localhost/api/Blog/HttpRequestMessage/GetUser?mediaType=" + mediaType);
// Act
var response = await Client.SendAsync(request);
var user = await response.Content.ReadAsAsync<WebApiCompatShimWebSite.User>();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("Test User", user.Name);
Assert.Equal(mediaType, response.Content.Headers.ContentType.MediaType);
}
[Theory]
[InlineData("application/json", "application/json")]
[InlineData("text/xml", "text/xml")]
[InlineData("text/plain, text/xml; q=0.5", "text/xml")]
[InlineData("application/*", "application/json")]
public async Task ApiController_CreateResponse_Conneg_Error(string accept, string mediaType)
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Get,
"http://localhost/api/Blog/HttpRequestMessage/Fail");
request.Headers.Accept.ParseAdd(accept);
// Act
var response = await Client.SendAsync(request);
var error = await response.Content.ReadAsAsync<HttpError>();
// Assert
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
Assert.Equal("It failed.", error.Message);
Assert.Equal(mediaType, response.Content.Headers.ContentType.MediaType);
}
[Fact]
public async Task ApiController_CreateResponse_HardcodedFormatter()
{
// Arrange
var request = new HttpRequestMessage(
HttpMethod.Get,
"http://localhost/api/Blog/HttpRequestMessage/GetUserJson");
// Accept header will be ignored
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
// Act
var response = await Client.SendAsync(request);
var user = await response.Content.ReadAsAsync<WebApiCompatShimWebSite.User>();
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("Test User", user.Name);
Assert.Equal("text/json", response.Content.Headers.ContentType.MediaType);
}
[Theory]
[InlineData("http://localhost/Mvc/Index", HttpStatusCode.OK)]
[InlineData("http://localhost/api/Blog/Mvc/Index", HttpStatusCode.NotFound)]
public async Task WebApiRouting_AccessMvcController(string url, HttpStatusCode expected)
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, url);
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(expected, response.StatusCode);
}
[Theory]
[InlineData("http://localhost/BasicApi/GenerateUrl", HttpStatusCode.NotFound)]
[InlineData("http://localhost/api/Blog/BasicApi/GenerateUrl", HttpStatusCode.OK)]
public async Task WebApiRouting_AccessWebApiController(string url, HttpStatusCode expected)
{
// Arrange
var request = new HttpRequestMessage(HttpMethod.Get, url);
// Act
var response = await Client.SendAsync(request);
// Assert
Assert.Equal(expected, response.StatusCode);
}
[Fact]
public async Task ApiController_Returns_ByteArrayContent()
{
// Arrange
var expectedBody = "Hello from ByteArrayContent!!";
// Act
var response = await Client.GetAsync("http://localhost/api/Blog/HttpRequestMessage/ReturnByteArrayContent");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
Assert.Equal("text/plain", response.Content.Headers.ContentType.MediaType);
var actualBody = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, actualBody);
}
[Fact]
public async Task ApiController_Returns_StreamContent()
{
// Arrange
var expectedBody = "This content is from a file";
// Act
var response = await Client.GetAsync("http://localhost/api/Blog/HttpRequestMessage/ReturnStreamContent");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
Assert.Equal("image/jpeg", response.Content.Headers.ContentType.MediaType);
Assert.NotNull(response.Content.Headers.ContentDisposition);
Assert.Equal("attachment", response.Content.Headers.ContentDisposition.DispositionType);
var actualBody = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, actualBody);
}
[Theory]
[InlineData("ReturnPushStreamContent", "Hello from PushStreamContent!!")]
[InlineData("ReturnPushStreamContentSync", "Hello from PushStreamContent Sync!!")]
public async Task ApiController_Returns_PushStreamContent(string action, string expectedBody)
{
// Arrange & Act
var response = await Client.GetAsync("http://localhost/api/Blog/HttpRequestMessage/" + action);
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
Assert.Equal("application/pdf", response.Content.Headers.ContentType.MediaType);
var actualBody = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, actualBody);
}
[Fact]
public async Task ApiController_Returns_PushStreamContentWithCustomHeaders()
{
// Arrange
var expectedBody = "Hello from PushStreamContent with custom headers!!";
var multipleValues = new[] { "value1", "value2" };
// Act
var response = await Client.GetAsync(
"http://localhost/api/Blog/HttpRequestMessage/ReturnPushStreamContentWithCustomHeaders");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotNull(response.Content);
Assert.Equal("application/octet-stream", response.Content.Headers.ContentType.ToString());
var actualBody = await response.Content.ReadAsStringAsync();
Assert.Equal(expectedBody, actualBody);
Assert.Equal(multipleValues, response.Headers.GetValues("Multiple"));
}
}
}