a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
258 lines
9.4 KiB
C#
258 lines
9.4 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http.Formatting.Mocks;
|
|
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using Microsoft.TestCommon;
|
|
using Newtonsoft.Json.Linq;
|
|
using Xunit;
|
|
using Assert = Microsoft.TestCommon.AssertEx;
|
|
|
|
namespace System.Net.Http.Formatting
|
|
{
|
|
public class DefaultContentNegotiatorTests
|
|
{
|
|
private readonly DefaultContentNegotiator _negotiator = new DefaultContentNegotiator();
|
|
private readonly HttpRequestMessage _request = new HttpRequestMessage();
|
|
|
|
[Fact]
|
|
public void TypeIsCorrect()
|
|
{
|
|
Assert.Type.HasProperties(typeof(DefaultContentNegotiator), TypeAssert.TypeProperties.IsPublicVisibleClass);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_WhenTypeParameterIsNull_ThrowsException()
|
|
{
|
|
Assert.ThrowsArgumentNull(() => _negotiator.Negotiate(null, _request, Enumerable.Empty<MediaTypeFormatter>()), "type");
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_WhenRequestParameterIsNull_ThrowsException()
|
|
{
|
|
Assert.ThrowsArgumentNull(() => _negotiator.Negotiate(typeof(string), null, Enumerable.Empty<MediaTypeFormatter>()), "request");
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_WhenFormattersParameterIsNull_ThrowsException()
|
|
{
|
|
Assert.ThrowsArgumentNull(() => _negotiator.Negotiate(typeof(string), _request, null), "formatters");
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_ForEmptyFormatterCollection_ReturnsNull()
|
|
{
|
|
var result = _negotiator.Negotiate(typeof(string), _request, Enumerable.Empty<MediaTypeFormatter>());
|
|
|
|
Assert.Null(result);
|
|
}
|
|
|
|
[Fact]
|
|
public void MediaTypeMappingTakesPrecedenceOverAcceptHeader()
|
|
{
|
|
// Prepare the request message
|
|
_request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
|
|
_request.Headers.Add("Browser", "IE");
|
|
_request.Headers.Add("Cookie", "ABC");
|
|
|
|
// Prepare the formatters
|
|
List<MediaTypeFormatter> formatters = new List<MediaTypeFormatter>();
|
|
formatters.Add(new JsonMediaTypeFormatter());
|
|
formatters.Add(new XmlMediaTypeFormatter());
|
|
PlainTextFormatter frmtr = new PlainTextFormatter();
|
|
frmtr.SupportedMediaTypes.Clear();
|
|
frmtr.MediaTypeMappings.Clear();
|
|
frmtr.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
|
|
frmtr.MediaTypeMappings.Add(new MyMediaTypeMapping(new MediaTypeHeaderValue(("application/xml"))));
|
|
formatters.Add(frmtr);
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, formatters);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal("application/xml", result.MediaType.MediaType);
|
|
Assert.IsType<PlainTextFormatter>(result.Formatter);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_ForRequestReturnsFirstMatchingFormatter()
|
|
{
|
|
MediaTypeHeaderValue mediaType = new MediaTypeHeaderValue("application/myMediaType");
|
|
|
|
MediaTypeFormatter formatter1 = new MockMediaTypeFormatter()
|
|
{
|
|
CanWriteTypeCallback = (Type t) => false
|
|
};
|
|
|
|
MediaTypeFormatter formatter2 = new MockMediaTypeFormatter()
|
|
{
|
|
CanWriteTypeCallback = (Type t) => true
|
|
};
|
|
|
|
formatter2.SupportedMediaTypes.Add(mediaType);
|
|
|
|
MediaTypeFormatterCollection collection = new MediaTypeFormatterCollection(
|
|
new MediaTypeFormatter[]
|
|
{
|
|
formatter1,
|
|
formatter2
|
|
});
|
|
|
|
_request.Content = new StringContent("test", Encoding.Default, mediaType.MediaType);
|
|
|
|
var result = _negotiator.Negotiate(typeof(string), _request, collection);
|
|
Assert.Same(formatter2, result.Formatter);
|
|
Assert.MediaType.AreEqual(mediaType, result.MediaType, "Expected the formatter's media type to be returned.");
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_SelectsJsonAsDefaultFormatter()
|
|
{
|
|
// Arrange
|
|
_request.Content = new StringContent("test");
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, new MediaTypeFormatterCollection());
|
|
|
|
// Assert
|
|
Assert.IsType<JsonMediaTypeFormatter>(result.Formatter);
|
|
Assert.Equal(MediaTypeConstants.ApplicationJsonMediaType.MediaType, result.MediaType.MediaType);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_SelectsXmlFormatter_ForXhrRequestThatAcceptsXml()
|
|
{
|
|
// Arrange
|
|
_request.Content = new StringContent("test");
|
|
_request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/xml"));
|
|
_request.Headers.Add("x-requested-with", "XMLHttpRequest");
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, new MediaTypeFormatterCollection());
|
|
|
|
// Assert
|
|
Assert.Equal("application/xml", result.MediaType.MediaType);
|
|
Assert.IsType<XmlMediaTypeFormatter>(result.Formatter);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_SelectsJsonFormatter_ForXhrRequestThatDoesNotSpecifyAcceptHeaders()
|
|
{
|
|
// Arrange
|
|
_request.Content = new StringContent("test");
|
|
_request.Headers.Add("x-requested-with", "XMLHttpRequest");
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, new MediaTypeFormatterCollection());
|
|
|
|
// Assert
|
|
Assert.Equal("application/json", result.MediaType.MediaType);
|
|
Assert.IsType<JsonMediaTypeFormatter>(result.Formatter);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_RespectsFormatterOrdering_ForXhrRequestThatDoesNotSpecifyAcceptHeaders()
|
|
{
|
|
// Arrange
|
|
_request.Content = new StringContent("test");
|
|
_request.Headers.Add("x-requested-with", "XMLHttpRequest");
|
|
|
|
MediaTypeFormatterCollection formatters = new MediaTypeFormatterCollection(new MediaTypeFormatter[]
|
|
{
|
|
new XmlMediaTypeFormatter(),
|
|
new JsonMediaTypeFormatter(),
|
|
new FormUrlEncodedMediaTypeFormatter()
|
|
});
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, formatters);
|
|
|
|
// Assert
|
|
Assert.Equal("application/json", result.MediaType.MediaType);
|
|
Assert.IsType<JsonMediaTypeFormatter>(result.Formatter);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_SelectsJsonFormatter_ForXHRAndJsonValueResponse()
|
|
{
|
|
// Arrange
|
|
_request.Content = new StringContent("test");
|
|
_request.Headers.Add("x-requested-with", "XMLHttpRequest");
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(JToken), _request, new MediaTypeFormatterCollection());
|
|
|
|
Assert.Equal("application/json", result.MediaType.MediaType);
|
|
Assert.IsType<JsonMediaTypeFormatter>(result.Formatter);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_SelectsJsonFormatter_ForXHRAndMatchAllAcceptHeader()
|
|
{
|
|
// Accept
|
|
_request.Content = new StringContent("test");
|
|
_request.Headers.Add("x-requested-with", "XMLHttpRequest");
|
|
_request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("*/*"));
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, new MediaTypeFormatterCollection());
|
|
|
|
// Assert
|
|
Assert.Equal("application/json", result.MediaType.MediaType);
|
|
Assert.IsType<JsonMediaTypeFormatter>(result.Formatter);
|
|
}
|
|
|
|
[Fact]
|
|
public void Negotiate_UsesRequestedFormatterForXHRAndMatchAllPlusOtherAcceptHeader()
|
|
{
|
|
// Arrange
|
|
_request.Content = new StringContent("test");
|
|
_request.Headers.Add("x-requested-with", "XMLHttpRequest");
|
|
_request.Headers.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); // XHR header sent by Firefox 3b5
|
|
|
|
// Act
|
|
var result = _negotiator.Negotiate(typeof(string), _request, new MediaTypeFormatterCollection());
|
|
|
|
// Assert
|
|
Assert.Equal("application/xml", result.MediaType.MediaType);
|
|
Assert.IsType<XmlMediaTypeFormatter>(result.Formatter);
|
|
}
|
|
|
|
private class PlainTextFormatter : MediaTypeFormatter
|
|
{
|
|
public override bool CanReadType(Type type)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public override bool CanWriteType(Type type)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
private class MyMediaTypeMapping : MediaTypeMapping
|
|
{
|
|
public MyMediaTypeMapping(MediaTypeHeaderValue mediaType)
|
|
: base(mediaType)
|
|
{
|
|
}
|
|
|
|
public override double TryMatchMediaType(HttpRequestMessage request)
|
|
{
|
|
if (request.Headers.Contains("Cookie"))
|
|
{
|
|
return 1.0;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|