From 38e82c0aa59f9105767f73422d5ca7bcad902afa Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 23 Sep 2014 10:05:28 -0700 Subject: [PATCH] Updating Microsoft.AspNet.Mvc.Core.Test to work on Mono --- .../ActionExecutorTests.cs | 31 ++++---- .../AntiXsrf/AntiForgeryOptionsTests.cs | 4 +- .../AntiXsrf/AntiForgeryWorkerTests.cs | 7 +- .../AntiXsrf/ClaimUidExtractorTest.cs | 16 ++-- .../AntiXsrf/MockClaimsIdentity.cs | 25 ------- .../AntiXsrf/TokenProviderTests.cs | 25 +++++-- .../ControllerTests.cs | 75 ++++++++++++------- .../DefaultActionDiscoveryConventionsTests.cs | 6 +- ...taContractSerializerInputFormatterTests.cs | 21 +++++- ...aContractSerializerOutputFormatterTests.cs | 4 +- .../XmlSerializerInputFormatterTests.cs | 28 ++++++- .../MvcOptionsTests.cs | 2 +- .../ModelBindingHelperTest.cs | 7 +- .../ReflectedActionDescriptorProviderTests.cs | 16 +++- .../ViewResultTest.cs | 21 +++++- .../project.json | 2 +- 16 files changed, 182 insertions(+), 108 deletions(-) delete mode 100644 test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/MockClaimsIdentity.cs diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ActionExecutorTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ActionExecutorTests.cs index b31ae827cc..402bc84522 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ActionExecutorTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ActionExecutorTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.Threading.Tasks; +using Microsoft.AspNet.Testing; using Xunit; namespace Microsoft.AspNet.Mvc.Core.Test @@ -94,13 +95,12 @@ namespace Microsoft.AspNet.Mvc.Core.Test var actionParameters = new Dictionary { { "i", inputParam1 }, { "s", inputParam2 } }; var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskActionWithException); - await AssertThrowsAsync( - async () => - await ReflectedActionExecutor.ExecuteAsync( - methodWithTaskOfIntReturnType.GetMethodInfo(), - _controller, - actionParameters), - "Not Implemented Exception"); + + // Act and Assert + await Assert.ThrowsAsync( + () => ReflectedActionExecutor.ExecuteAsync(methodWithTaskOfIntReturnType.GetMethodInfo(), + _controller, + actionParameters)); } [Fact] @@ -111,13 +111,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test var actionParameters = new Dictionary { { "i", inputParam1 }, { "s", inputParam2 } }; var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskActionWithExceptionWithoutAsync); - await AssertThrowsAsync( - async () => - await ReflectedActionExecutor.ExecuteAsync( - methodWithTaskOfIntReturnType.GetMethodInfo(), - _controller, - actionParameters), - "Not Implemented Exception"); + await Assert.ThrowsAsync( + () => ReflectedActionExecutor.ExecuteAsync(methodWithTaskOfIntReturnType.GetMethodInfo(), + _controller, + actionParameters)); } [Fact] @@ -249,6 +246,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test _controller, actionParameters), expectedException); + + Assert.Equal(expectedException, ex.Message); } [Fact] @@ -275,9 +274,11 @@ namespace Microsoft.AspNet.Mvc.Core.Test var actionParameters = new Dictionary { { "i", "Some Invalid Value" }, { "s", inputParam2 } }; var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskValueTypeAction); + var message = TestPlatformHelper.IsMono ? "Object type {0} cannot be converted to target type: {1}" : + "Object of type '{0}' cannot be converted to type '{1}'."; var expectedException = string.Format( CultureInfo.CurrentCulture, - "Object of type '{0}' cannot be converted to type '{1}'.", + message, typeof (string), typeof (int)); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryOptionsTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryOptionsTests.cs index 7081154346..3e789092a5 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryOptionsTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryOptionsTests.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Act & Assert var ex = Assert.Throws(() => options.CookieName = null); Assert.Equal("The 'CookieName' property of 'Microsoft.AspNet.Mvc.AntiForgeryOptions' must not be null." + - "\r\nParameter name: value", ex.Message); + Environment.NewLine + "Parameter name: value", ex.Message); } [Fact] @@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Act & Assert var ex = Assert.Throws(() => options.FormFieldName = null); Assert.Equal("The 'FormFieldName' property of 'Microsoft.AspNet.Mvc.AntiForgeryOptions' must not be null." + - "\r\nParameter name: value", ex.Message); + Environment.NewLine + "Parameter name: value", ex.Message); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryWorkerTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryWorkerTests.cs index 678819ea3d..f71d91d278 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryWorkerTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/AntiForgeryWorkerTests.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Security.Claims; -using System.Security.Principal; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.Rendering; @@ -392,12 +391,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test private Mock GetHttpContext(bool setupResponse = true) { - var identity = new GenericIdentity("some-user"); + var identity = new ClaimsIdentity("some-auth"); var mockHttpContext = new Mock(); - mockHttpContext.Setup(o => o.User) - .Returns(new GenericPrincipal(identity, new string[0])); - + .Returns(new ClaimsPrincipal(identity)); if (setupResponse) { diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/ClaimUidExtractorTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/ClaimUidExtractorTest.cs index a29c1a21fa..935bde557b 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/ClaimUidExtractorTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/ClaimUidExtractorTest.cs @@ -62,11 +62,11 @@ namespace Microsoft.AspNet.Mvc.Core.Test [Fact] public void DefaultUniqueClaimTypes_NotPresent_SerializesAllClaimTypes() { - var identity = new MockClaimsIdentity(); - identity.AddClaim(ClaimTypes.Email, "someone@antifrogery.com"); - identity.AddClaim(ClaimTypes.GivenName, "some"); - identity.AddClaim(ClaimTypes.Surname, "one"); - identity.AddClaim(ClaimTypes.NameIdentifier, String.Empty); + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim(ClaimTypes.Email, "someone@antifrogery.com")); + identity.AddClaim(new Claim(ClaimTypes.GivenName, "some")); + identity.AddClaim(new Claim(ClaimTypes.Surname, "one")); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, String.Empty)); // Arrange var claimsIdentity = (ClaimsIdentity)identity; @@ -90,9 +90,9 @@ namespace Microsoft.AspNet.Mvc.Core.Test public void DefaultUniqueClaimTypes_Present() { // Arrange - var identity = new MockClaimsIdentity(); - identity.AddClaim("fooClaim", "fooClaimValue"); - identity.AddClaim(ClaimTypes.NameIdentifier, "nameIdentifierValue"); + var identity = new ClaimsIdentity(); + identity.AddClaim(new Claim("fooClaim", "fooClaimValue")); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "nameIdentifierValue")); // Act var uniqueIdentifierParameters = DefaultClaimUidExtractor.GetUniqueIdentifierParameters(identity); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/MockClaimsIdentity.cs b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/MockClaimsIdentity.cs deleted file mode 100644 index a1a66e2508..0000000000 --- a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/MockClaimsIdentity.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Collections.Generic; -using System.Security.Claims; - -namespace Microsoft.AspNet.Mvc.Core.Test -{ - // Convenient class for mocking a ClaimsIdentity instance given some - // prefabricated Claim instances. - internal sealed class MockClaimsIdentity : ClaimsIdentity - { - private readonly List _claims = new List(); - - public void AddClaim(string claimType, string value) - { - _claims.Add(new Claim(claimType, value)); - } - - public override IEnumerable Claims - { - get { return _claims; } - } - } -} \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/TokenProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/TokenProviderTests.cs index a5403e9941..7ce02ac264 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/TokenProviderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/AntiXsrf/TokenProviderTests.cs @@ -3,8 +3,10 @@ using System; using System.Security.Claims; +using System.Security.Cryptography; using System.Security.Principal; using Microsoft.AspNet.Http; +using Microsoft.AspNet.PipelineCore; using Microsoft.AspNet.Security.DataProtection; using Moq; using Xunit; @@ -135,7 +137,10 @@ namespace Microsoft.AspNet.Mvc.Core.Test var config = new AntiForgeryOptions(); byte[] data = new byte[256 / 8]; - CryptRand.FillBuffer(new ArraySegment(data)); + using (var rng = RandomNumberGenerator.Create()) + { + rng.GetBytes(data); + } var base64ClaimUId = Convert.ToBase64String(data); var expectedClaimUid = new BinaryBlob(256, data); @@ -370,7 +375,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var httpContext = new Mock().Object; - ClaimsIdentity identity = new GenericIdentity(identityUsername); + var identity = GetAuthenticatedIdentity(identityUsername); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { @@ -402,7 +407,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var httpContext = new Mock().Object; - ClaimsIdentity identity = new GenericIdentity("the-user"); + var identity = GetAuthenticatedIdentity("the-user"); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { @@ -435,7 +440,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var httpContext = new Mock().Object; - ClaimsIdentity identity = new GenericIdentity(String.Empty); + var identity = new ClaimsIdentity(); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { @@ -467,7 +472,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var httpContext = new Mock().Object; - ClaimsIdentity identity = new GenericIdentity(String.Empty); + var identity = new ClaimsIdentity(); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { @@ -499,7 +504,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var httpContext = new Mock().Object; - ClaimsIdentity identity = new GenericIdentity("the-user"); + var identity = GetAuthenticatedIdentity("the-user"); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { @@ -531,7 +536,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test { // Arrange var httpContext = new Mock().Object; - ClaimsIdentity identity = new GenericIdentity("the-user"); + var identity = GetAuthenticatedIdentity("the-user"); var sessionToken = new AntiForgeryToken() { IsSessionToken = true }; var fieldtoken = new AntiForgeryToken() { @@ -558,6 +563,12 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Nothing to assert - if we got this far, success! } + private static ClaimsIdentity GetAuthenticatedIdentity(string identityUsername) + { + var claim = new Claim(ClaimsIdentity.DefaultNameClaimType, identityUsername); + return new ClaimsIdentity(new[] { claim }, "Some-Authentication"); + } + private sealed class MyAuthenticatedIdentityWithoutUsername : ClaimsIdentity { public override bool IsAuthenticated diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs index 76d1ba72ce..80cb2c3e0d 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ControllerTests.cs @@ -181,7 +181,9 @@ namespace Microsoft.AspNet.Mvc.Test [Theory] [MemberData(nameof(RedirectTestData))] - public void RedirectToAction_WithParameterActionControllerRouteValues_SetsResultProperties(object routeValues) + public void RedirectToAction_WithParameterActionControllerRouteValues_SetsResultProperties( + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -194,13 +196,14 @@ namespace Microsoft.AspNet.Mvc.Test Assert.False(resultTemporary.Permanent); Assert.Equal("SampleAction", resultTemporary.ActionName); Assert.Equal("SampleController", resultTemporary.ControllerName); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultTemporary.RouteValues); + Assert.Equal(expected, resultTemporary.RouteValues); } [Theory] [MemberData(nameof(RedirectTestData))] public void RedirectToActionPermanent_WithParameterActionControllerRouteValues_SetsResultProperties( - object routeValues) + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -216,12 +219,14 @@ namespace Microsoft.AspNet.Mvc.Test Assert.True(resultPermanent.Permanent); Assert.Equal("SampleAction", resultPermanent.ActionName); Assert.Equal("SampleController", resultPermanent.ControllerName); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultPermanent.RouteValues); + Assert.Equal(expected, resultPermanent.RouteValues); } [Theory] [MemberData(nameof(RedirectTestData))] - public void RedirectToAction_WithParameterActionAndRouteValues_SetsResultProperties(object routeValues) + public void RedirectToAction_WithParameterActionAndRouteValues_SetsResultProperties( + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -233,13 +238,14 @@ namespace Microsoft.AspNet.Mvc.Test Assert.IsType(resultTemporary); Assert.False(resultTemporary.Permanent); Assert.Null(resultTemporary.ActionName); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultTemporary.RouteValues); + Assert.Equal(expected, resultTemporary.RouteValues); } [Theory] [MemberData(nameof(RedirectTestData))] public void RedirectToActionPermanent_WithParameterActionAndRouteValues_SetsResultProperties( - object routeValues) + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -251,12 +257,14 @@ namespace Microsoft.AspNet.Mvc.Test Assert.IsType(resultPermanent); Assert.True(resultPermanent.Permanent); Assert.Null(resultPermanent.ActionName); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultPermanent.RouteValues); + Assert.Equal(expected, resultPermanent.RouteValues); } [Theory] [MemberData(nameof(RedirectTestData))] - public void RedirectToRoute_WithParameterRouteValues_SetsResultEqualRouteValues(object routeValues) + public void RedirectToRoute_WithParameterRouteValues_SetsResultEqualRouteValues( + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -267,13 +275,14 @@ namespace Microsoft.AspNet.Mvc.Test // Assert Assert.IsType(resultTemporary); Assert.False(resultTemporary.Permanent); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultTemporary.RouteValues); + Assert.Equal(expected, resultTemporary.RouteValues); } [Theory] [MemberData(nameof(RedirectTestData))] public void RedirectToRoutePermanent_WithParameterRouteValues_SetsResultEqualRouteValuesAndPermanent( - object routeValues) + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -284,7 +293,7 @@ namespace Microsoft.AspNet.Mvc.Test // Assert Assert.IsType(resultPermanent); Assert.True(resultPermanent.Permanent); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultPermanent.RouteValues); + Assert.Equal(expected, resultPermanent.RouteValues); } [Fact] @@ -322,7 +331,8 @@ namespace Microsoft.AspNet.Mvc.Test [Theory] [MemberData(nameof(RedirectTestData))] public void RedirectToRoute_WithParameterRouteNameAndRouteValues_SetsResultSameRouteNameAndRouteValues( - object routeValues) + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -335,13 +345,14 @@ namespace Microsoft.AspNet.Mvc.Test Assert.IsType(resultTemporary); Assert.False(resultTemporary.Permanent); Assert.Same(routeName, resultTemporary.RouteName); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultTemporary.RouteValues); + Assert.Equal(expected, resultTemporary.RouteValues); } [Theory] [MemberData(nameof(RedirectTestData))] public void RedirectToRoutePermanent_WithParameterRouteNameAndRouteValues_SetsResultProperties( - object routeValues) + object routeValues, + IEnumerable> expected) { // Arrange var controller = new Controller(); @@ -354,7 +365,7 @@ namespace Microsoft.AspNet.Mvc.Test Assert.IsType(resultPermanent); Assert.True(resultPermanent.Permanent); Assert.Same(routeName, resultPermanent.RouteName); - Assert.Equal(TypeHelper.ObjectToDictionary(routeValues), resultPermanent.RouteValues); + Assert.Equal(expected, resultPermanent.RouteValues); } [Fact] @@ -524,19 +535,29 @@ namespace Microsoft.AspNet.Mvc.Test { get { - yield return new object[] { null }; yield return new object[] - { - new Dictionary() { { "hello", "world" } }, - }; + { + null, + Enumerable.Empty>() + }; + yield return new object[] - { - new RouteValueDictionary(new Dictionary() - { - { "test", "case" }, - { "sample", "route" }, - }), - }; + { + new Dictionary { { "hello", "world" } }, + new[] { new KeyValuePair("hello", "world") } + }; + + var expected2 = new Dictionary + { + { "test", "case" }, + { "sample", "route" }, + }; + + yield return new object[] + { + new RouteValueDictionary(expected2), + expected2 + }; } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionDiscoveryConventionsTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionDiscoveryConventionsTests.cs index f80f7fbd39..0eeb077d51 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionDiscoveryConventionsTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/DefaultActionDiscoveryConventionsTests.cs @@ -223,7 +223,7 @@ namespace Microsoft.AspNet.Mvc var action = Assert.Single(actionInfos); Assert.Equal("Details", action.ActionName); Assert.True(action.RequireActionNameMatch); - Assert.Equal(new[] { "POST", "GET" }, action.HttpMethods); + Assert.Equal(new[] { "GET", "POST" }, action.HttpMethods.OrderBy(m => m, StringComparer.Ordinal)); Assert.Null(action.AttributeRoute); } @@ -242,7 +242,7 @@ namespace Microsoft.AspNet.Mvc var action = Assert.Single(actionInfos); Assert.Equal("List", action.ActionName); Assert.True(action.RequireActionNameMatch); - Assert.Equal(new[] { "GET", "PUT", "POST" }, action.HttpMethods); + Assert.Equal(new[] { "GET", "POST", "PUT"}, action.HttpMethods.OrderBy(m => m, StringComparer.Ordinal)); Assert.Null(action.AttributeRoute); } @@ -310,7 +310,7 @@ namespace Microsoft.AspNet.Mvc Assert.Equal("List", action.ActionName); Assert.True(action.RequireActionNameMatch); - Assert.Equal(new[] { "GET", "HEAD" }, action.HttpMethods); + Assert.Equal(new[] { "GET", "HEAD" }, action.HttpMethods.OrderBy(m => m, StringComparer.Ordinal)); Assert.NotNull(action.AttributeRoute); Assert.Equal("ListAll", action.AttributeRoute.Template); diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTests.cs index 6be33f0c4e..56bfd1a91e 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerInputFormatterTests.cs @@ -11,6 +11,7 @@ using System.Threading.Tasks; using System.Xml; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Testing; using Moq; using Xunit; @@ -181,6 +182,12 @@ namespace Microsoft.AspNet.Mvc [Fact] public async Task XmlDataContractSerializerFormatterThrowsOnExceededMaxDepth() { + if (TestPlatformHelper.IsMono) + { + // ReaderQuotas are not honored on Mono + return; + } + // Arrange var input = "" + "test" + @@ -198,6 +205,12 @@ namespace Microsoft.AspNet.Mvc [Fact] public async Task XmlDataContractSerializerFormatterThrowsWhenReaderQuotasAreChanged() { + if (TestPlatformHelper.IsMono) + { + // ReaderQuotas are not honored on Mono + return; + } + // Arrange var input = "" + "test" + @@ -244,6 +257,11 @@ namespace Microsoft.AspNet.Mvc public async Task XmlDataContractSerializerFormatterThrowsOnInvalidCharacters() { // Arrange + var expectedException = TestPlatformHelper.IsMono ? typeof(SerializationException) : + typeof(XmlException); + var expectedMessage = TestPlatformHelper.IsMono ? + "Expected element 'TestLevelTwo' in namespace '', but found Element node 'DummyClass' in namespace ''" : + "The encoding in the declaration 'UTF-8' does not match the encoding of the document 'utf-16LE'."; var inpStart = Encodings.UTF16EncodingLittleEndian.GetBytes("" + ""); byte[] inp = { 192, 193 }; @@ -258,7 +276,8 @@ namespace Microsoft.AspNet.Mvc var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); // Act - await Assert.ThrowsAsync(typeof(XmlException), async () => await formatter.ReadAsync(context)); + var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context)); + Assert.Equal(expectedMessage, ex.Message); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs index 511f74824e..014dd11cc7 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlDataContractSerializerOutputFormatterTests.cs @@ -57,8 +57,8 @@ namespace Microsoft.AspNet.Mvc.Core "" + "10" }; yield return new object[] { new Dictionary() { { "Hello", "World" } }, - "" + + "" + "HelloWorld" }; } } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerInputFormatterTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerInputFormatterTests.cs index 03ce946bcd..96cd9bd64e 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerInputFormatterTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/Formatters/XmlSerializerInputFormatterTests.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using System.Xml; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Testing; using Moq; using Xunit; @@ -180,6 +181,12 @@ namespace Microsoft.AspNet.Mvc [Fact] public async Task XmlSerializerFormatterThrowsOnExceededMaxDepth() { + if (TestPlatformHelper.IsMono) + { + // ReaderQuotas are not honored on Mono + return; + } + // Arrange var input = "" + "test" + @@ -193,12 +200,18 @@ namespace Microsoft.AspNet.Mvc var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); // Act & Assert - await Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await formatter.ReadAsync(context)); + await Assert.ThrowsAsync(typeof(InvalidOperationException), () => formatter.ReadAsync(context)); } [Fact] public async Task XmlSerializerFormatterThrowsWhenReaderQuotasAreChanged() { + if (TestPlatformHelper.IsMono) + { + // ReaderQuotas are not honored on Mono + return; + } + // Arrange var input = "" + "test" + @@ -212,7 +225,7 @@ namespace Microsoft.AspNet.Mvc var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); // Act & Assert - await Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await formatter.ReadAsync(context)); + await Assert.ThrowsAsync(typeof(InvalidOperationException), () => formatter.ReadAsync(context)); } [Fact] @@ -247,6 +260,12 @@ namespace Microsoft.AspNet.Mvc public async Task XmlSerializerFormatterThrowsOnInvalidCharacters() { // Arrange + var expectedException = TestPlatformHelper.IsMono ? typeof(InvalidOperationException) : + typeof(XmlException); + var expectedMessage = TestPlatformHelper.IsMono ? + "There is an error in XML document." : + "The encoding in the declaration 'UTF-8' does not match the encoding of the document 'utf-16LE'."; + var inpStart = Encodings.UTF16EncodingLittleEndian.GetBytes("" + ""); byte[] inp = { 192, 193 }; @@ -260,8 +279,9 @@ namespace Microsoft.AspNet.Mvc var formatter = new XmlSerializerInputFormatter(); var context = GetInputFormatterContext(contentBytes, typeof(TestLevelTwo)); - // Act - await Assert.ThrowsAsync(typeof(XmlException), async () => await formatter.ReadAsync(context)); + // Act and Assert + var ex = await Assert.ThrowsAsync(expectedException, () => formatter.ReadAsync(context)); + Assert.Equal(expectedMessage, ex.Message); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/MvcOptionsTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/MvcOptionsTests.cs index efcc3f2cbf..5688616085 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/MvcOptionsTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/MvcOptionsTests.cs @@ -17,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Act & Assert var ex = Assert.Throws(() => options.AntiForgeryOptions = null); Assert.Equal("The 'AntiForgeryOptions' property of 'Microsoft.AspNet.Mvc.MvcOptions' must not be null." + - "\r\nParameter name: value", ex.Message); + Environment.NewLine + "Parameter name: value", ex.Message); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs index ff3e76a4cb..1f1beccf00 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ParameterBinding/ModelBindingHelperTest.cs @@ -8,6 +8,7 @@ using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNet.Http; using Microsoft.AspNet.Mvc.ModelBinding; +using Microsoft.AspNet.Testing; using Moq; using Xunit; @@ -50,6 +51,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test public async Task TryUpdateModel_ReturnsFalse_IfModelValidationFails() { // Arrange + var expectedMessage = TestPlatformHelper.IsMono ? "The field MyProperty is invalid." : + "The MyProperty field is required."; var binders = new IModelBinder[] { new TypeConverterModelBinder(), @@ -79,8 +82,8 @@ namespace Microsoft.AspNet.Mvc.Core.Test // Assert Assert.False(result); - Assert.Equal("The MyProperty field is required.", - modelStateDictionary["MyProperty"].Errors[0].ErrorMessage); + var error = Assert.Single(modelStateDictionary["MyProperty"].Errors); + Assert.Equal(expectedMessage, error.ErrorMessage); } [Fact] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs index 4a5b070a2c..2107a0a5a9 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ReflectedActionDescriptorProviderTests.cs @@ -108,7 +108,7 @@ namespace Microsoft.AspNet.Mvc.Test () => provider.GetDescriptors()); // Act - Assert.Equal(expectedExceptionMessage, ex.Message); + VerifyMultiLineError(expectedExceptionMessage, ex.Message); } [Fact] @@ -601,7 +601,7 @@ namespace Microsoft.AspNet.Mvc.Test var ex = Assert.Throws(() => { provider.GetDescriptors(); }); // Assert - Assert.Equal(expectedMessage, ex.Message); + VerifyMultiLineError(expectedMessage, ex.Message); } [Fact] @@ -806,7 +806,7 @@ namespace Microsoft.AspNet.Mvc.Test var exception = Assert.Throws(() => provider.GetDescriptors()); // Assert - Assert.Equal(expectedMessage, exception.Message); + VerifyMultiLineError(expectedMessage, exception.Message); } [Fact] @@ -1190,6 +1190,16 @@ namespace Microsoft.AspNet.Mvc.Test return provider.GetDescriptors(); } + private static void VerifyMultiLineError(string expectedMessage, string actualMessage) + { + // The error message depends on the order of attributes returned by reflection which is not consistent across + // platforms. We'll compare them individually instead. + Assert.Equal(expectedMessage.Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .OrderBy(m => m, StringComparer.Ordinal), + actualMessage.Split(new[] { Environment.NewLine }, StringSplitOptions.None) + .OrderBy(m => m, StringComparer.Ordinal)); + } + private class HttpMethodController { [HttpPost] diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs index 4c0489c459..79ca3f9d17 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/ViewResultTest.cs @@ -125,11 +125,28 @@ namespace Microsoft.AspNet.Mvc.Core.Test Assert.Equal(expected, memoryStream.ToArray()); } + public static IEnumerable ExecuteResultAsync_DoesNotWriteToResponse_OnceExceptionIsThrownData + { + get + { + yield return new object[] { 30, 0 }; + + if (PlatformHelper.IsMono) + { + // The StreamWriter in Mono buffers 2x the buffer size before flushing. + yield return new object[] { ViewResultStreamWriterBufferSize * 2 + 30, ViewResultStreamWriterBufferSize }; + } + else + { + yield return new object[] { ViewResultStreamWriterBufferSize + 30, ViewResultStreamWriterBufferSize }; + } + } + } + // The StreamWriter used by ViewResult an internal buffer and consequently anything written to this buffer // prior to it filling up will not be written to the underlying stream once an exception is thrown. [Theory] - [InlineData(30, 0)] - [InlineData(ViewResultStreamWriterBufferSize + 30, ViewResultStreamWriterBufferSize)] + [MemberData(nameof(ExecuteResultAsync_DoesNotWriteToResponse_OnceExceptionIsThrownData))] public async Task ExecuteResultAsync_DoesNotWriteToResponse_OnceExceptionIsThrown(int writtenLength, int expectedLength) { // Arrange diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/project.json b/test/Microsoft.AspNet.Mvc.Core.Test/project.json index 4cff9a3d9c..69bf78ec69 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/project.json +++ b/test/Microsoft.AspNet.Mvc.Core.Test/project.json @@ -1,6 +1,6 @@ { "compilationOptions": { - "warningsAsErrors": true + "warningsAsErrors": "true" }, "dependencies": { "Microsoft.AspNet.Http": "1.0.0-*",