This repository has been archived by the owner on Dec 14, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Include Functional tests and unit tests Resolves #1653
- Loading branch information
Yishai Galatzer
committed
Feb 3, 2015
1 parent
2c5ae68
commit b9c5019
Showing
7 changed files
with
278 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
76 changes: 76 additions & 0 deletions
76
src/Microsoft.AspNet.Mvc.Core/Formatters/StreamOutputFormatter.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// 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; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
namespace Microsoft.AspNet.Mvc | ||
{ | ||
/// <summary> | ||
/// Always copies the stream to the response, regardless of requested content type. | ||
/// </summary> | ||
public class StreamOutputFormatter : IOutputFormatter | ||
{ | ||
|
||
/// <summary> | ||
/// Echos the <paramref name="contentType"/> if the <paramref name="runtimeType"/> implements | ||
/// <see cref="Stream"/> and <paramref name="contentType"/> is not <c>null</c>. | ||
/// </summary> | ||
/// <param name="declaredType">The declared type for which the supported content types are desired.</param> | ||
/// <param name="runtimeType">The runtime type for which the supported content types are desired.</param> | ||
/// <param name="contentType"> | ||
/// The content type for which the supported content types are desired, or <c>null</c> if any content | ||
/// type can be used. | ||
/// </param> | ||
/// <returns>Content types which are supported by this formatter.</returns> | ||
public IReadOnlyList<MediaTypeHeaderValue> GetSupportedContentTypes( | ||
Type declaredType, | ||
Type runtimeType, | ||
MediaTypeHeaderValue contentType) | ||
{ | ||
if (contentType == null) | ||
{ | ||
return null; | ||
} | ||
|
||
if (runtimeType != null && typeof(Stream).IsAssignableFrom(runtimeType)) | ||
{ | ||
return new[] { contentType }; | ||
} | ||
|
||
return null; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public bool CanWriteResult([NotNull] OutputFormatterContext context, MediaTypeHeaderValue contentType) | ||
{ | ||
// Ignore the passed in content type, if the object is a Stream. | ||
// always return it as a text/plain format. | ||
if (context.Object is Stream) | ||
{ | ||
context.SelectedContentType = contentType; | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/// <inheritdoc /> | ||
public async Task WriteAsync([NotNull] OutputFormatterContext context) | ||
{ | ||
var valueAsStream = ((Stream)context.Object); | ||
|
||
var response = context.ActionContext.HttpContext.Response; | ||
|
||
if (context.SelectedContentType != null) | ||
{ | ||
response.ContentType = context.SelectedContentType.ToString(); | ||
} | ||
|
||
await valueAsStream.CopyToAsync(response.Body); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
test/Microsoft.AspNet.Mvc.Core.Test/Formatters/StreamOutputFormatterTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// 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; | ||
using System.IO; | ||
using Microsoft.AspNet.Mvc; | ||
using Microsoft.Net.Http.Headers; | ||
using Xunit; | ||
|
||
namespace Microsoft.AspNet.Mvc | ||
{ | ||
public class StreamOutputFormatterTest | ||
{ | ||
[InlineData(typeof(Stream), typeof(FileStream), "text/plain", "text/plain")] | ||
[InlineData(typeof(object), typeof(FileStream), "text/plain", "text/plain")] | ||
[InlineData(typeof(object), typeof(MemoryStream), "text/plain", "text/plain")] | ||
[InlineData(typeof(object), typeof(object), "text/plain", null)] | ||
[InlineData(typeof(object), typeof(string), "text/plain", null)] | ||
[InlineData(typeof(object), null, "text/plain", null)] | ||
[InlineData(typeof(IActionResult), null, "text/plain", null)] | ||
[InlineData(typeof(IActionResult), typeof(IActionResult), "text/plain", null)] | ||
[Theory] | ||
public void GetSupportedContentTypes_ReturnsAppropriateValues(Type declaredType, Type runtimeType, | ||
string contentType, string expected) | ||
{ | ||
// Arrange | ||
var formatter = new StreamOutputFormatter(); | ||
var contentTypeHeader = contentType == null ? null : new MediaTypeHeaderValue(contentType); | ||
|
||
// Act | ||
var contentTypes = formatter.GetSupportedContentTypes(declaredType, runtimeType, contentTypeHeader); | ||
|
||
// Assert | ||
if (expected == null) | ||
{ | ||
Assert.Null(contentTypes); | ||
} | ||
else | ||
{ | ||
Assert.Equal(1, contentTypes.Count); | ||
Assert.Equal(expected, contentTypes[0].ToString()); | ||
} | ||
} | ||
|
||
[InlineData(typeof(object))] | ||
[InlineData(typeof(SimplePOCO))] | ||
[InlineData(null)] | ||
[Theory] | ||
public void CanWriteResult_OnlyActsOnStreams(Type type) | ||
{ | ||
// Arrange | ||
var formatter = new StreamOutputFormatter(); | ||
var context = new OutputFormatterContext(); | ||
var contentType = new MediaTypeHeaderValue("text/plain"); | ||
|
||
context.Object = type != null ? Activator.CreateInstance(type) : null; | ||
|
||
// Act | ||
var result = formatter.CanWriteResult(context, contentType); | ||
|
||
// Assert | ||
Assert.False(result); | ||
Assert.Null(context.SelectedContentType); | ||
} | ||
|
||
[Fact] | ||
public void CanWriteResult_SetsContentType() | ||
{ | ||
// Arrange | ||
var formatter = new StreamOutputFormatter(); | ||
var contentType = new MediaTypeHeaderValue("text/plain"); | ||
var context = new OutputFormatterContext(); | ||
context.Object = new MemoryStream(); | ||
|
||
// Act | ||
var result = formatter.CanWriteResult(context, contentType); | ||
|
||
// Assert | ||
Assert.True(result); | ||
Assert.Same(contentType, context.SelectedContentType); | ||
} | ||
|
||
private class SimplePOCO | ||
{ | ||
public int Id { get; set; } | ||
} | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
test/Microsoft.AspNet.Mvc.FunctionalTests/StreamOutputFormatterTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// 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; | ||
using System.Net; | ||
using System.Net.Http.Headers; | ||
using System.Threading.Tasks; | ||
using FormatterWebSite; | ||
using Microsoft.AspNet.Builder; | ||
using Microsoft.AspNet.TestHost; | ||
using Xunit; | ||
|
||
namespace Microsoft.AspNet.Mvc.FunctionalTests | ||
{ | ||
public class StreamOutputFormatterTest | ||
{ | ||
private readonly IServiceProvider _provider = TestHelper.CreateServices(nameof(FormatterWebSite)); | ||
private readonly Action<IApplicationBuilder> _app = new Startup().Configure; | ||
|
||
[InlineData("SimpleMemoryStream", null)] | ||
[InlineData("MemoryStreamWithContentType", "text/html")] | ||
[InlineData("MemoryStreamWithContentTypeFromProduces", "text/plain")] | ||
[InlineData("MemoryStreamWithContentTypeFromProducesWithMultipleValues", "text/html")] | ||
[InlineData("MemoryStreamOverridesContentTypeWithProduces", "text/plain")] | ||
[Theory] | ||
public async Task StreamOutputFormatter_ReturnsAppropriateContentAndContentType(string actionName, string contentType) | ||
{ | ||
// Arrange | ||
var server = TestServer.Create(_provider, _app); | ||
var client = server.CreateClient(); | ||
|
||
// Act | ||
var response = await client.GetAsync("http://localhost/Stream/" + actionName); | ||
var body = await response.Content.ReadAsStringAsync(); | ||
|
||
// Assert | ||
Assert.Equal(contentType, response.Content.Headers.ContentType?.ToString()); | ||
|
||
Assert.Equal("Sample text from a stream", body); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
test/WebSites/FormatterWebSite/Controllers/StreamController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// 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.IO; | ||
using Microsoft.AspNet.Mvc; | ||
using Microsoft.Net.Http.Headers; | ||
|
||
namespace FormatterWebSite | ||
{ | ||
public class StreamController : Controller | ||
{ | ||
[HttpGet] | ||
public Stream SimpleMemoryStream() | ||
{ | ||
return CreateDefaultStream(); | ||
} | ||
|
||
[HttpGet] | ||
public Stream MemoryStreamWithContentType() | ||
{ | ||
Response.ContentType = "text/html"; | ||
return CreateDefaultStream(); | ||
} | ||
|
||
[HttpGet] | ||
[Produces("text/plain")] | ||
public Stream MemoryStreamWithContentTypeFromProduces() | ||
{ | ||
return CreateDefaultStream(); | ||
} | ||
|
||
[HttpGet] | ||
[Produces("text/html", "text/plain")] | ||
public Stream MemoryStreamWithContentTypeFromProducesWithMultipleValues() | ||
{ | ||
return CreateDefaultStream(); | ||
} | ||
|
||
[HttpGet] | ||
[Produces("text/plain")] | ||
public Stream MemoryStreamOverridesContentTypeWithProduces() | ||
{ | ||
// Produces will set a ContentType on the implicit ObjecResult and | ||
// ContentType on response are overriden by content types from ObjectResult. | ||
Response.ContentType = "text/html"; | ||
|
||
return CreateDefaultStream(); | ||
} | ||
|
||
private static Stream CreateDefaultStream() | ||
{ | ||
var stream = new MemoryStream(); | ||
var writer = new StreamWriter(stream); | ||
writer.Write("Sample text from a stream"); | ||
writer.Flush(); | ||
stream.Seek(0, SeekOrigin.Begin); | ||
|
||
return stream; | ||
} | ||
} | ||
} |