129 lines
5.8 KiB
C#
129 lines
5.8 KiB
C#
// Copyright 2021 Cloud Native Foundation.
|
|
// Licensed under the Apache 2.0 license.
|
|
// See LICENSE file in the project root for full license information.
|
|
|
|
using CloudNative.CloudEvents.Core;
|
|
using CloudNative.CloudEvents.NewtonsoftJson;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Http.Internal;
|
|
using System;
|
|
using System.IO;
|
|
using System.Net.Mime;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Xunit;
|
|
using static CloudNative.CloudEvents.UnitTests.TestHelpers;
|
|
|
|
namespace CloudNative.CloudEvents.AspNetCore.UnitTests
|
|
{
|
|
public class HttpResponseExtensionsTest
|
|
{
|
|
[Fact]
|
|
public async Task CopyToHttpResponseAsync_BinaryMode()
|
|
{
|
|
var cloudEvent = new CloudEvent
|
|
{
|
|
Data = "plain text",
|
|
DataContentType = "text/plain"
|
|
}.PopulateRequiredAttributes();
|
|
var formatter = new JsonEventFormatter();
|
|
var response = CreateResponse();
|
|
await cloudEvent.CopyToHttpResponseAsync(response, ContentMode.Binary, formatter);
|
|
|
|
var content = GetContent(response);
|
|
Assert.Equal("text/plain", response.ContentType);
|
|
Assert.Equal("plain text", Encoding.UTF8.GetString(content.Span));
|
|
Assert.Equal("1.0", response.Headers["ce-specversion"]);
|
|
Assert.Equal(cloudEvent.Type, response.Headers["ce-type"]);
|
|
Assert.Equal(cloudEvent.Id, response.Headers["ce-id"]);
|
|
Assert.Equal(CloudEventAttributeType.UriReference.Format(cloudEvent.Source!), response.Headers["ce-source"]);
|
|
// There's no data content type header; the content type itself is used for that.
|
|
Assert.False(response.Headers.ContainsKey("ce-datacontenttype"));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CopyToHttpResponseAsync_BinaryDataButNoDataContentType()
|
|
{
|
|
var cloudEvent = new CloudEvent
|
|
{
|
|
Data = new byte[10],
|
|
}.PopulateRequiredAttributes();
|
|
var formatter = new JsonEventFormatter();
|
|
var response = CreateResponse();
|
|
// The formatter doesn't infer the data content type for binary data.
|
|
await Assert.ThrowsAsync<ArgumentException>(() => cloudEvent.CopyToHttpResponseAsync(response, ContentMode.Binary, formatter));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CopyToHttpResponseAsync_NonBinaryDataButNoDataContentType_ContentTypeIsInferred()
|
|
{
|
|
var cloudEvent = new CloudEvent
|
|
{
|
|
Data = "plain text",
|
|
}.PopulateRequiredAttributes();
|
|
var formatter = new JsonEventFormatter();
|
|
var response = CreateResponse();
|
|
await cloudEvent.CopyToHttpResponseAsync(response, ContentMode.Binary, formatter);
|
|
var content = GetContent(response);
|
|
// The formatter infers that it should encode the string as a JSON value (so it includes the double quotes)
|
|
Assert.Equal("application/json", response.ContentType);
|
|
Assert.Equal("\"plain text\"", Encoding.UTF8.GetString(content.Span));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CopyToHttpResponseAsync_BadContentMode()
|
|
{
|
|
var cloudEvent = new CloudEvent().PopulateRequiredAttributes();
|
|
var formatter = new JsonEventFormatter();
|
|
var response = CreateResponse();
|
|
await Assert.ThrowsAsync<ArgumentOutOfRangeException>(() => cloudEvent.CopyToHttpResponseAsync(response, (ContentMode)100, formatter));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CopyToHttpResponseAsync_StructuredMode()
|
|
{
|
|
var cloudEvent = new CloudEvent
|
|
{
|
|
Data = "plain text",
|
|
DataContentType = "text/plain"
|
|
}.PopulateRequiredAttributes();
|
|
var formatter = new JsonEventFormatter();
|
|
var response = CreateResponse();
|
|
await cloudEvent.CopyToHttpResponseAsync(response, ContentMode.Structured, formatter);
|
|
var content = GetContent(response);
|
|
Assert.Equal(MimeUtilities.MediaType + "+json; charset=utf-8", response.ContentType);
|
|
|
|
var parsed = new JsonEventFormatter().DecodeStructuredModeMessage(content, new ContentType(response.ContentType), extensionAttributes: null);
|
|
AssertCloudEventsEqual(cloudEvent, parsed);
|
|
|
|
// We populate headers even though we don't strictly need to; let's validate that.
|
|
Assert.Equal("1.0", response.Headers["ce-specversion"]);
|
|
Assert.Equal(cloudEvent.Type, response.Headers["ce-type"]);
|
|
Assert.Equal(cloudEvent.Id, response.Headers["ce-id"]);
|
|
Assert.Equal(CloudEventAttributeType.UriReference.Format(cloudEvent.Source!), response.Headers["ce-source"]);
|
|
// We don't populate the data content type header
|
|
Assert.False(response.Headers.ContainsKey("ce-datacontenttype"));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task CopyToHttpResponseAsync_Batch()
|
|
{
|
|
var batch = CreateSampleBatch();
|
|
var response = CreateResponse();
|
|
await batch.CopyToHttpResponseAsync(response, new JsonEventFormatter());
|
|
|
|
var content = GetContent(response);
|
|
Assert.Equal(MimeUtilities.BatchMediaType + "+json; charset=utf-8", response.ContentType);
|
|
var parsedBatch = new JsonEventFormatter().DecodeBatchModeMessage(content, new ContentType(response.ContentType), extensionAttributes: null);
|
|
AssertBatchesEqual(batch, parsedBatch);
|
|
}
|
|
|
|
private static HttpResponse CreateResponse() => new DefaultHttpResponse(new DefaultHttpContext()) { Body = new MemoryStream() };
|
|
private static ReadOnlyMemory<byte> GetContent(HttpResponse response)
|
|
{
|
|
response.Body.Position = 0;
|
|
return BinaryDataUtilities.ToReadOnlyMemory(response.Body);
|
|
}
|
|
}
|
|
}
|