From 9c1e2f54a5e8e0a3e5e11996ec419e6e74c81007 Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Fri, 13 Mar 2015 17:11:12 -0700 Subject: [PATCH] [Fixes #2157] Added additional functional tests for TempData --- .../SessionStateTempDataProvider.cs | 6 + .../SessionStateTempDataProviderTest.cs | 1 + .../TempDataTest.cs | 113 ++++++++++++++++++ .../Controllers/HomeController.cs | 24 ++++ 4 files changed, 144 insertions(+) diff --git a/src/Microsoft.AspNet.Mvc.Core/SessionStateTempDataProvider.cs b/src/Microsoft.AspNet.Mvc.Core/SessionStateTempDataProvider.cs index 126b00744a..7152a733cb 100644 --- a/src/Microsoft.AspNet.Mvc.Core/SessionStateTempDataProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/SessionStateTempDataProvider.cs @@ -43,6 +43,12 @@ namespace Microsoft.AspNet.Mvc // If we got it from Session, remove it so that no other request gets it session.Remove(TempDataSessionStateKey); } + else + { + // Since we call Save() after the response has been sent, we need to initialize an empty session + // so that it is established before the headers are sent. + session[TempDataSessionStateKey] = new byte[] { }; + } return tempDataDictionary; } diff --git a/test/Microsoft.AspNet.Mvc.Core.Test/SessionStateTempDataProviderTest.cs b/test/Microsoft.AspNet.Mvc.Core.Test/SessionStateTempDataProviderTest.cs index f2b431cc8e..1c266163d7 100644 --- a/test/Microsoft.AspNet.Mvc.Core.Test/SessionStateTempDataProviderTest.cs +++ b/test/Microsoft.AspNet.Mvc.Core.Test/SessionStateTempDataProviderTest.cs @@ -90,6 +90,7 @@ namespace Microsoft.AspNet.Mvc if (sessionEnabled) { httpContext.Setup(h => h.GetFeature()).Returns(Mock.Of()); + httpContext.Setup(h => h.Session[It.IsAny()]); } return httpContext.Object; } diff --git a/test/Microsoft.AspNet.Mvc.FunctionalTests/TempDataTest.cs b/test/Microsoft.AspNet.Mvc.FunctionalTests/TempDataTest.cs index 2fd81e6f6b..001014e54e 100644 --- a/test/Microsoft.AspNet.Mvc.FunctionalTests/TempDataTest.cs +++ b/test/Microsoft.AspNet.Mvc.FunctionalTests/TempDataTest.cs @@ -18,6 +18,39 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests private readonly Action _app = new TempDataWebSite.Startup().Configure; private readonly Action _configureServices = new TempDataWebSite.Startup().ConfigureServices; + [Fact] + public async Task TempData_PersistsJustForNextRequest() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + var nameValueCollection = new List> + { + new KeyValuePair("value", "Foo"), + }; + var content = new FormUrlEncodedContent(nameValueCollection); + + // Act 1 + var response = await client.PostAsync("/Home/SetTempData", content); + + // Assert 1 + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + // Act 2 + response = await client.SendAsync(GetRequest("Home/GetTempData", response)); + + // Assert 2 + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + var body = await response.Content.ReadAsStringAsync(); + Assert.Equal("Foo", body); + + // Act 3 + response = await client.SendAsync(GetRequest("Home/GetTempData", response)); + + // Assert 3 + Assert.Equal(HttpStatusCode.NoContent, response.StatusCode); + } + [Fact] public async Task ViewRendersTempData() { @@ -38,5 +71,85 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests var body = await response.Content.ReadAsStringAsync(); Assert.Equal("Foo", body); } + + [Fact] + public async Task Redirect_RetainsTempData_EvenIfAccessed() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + var nameValueCollection = new List> + { + new KeyValuePair("value", "Foo"), + }; + var content = new FormUrlEncodedContent(nameValueCollection); + + // Act 1 + var response = await client.PostAsync("/Home/SetTempData", content); + + // Assert 1 + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + // Act 2 + var redirectResponse = await client.SendAsync(GetRequest("/Home/GetTempDataAndRedirect", response)); + + // Assert 2 + Assert.Equal(HttpStatusCode.Redirect, redirectResponse.StatusCode); + + // Act 3 + response = await client.SendAsync(GetRequest(redirectResponse.Headers.Location.ToString(), response)); + + // Assert 3 + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + var body = await response.Content.ReadAsStringAsync(); + Assert.Equal("Foo", body); + } + + [Fact] + public async Task Peek_RetainsTempData() + { + // Arrange + var server = TestHelper.CreateServer(_app, SiteName, _configureServices); + var client = server.CreateClient(); + var nameValueCollection = new List> + { + new KeyValuePair("value", "Foo"), + }; + var content = new FormUrlEncodedContent(nameValueCollection); + + // Act 1 + var response = await client.PostAsync("/Home/SetTempData", content); + + // Assert 1 + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + + // Act 2 + var peekResponse = await client.SendAsync(GetRequest("/Home/PeekTempData", response)); + + // Assert 2 + Assert.Equal(HttpStatusCode.OK, peekResponse.StatusCode); + var body = await peekResponse.Content.ReadAsStringAsync(); + Assert.Equal("Foo", body); + + // Act 3 + var getResponse = await client.SendAsync(GetRequest("/Home/GetTempData", response)); + + // Assert 3 + Assert.Equal(HttpStatusCode.OK, getResponse.StatusCode); + body = await getResponse.Content.ReadAsStringAsync(); + Assert.Equal("Foo", body); + } + + private HttpRequestMessage GetRequest(string path, HttpResponseMessage response) + { + var request = new HttpRequestMessage(HttpMethod.Get, path); + IEnumerable values; + if (response.Headers.TryGetValues("Set-Cookie", out values)) + { + request.Headers.Add("Cookie", values); + } + + return request; + } } } \ No newline at end of file diff --git a/test/WebSites/TempDataWebSite/Controllers/HomeController.cs b/test/WebSites/TempDataWebSite/Controllers/HomeController.cs index 2149b7c257..732a8c269d 100644 --- a/test/WebSites/TempDataWebSite/Controllers/HomeController.cs +++ b/test/WebSites/TempDataWebSite/Controllers/HomeController.cs @@ -17,5 +17,29 @@ namespace TempDataWebSite.Controllers TempData["key"] = value; return View(); } + + public IActionResult SetTempData(string value) + { + TempData["key"] = value; + return Content(value); + } + + public IActionResult GetTempDataAndRedirect() + { + var value = TempData["key"]; + return RedirectToAction("GetTempData"); + } + + public string GetTempData() + { + var value = TempData["key"]; + return value?.ToString(); + } + + public IActionResult PeekTempData() + { + var peekValue = TempData.Peek("key"); + return Content(peekValue.ToString()); + } } }