|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Buffers;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.SignalR.Protocol;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Xunit;
namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol;
using static HubMessageHelpers;
public class NewtonsoftJsonHubProtocolTests : JsonHubProtocolTestsBase
{
protected override IHubProtocol JsonHubProtocol => new NewtonsoftJsonHubProtocol();
protected override IHubProtocol GetProtocolWithOptions(bool useCamelCase, bool ignoreNullValues)
{
var protocolOptions = new NewtonsoftJsonHubProtocolOptions
{
PayloadSerializerSettings = new JsonSerializerSettings()
{
NullValueHandling = ignoreNullValues ? NullValueHandling.Ignore : NullValueHandling.Include,
ContractResolver = useCamelCase ? new CamelCasePropertyNamesContractResolver() : new DefaultContractResolver()
}
};
return new NewtonsoftJsonHubProtocol(Options.Create(protocolOptions));
}
[Theory]
[InlineData("", "Unexpected end when reading JSON.")]
[InlineData("42", "Unexpected JSON Token Type 'Integer'. Expected a JSON Object.")]
[InlineData("{\"type\":\"foo\"}"{\"type\":\"foo\"}", "Expected 'type' to be of type Integer.")]
[InlineData("{\"type\":3,\"invocationId\":\"42\",\"result\":true", "Unexpected end when reading JSON.")]
[InlineData("{\"type\":8,\"sequenceId\":true}"{\"type\":8,\"sequenceId\":true}", "Expected 'sequenceId' to be of type Integer.")]
[InlineData("{\"type\":9,\"sequenceId\":\"value\"}"{\"type\":9,\"sequenceId\":\"value\"}", "Expected 'sequenceId' to be of type Integer.")]
public void CustomInvalidMessages(string input, string expectedMessage)
{
input = Frame(input);
var binder = new TestBinder(Array.Empty<Type>(), typeof(object));
var data = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(input));
var ex = Assert.Throws<InvalidDataException>(() => JsonHubProtocol.TryParseMessage(ref data, binder, out var _));
Assert.Equal(expectedMessage, ex.Message);
}
[Theory]
[MemberData(nameof(CustomProtocolTestDataNames))]
public void CustomWriteMessage(string protocolTestDataName)
{
var testData = CustomProtocolTestData[protocolTestDataName];
var expectedOutput = Frame(testData.Json);
var protocol = GetProtocolWithOptions(testData.UseCamelCase, testData.IgnoreNullValues);
var writer = MemoryBufferWriter.Get();
try
{
protocol.WriteMessage(testData.Message, writer);
var json = Encoding.UTF8.GetString(writer.ToArray());
Assert.Equal(expectedOutput, json);
}
finally
{
MemoryBufferWriter.Return(writer);
}
}
[Theory]
[MemberData(nameof(CustomProtocolTestDataNames))]
public void CustomParseMessage(string protocolTestDataName)
{
var testData = CustomProtocolTestData[protocolTestDataName];
var input = Frame(testData.Json);
var binder = new TestBinder(testData.Message);
var data = new ReadOnlySequence<byte>(Encoding.UTF8.GetBytes(input));
var protocol = GetProtocolWithOptions(testData.UseCamelCase, testData.IgnoreNullValues);
protocol.TryParseMessage(ref data, binder, out var message);
Assert.Equal(testData.Message, message, TestHubMessageEqualityComparer.Instance);
}
public static IDictionary<string, JsonProtocolTestData> CustomProtocolTestData => new[]
{
new JsonProtocolTestData("InvocationMessage_HasFloatArgument", new InvocationMessage(null, "Target", new object[] { 1, "Foo", 2.0f }), true, true, "{\"type\":1,\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"{\"type\":1,\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"),
new JsonProtocolTestData("InvocationMessage_HasHeaders", AddHeaders(TestHeaders, new InvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f })), true, true, "{\"type\":1," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"),
new JsonProtocolTestData("StreamItemMessage_HasFloatItem", new StreamItemMessage("123", 2.0f), true, true, "{\"type\":2,\"invocationId\":\"123\",\"item\":2.0}"{\"type\":2,\"invocationId\":\"123\",\"item\":2.0}"),
new JsonProtocolTestData("CompletionMessage_HasFloatResult", CompletionMessage.WithResult("123", 2.0f), true, true, "{\"type\":3,\"invocationId\":\"123\",\"result\":2.0}"{\"type\":3,\"invocationId\":\"123\",\"result\":2.0}"),
new JsonProtocolTestData("StreamInvocationMessage_HasFloatArgument", new StreamInvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f }), true, true, "{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"{\"type\":4,\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"),
}.ToDictionary(t => t.Name);
public static IEnumerable<object[]> CustomProtocolTestDataNames => CustomProtocolTestData.Keys.Select(name => new object[] { name });
}
|