// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. using System.Text; using Moq; using Xunit; using Assert = Microsoft.TestCommon.AssertEx; namespace System.Web.Mvc.Test { public class JsonResultTest { private static readonly object _jsonData = new object[] { 1, 2, "three", "four" }; private static readonly string _jsonSerializedData = "[1,2,\"three\",\"four\"]"; [Fact] public void PropertyDefaults() { // Act JsonResult result = new JsonResult(); // Assert Assert.Null(result.Data); Assert.Null(result.ContentEncoding); Assert.Null(result.ContentType); Assert.Null(result.MaxJsonLength); Assert.Null(result.RecursionLimit); Assert.Equal(JsonRequestBehavior.DenyGet, result.JsonRequestBehavior); } [Fact] public void EmptyContentTypeRendersDefault() { // Arrange object data = _jsonData; Encoding contentEncoding = Encoding.UTF8; // Arrange expectations Mock mockControllerContext = new Mock(MockBehavior.Strict); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = "application/json").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentEncoding = contentEncoding).Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(_jsonSerializedData)).Verifiable(); JsonResult result = new JsonResult { Data = data, ContentType = String.Empty, ContentEncoding = contentEncoding }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void ExecuteResult() { // Arrange object data = _jsonData; string contentType = "Some content type."; Encoding contentEncoding = Encoding.UTF8; // Arrange expectations Mock mockControllerContext = new Mock(MockBehavior.Strict); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = contentType).Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentEncoding = contentEncoding).Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(_jsonSerializedData)).Verifiable(); JsonResult result = new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void ExecuteResultWithNullContextThrows() { Assert.ThrowsArgumentNull( delegate { new JsonResult().ExecuteResult(null /* context */); }, "context"); } [Fact] public void NullContentIsNotOutput() { // Arrange string contentType = "Some content type."; Encoding contentEncoding = Encoding.UTF8; // Arrange expectations Mock mockControllerContext = new Mock(); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = contentType).Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentEncoding = contentEncoding).Verifiable(); JsonResult result = new JsonResult { ContentType = contentType, ContentEncoding = contentEncoding }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void NullContentEncodingIsNotOutput() { // Arrange object data = _jsonData; string contentType = "Some content type."; // Arrange expectations Mock mockControllerContext = new Mock(MockBehavior.Strict); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = contentType).Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(_jsonSerializedData)).Verifiable(); JsonResult result = new JsonResult { Data = data, ContentType = contentType, }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void NullContentTypeRendersDefault() { // Arrange object data = _jsonData; Encoding contentEncoding = Encoding.UTF8; // Arrange expectations Mock mockControllerContext = new Mock(MockBehavior.Strict); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = "application/json").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentEncoding = contentEncoding).Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(_jsonSerializedData)).Verifiable(); JsonResult result = new JsonResult { Data = data, ContentEncoding = contentEncoding }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void NullMaxJsonLengthDefaultIsUsed() { // Arrange string data = new String('1', 2100000); Mock mockControllerContext = new Mock(); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = "application/json").Verifiable(); JsonResult result = new JsonResult { Data = data }; // Act & Assert Assert.Throws( () => result.ExecuteResult(mockControllerContext.Object), "Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property."); } [Fact] public void MaxJsonLengthIsPassedToSerializer() { // Arrange string data = new String('1', 2100000); string jsonData = "\"" + data + "\""; Mock mockControllerContext = new Mock(); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = "application/json").Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(jsonData)).Verifiable(); JsonResult result = new JsonResult { Data = data, MaxJsonLength = 2200000 }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void RecursionLimitIsPassedToSerilizer() { // Arrange Tuple>> data = new Tuple>>("key1", new Tuple>("key2", new Tuple("key3", "value") ) ); string jsonData = "{\"Item1\":\"key1\",\"Item2\":{\"Item1\":\"key2\",\"Item2\":{\"Item1\":\"key3\",\"Item2\":\"value\"}}}"; Mock mockControllerContext = new Mock(); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = "application/json").Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(jsonData)).Verifiable(); JsonResult result = new JsonResult { Data = data, RecursionLimit = 2 }; // Act & Assert Assert.Throws( () => result.ExecuteResult(mockControllerContext.Object), "RecursionLimit exceeded."); } [Fact] public void NullRecursionLimitDefaultIsUsed() { // Arrange Tuple>> data = new Tuple>>("key1", new Tuple>("key2", new Tuple("key3", "value") ) ); string jsonData = "{\"Item1\":\"key1\",\"Item2\":{\"Item1\":\"key2\",\"Item2\":{\"Item1\":\"key3\",\"Item2\":\"value\"}}}"; Mock mockControllerContext = new Mock(); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("POST").Verifiable(); mockControllerContext.SetupSet(c => c.HttpContext.Response.ContentType = "application/json").Verifiable(); mockControllerContext.Setup(c => c.HttpContext.Response.Write(jsonData)).Verifiable(); JsonResult result = new JsonResult { Data = data }; // Act result.ExecuteResult(mockControllerContext.Object); // Assert mockControllerContext.Verify(); } [Fact] public void GetRequestBlocked() { // Arrange expectations Mock mockControllerContext = new Mock(MockBehavior.Strict); mockControllerContext.SetupGet(c => c.HttpContext.Request.HttpMethod).Returns("GET").Verifiable(); JsonResult result = new JsonResult(); // Act & Assert Assert.Throws( () => result.ExecuteResult(mockControllerContext.Object), "This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet."); mockControllerContext.Verify(); } } }