sdk-csharp/test/CloudNative.CloudEvents.Uni.../DocumentationSamples.cs

178 lines
6.4 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.AspNetCore;
using CloudNative.CloudEvents.Http;
using CloudNative.CloudEvents.NewtonsoftJson;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Xunit;
namespace CloudNative.CloudEvents.UnitTests
{
/// <summary>
/// Tests for the code in the docs/ directory.
/// The code itself is currently copy/pasted from this file, but at least we have some confidence
/// that it's working code. In the future we can write tooling to extract the code automatically.
/// </summary>
public class DocumentationSamples
{
[Fact]
public async Task HttpRequestMessageRoundtrip()
{
var requestMessage = CreateHttpRequestMessage();
var request = await ConvertHttpRequestMessage(requestMessage);
var cloudEvent = await ParseHttpRequestAsync(request);
Assert.Equal("event-id", cloudEvent.Id);
Assert.Equal("This is CloudEvent data", cloudEvent.Data);
}
private static HttpRequestMessage CreateHttpRequestMessage()
{
// Sample: guide.md#PopulateHttpRequestMessage
CloudEvent cloudEvent = new CloudEvent
{
Id = "event-id",
Type = "event-type",
Source = new Uri("https://cloudevents.io/"),
Time = DateTimeOffset.UtcNow,
DataContentType = "text/plain",
Data = "This is CloudEvent data"
};
CloudEventFormatter formatter = new JsonEventFormatter();
HttpRequestMessage request = new HttpRequestMessage
{
Method = HttpMethod.Post,
Content = cloudEvent.ToHttpContent(ContentMode.Structured, formatter)
};
// End sample
return request;
}
private static async Task<CloudEvent> ParseHttpRequestAsync(HttpRequest request)
{
// Sample: guide.md#ParseHttpRequestMessage
CloudEventFormatter formatter = new JsonEventFormatter();
CloudEvent cloudEvent = await request.ToCloudEventAsync(formatter);
// End sample
return cloudEvent;
}
[Fact]
public async Task GameResultRoundtrip1()
{
var requestMessage = SerializeGameResult();
var request = await ConvertHttpRequestMessage(requestMessage);
var result = await DeserializeGameResult1(request);
Assert.Equal("player1", result.PlayerId);
Assert.Equal("game1", result.GameId);
Assert.Equal(200, result.Score);
}
[Fact]
public async Task GameResultRoundtrip2()
{
var requestMessage = SerializeGameResult();
var request = await ConvertHttpRequestMessage(requestMessage);
var result = await DeserializeGameResult2(request);
Assert.Equal("player1", result.PlayerId);
Assert.Equal("game1", result.GameId);
Assert.Equal(200, result.Score);
}
// Sample: guide.md#GameResult
public class GameResult
{
[JsonProperty("playerId")]
public string? PlayerId { get; set; }
[JsonProperty("gameId")]
public string? GameId { get; set; }
[JsonProperty("score")]
public int Score { get; set; }
}
// End sample
private static HttpRequestMessage SerializeGameResult()
{
// Sample: guide.md#SerializeGameResult
var result = new GameResult
{
PlayerId = "player1",
GameId = "game1",
Score = 200
};
var cloudEvent = new CloudEvent
{
Id = "result-1",
Type = "game.played.v1",
Source = new Uri("/game", UriKind.Relative),
Time = DateTimeOffset.UtcNow,
DataContentType = "application/json",
Data = result
};
var formatter = new JsonEventFormatter();
var request = new HttpRequestMessage
{
Method = HttpMethod.Post,
Content = cloudEvent.ToHttpContent(ContentMode.Binary, formatter)
};
// End sample
return request;
}
private static async Task<GameResult> DeserializeGameResult1(HttpRequest request)
{
// Sample: guide.md#DeserializeGameResult1
CloudEventFormatter formatter = new JsonEventFormatter();
CloudEvent cloudEvent = await request.ToCloudEventAsync(formatter);
JObject dataAsJObject = (JObject) cloudEvent.Data!;
GameResult result = dataAsJObject.ToObject<GameResult>()!;
// End sample
return result;
}
private static async Task<GameResult> DeserializeGameResult2(HttpRequest request)
{
// Sample: guide.md#DeserializeGameResult2
CloudEventFormatter formatter = new JsonEventFormatter<GameResult>();
CloudEvent cloudEvent = await request.ToCloudEventAsync(formatter);
GameResult result = (GameResult) cloudEvent.Data!;
// End sample
return result;
}
private static async Task<HttpRequest> ConvertHttpRequestMessage(HttpRequestMessage message)
{
var request = new DefaultHttpRequest(new DefaultHttpContext());
foreach (var header in message.Headers)
{
request.Headers[header.Key] = header.Value.Single();
}
if (message.Content?.Headers is HttpContentHeaders contentHeaders)
{
foreach (var header in contentHeaders)
{
request.Headers[header.Key] = header.Value.Single();
}
}
var contentBytes = await (message.Content?.ReadAsByteArrayAsync() ?? Task.FromResult(Array.Empty<byte>()));
request.Body = new MemoryStream(contentBytes);
return request;
}
}
}