mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-19 23:41:41 +02:00
Use latest ProtoBufJsonConverter to support WellKnownTypes (#1161)
* Use latest ProtoBufJsonConverter to support WellKnownTypes * Fix * 02 * WireMockServer_WithBodyAsProtoBuf_WithWellKnownTypes * . * extra test * 0.4.0-preview-06 * 7 * <PackageReference Include="ProtoBufJsonConverter" Version="0.4.0-preview-08" /> * Update README.md * <PackageReference Include="ProtoBufJsonConverter" Version="0.4.0-preview-09" /> * <PackageReference Include="ProtoBufJsonConverter" Version="0.4.0" /> * Update README.md
This commit is contained in:
@@ -89,7 +89,7 @@ public class MappingModel
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Data Object which can be used when WithTransformer is used.
|
/// Data Object which can be used when WithTransformer is used.
|
||||||
/// e.g. lookup an path in this object using
|
/// e.g. lookup a path in this object using
|
||||||
/// <example>
|
/// <example>
|
||||||
/// lookup data "1"
|
/// lookup data "1"
|
||||||
/// </example>
|
/// </example>
|
||||||
@@ -105,4 +105,9 @@ public class MappingModel
|
|||||||
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
|
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ProtoDefinition { get; set; }
|
public string? ProtoDefinition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Grpc ProtoDefinitions which are used for this mapping (request and response). [Optional]
|
||||||
|
/// </summary>
|
||||||
|
public string[]? ProtoDefinitions { get; set; }
|
||||||
}
|
}
|
||||||
@@ -137,6 +137,11 @@ public class ResponseModel
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ProtoDefinition { get; set; }
|
public string? ProtoDefinition { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the proto definitions.
|
||||||
|
/// </summary>
|
||||||
|
public string[]? ProtoDefinitions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public class SettingsModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of Grpc ProtoDefinitions which can be used.
|
/// A list of Grpc ProtoDefinitions which can be used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, string>? ProtoDefinitions { get; set; }
|
public Dictionary<string, string[]>? ProtoDefinitions { get; set; }
|
||||||
|
|
||||||
#if NETSTANDARD1_3_OR_GREATER || NET461
|
#if NETSTANDARD1_3_OR_GREATER || NET461
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public interface IBodyData
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the proto definition.
|
/// Gets or sets the proto definition.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<IdOrText>? ProtoDefinition { get; set; }
|
public Func<IdOrTexts>? ProtoDefinition { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
// Copyright © WireMock.Net
|
|
||||||
|
|
||||||
namespace WireMock.Models;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A structure defining an (optional) Id and a Text.
|
|
||||||
/// </summary>
|
|
||||||
public readonly struct IdOrText
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The Id [optional].
|
|
||||||
/// </summary>
|
|
||||||
public string? Id { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Text.
|
|
||||||
/// </summary>
|
|
||||||
public string Text { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// When Id is defined, return the Id, else the Text.
|
|
||||||
/// </summary>
|
|
||||||
public string Value => Id ?? Text;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a IdOrText
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The Id [optional]</param>
|
|
||||||
/// <param name="text">The Text.</param>
|
|
||||||
public IdOrText(string? id, string text)
|
|
||||||
{
|
|
||||||
Id = id;
|
|
||||||
Text = text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
59
src/WireMock.Net.Abstractions/Models/IdOrTexts.cs
Normal file
59
src/WireMock.Net.Abstractions/Models/IdOrTexts.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace WireMock.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A structure defining an (optional) Id and a Text.
|
||||||
|
/// </summary>
|
||||||
|
public readonly struct IdOrTexts
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The Id [optional].
|
||||||
|
/// </summary>
|
||||||
|
public string? Id { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Text.
|
||||||
|
/// </summary>
|
||||||
|
public IReadOnlyList<string> Texts { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a IdOrText
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The Id [optional]</param>
|
||||||
|
/// <param name="text">The Text.</param>
|
||||||
|
public IdOrTexts(string? id, string text) : this(id, [text])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a IdOrText
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The Id [optional]</param>
|
||||||
|
/// <param name="texts">The Texts.</param>
|
||||||
|
public IdOrTexts(string? id, IReadOnlyList<string> texts)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Texts = texts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When Id is defined, return process the Id, else process the Texts.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Callback to process the id.</param>
|
||||||
|
/// <param name="texts">Callback to process the texts.</param>
|
||||||
|
public void Value(Action<string> id, Action<IReadOnlyList<string>> texts)
|
||||||
|
{
|
||||||
|
if (Id != null)
|
||||||
|
{
|
||||||
|
id(Id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
texts(Texts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,16 @@ public static class AnyOfExtensions
|
|||||||
return value.IsFirst ? value.First : value.Second.Pattern;
|
return value.IsFirst ? value.First : value.Second.Pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the patterns.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="values">AnyOf types</param>
|
||||||
|
/// <returns>string values</returns>
|
||||||
|
public static string[] GetPatterns(this AnyOf<string, StringPattern>[] values)
|
||||||
|
{
|
||||||
|
return values.Select(GetPattern).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a string-patterns to AnyOf patterns.
|
/// Converts a string-patterns to AnyOf patterns.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public interface IMapping
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
|
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IdOrText? ProtoDefinition { get; }
|
IdOrTexts? ProtoDefinition { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ProvideResponseAsync
|
/// ProvideResponseAsync
|
||||||
@@ -175,26 +175,7 @@ public interface IMapping
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Define a Grpc ProtoDefinition which is used for this mapping (request and response).
|
/// Define a Grpc ProtoDefinition which is used for this mapping (request and response).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="protoDefinition">The proto definition as text.</param>
|
/// <param name="protoDefinition">The proto definitions as id or text.</param>
|
||||||
/// <returns>The <see cref="IMapping"/>.</returns>
|
/// <returns>The <see cref="IMapping"/>.</returns>
|
||||||
IMapping WithProtoDefinition(IdOrText protoDefinition);
|
IMapping WithProtoDefinition(IdOrTexts protoDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
executionConditionState">State in which the current mapping can occur. [Optional]
|
|
||||||
nextState">The next state which will occur after the current mapping execution. [Optional]
|
|
||||||
stateTimes">Only when the current state is executed this number, the next state which will occur. [Optional]
|
|
||||||
webhooks">The Webhooks. [Optional]
|
|
||||||
useWebhooksFireAndForget">Use Fire and Forget for the defined webhook(s). [Optional]
|
|
||||||
timeSettings">The TimeSettings. [Optional]
|
|
||||||
data">The data object. [Optional]
|
|
||||||
|
|
||||||
|
|
||||||
string? executionConditionState,
|
|
||||||
string? nextState,
|
|
||||||
int? stateTimes,
|
|
||||||
IWebhook[]? webhooks,
|
|
||||||
bool? useWebhooksFireAndForget,
|
|
||||||
ITimeSettings? timeSettings,
|
|
||||||
object? data,
|
|
||||||
*/
|
|
||||||
@@ -82,7 +82,7 @@ public class Mapping : IMapping
|
|||||||
public double? Probability { get; private set; }
|
public double? Probability { get; private set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IdOrText? ProtoDefinition { get; private set; }
|
public IdOrTexts? ProtoDefinition { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
/// Initializes a new instance of the <see cref="Mapping"/> class.
|
||||||
@@ -189,7 +189,7 @@ public class Mapping : IMapping
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IMapping WithProtoDefinition(IdOrText protoDefinition)
|
public IMapping WithProtoDefinition(IdOrTexts protoDefinition)
|
||||||
{
|
{
|
||||||
ProtoDefinition = protoDefinition;
|
ProtoDefinition = protoDefinition;
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using ProtoBufJsonConverter;
|
using ProtoBufJsonConverter;
|
||||||
@@ -25,9 +26,9 @@ public class ProtoBufMatcher : IProtoBufMatcher
|
|||||||
public MatchBehaviour MatchBehaviour { get; }
|
public MatchBehaviour MatchBehaviour { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Func to define The proto definition as text.
|
/// The Func to define the proto definition as id or texts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<IdOrText> ProtoDefinition { get; }
|
public Func<IdOrTexts> ProtoDefinition { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
/// The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
|
||||||
@@ -44,12 +45,12 @@ public class ProtoBufMatcher : IProtoBufMatcher
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ProtoBufMatcher"/> class.
|
/// Initializes a new instance of the <see cref="ProtoBufMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="protoDefinition">The proto definition.</param>
|
/// <param name="protoDefinition">The proto definition as id or text.</param>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||||
/// <param name="matcher">The optional jsonMatcher to use to match the ProtoBuf as (json) object.</param>
|
/// <param name="matcher">The optional jsonMatcher to use to match the ProtoBuf as (json) object.</param>
|
||||||
public ProtoBufMatcher(
|
public ProtoBufMatcher(
|
||||||
Func<IdOrText> protoDefinition,
|
Func<IdOrTexts> protoDefinition,
|
||||||
string messageType,
|
string messageType,
|
||||||
MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch,
|
MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch,
|
||||||
IObjectMatcher? matcher = null
|
IObjectMatcher? matcher = null
|
||||||
@@ -102,7 +103,11 @@ public class ProtoBufMatcher : IProtoBufMatcher
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = new ConvertToObjectRequest(ProtoDefinition().Text, MessageType, input);
|
var protoDefinitions = ProtoDefinition().Texts;
|
||||||
|
|
||||||
|
var resolver = new WireMockProtoFileResolver(protoDefinitions);
|
||||||
|
var request = new ConvertToObjectRequest(protoDefinitions[0], MessageType, input)
|
||||||
|
.WithProtoFileResolver(resolver);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ public class RequestMessageProtoBufMatcher : IRequestMatcher
|
|||||||
/// Initializes a new instance of the <see cref="RequestMessageProtoBufMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageProtoBufMatcher"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||||
/// <param name="protoDefinition">The Func to define The proto definition as text.</param>
|
/// <param name="protoDefinition">The Func to define the proto definitions as id or text.</param>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
/// <param name="matcher">The optional matcher to use to match the ProtoBuf as (json) object.</param>
|
/// <param name="matcher">The optional matcher to use to match the ProtoBuf as (json) object.</param>
|
||||||
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, Func<IdOrText> protoDefinition, string messageType, IObjectMatcher? matcher = null)
|
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, Func<IdOrTexts> protoDefinition, string messageType, IObjectMatcher? matcher = null)
|
||||||
{
|
{
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
Matcher = new ProtoBufMatcher(protoDefinition, messageType, matchBehaviour, matcher);
|
Matcher = new ProtoBufMatcher(protoDefinition, messageType, matchBehaviour, matcher);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class BodyData : IBodyData
|
|||||||
|
|
||||||
#region ProtoBuf
|
#region ProtoBuf
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Func<IdOrText>? ProtoDefinition { get; set; }
|
public Func<IdOrTexts>? ProtoDefinition { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string? ProtoBufMessageType { get; set; }
|
public string? ProtoBufMessageType { get; set; }
|
||||||
|
|||||||
@@ -151,8 +151,8 @@ namespace WireMock.Owin.Mappers
|
|||||||
|
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
case BodyType.ProtoBuf:
|
case BodyType.ProtoBuf:
|
||||||
var protoDefinition = bodyData.ProtoDefinition?.Invoke().Text;
|
var protoDefinitions = bodyData.ProtoDefinition?.Invoke().Texts;
|
||||||
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinition, bodyData.ProtoBufMessageType, bodyData.BodyAsJson).ConfigureAwait(false);
|
return await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(protoDefinitions, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson).ConfigureAwait(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case BodyType.Bytes:
|
case BodyType.Bytes:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders;
|
namespace WireMock.RequestBuilders;
|
||||||
@@ -10,7 +11,7 @@ namespace WireMock.RequestBuilders;
|
|||||||
public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
|
public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithGrpcProto
|
/// WithBodyAsProtoBuf
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="protoDefinition">The proto definition as text.</param>
|
/// <param name="protoDefinition">The proto definition as text.</param>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
@@ -19,7 +20,7 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
|
|||||||
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithGrpcProto
|
/// WithBodyAsProtoBuf
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="protoDefinition">The proto definition as text.</param>
|
/// <param name="protoDefinition">The proto definition as text.</param>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
@@ -29,7 +30,26 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
|
|||||||
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithGrpcProto
|
/// WithBodyAsProtoBuf
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="protoDefinitions">The proto definitions as text.</param>
|
||||||
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
|
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||||
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
|
IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBodyAsProtoBuf
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="protoDefinitions">The proto definitions as text.</param>
|
||||||
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
|
/// <param name="matcher">The matcher to use to match the ProtoBuf as (json) object.</param>
|
||||||
|
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||||
|
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||||
|
IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBodyAsProtoBuf
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
|
||||||
@@ -37,7 +57,7 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
|
|||||||
IRequestBuilder WithBodyAsProtoBuf(string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
IRequestBuilder WithBodyAsProtoBuf(string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithGrpcProto
|
/// WithBodyAsProtoBuf
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
/// <param name="matcher">The matcher to use to match the ProtoBuf as (json) object.</param>
|
/// <param name="matcher">The matcher to use to match the ProtoBuf as (json) object.</param>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
|
using WireMock.Models;
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders;
|
namespace WireMock.RequestBuilders;
|
||||||
|
|
||||||
@@ -10,13 +13,25 @@ public partial class Request
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||||
{
|
{
|
||||||
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new (null, protoDefinition), messageType));
|
return WithBodyAsProtoBuf([ protoDefinition ], messageType, matchBehaviour);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||||
{
|
{
|
||||||
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new(null, protoDefinition), messageType, matcher));
|
return WithBodyAsProtoBuf([protoDefinition], messageType, matcher, matchBehaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||||
|
{
|
||||||
|
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new IdOrTexts(null, protoDefinitions), messageType));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IRequestBuilder WithBodyAsProtoBuf(IReadOnlyList<string> protoDefinitions, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||||
|
{
|
||||||
|
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => new IdOrTexts(null, protoDefinitions), messageType, matcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JsonConverter.Abstractions;
|
using JsonConverter.Abstractions;
|
||||||
@@ -109,7 +110,7 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
|
|||||||
IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter jsonConverter, JsonConverterOptions? options = null);
|
IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter jsonConverter, JsonConverterOptions? options = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithBody : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
|
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="protoDefinition">The proto definition as text.</param>
|
/// <param name="protoDefinition">The proto definition as text.</param>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
@@ -126,7 +127,24 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// WithBody : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
|
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on proto definitions, message type and the value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="protoDefinitions">The proto definition as text.</param>
|
||||||
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
|
/// <param name="value">The object to convert to protobuf byte[].</param>
|
||||||
|
/// <param name="jsonConverter">The <see cref="IJsonConverter"/> [optional]. Default value is NewtonsoftJsonConverter.</param>
|
||||||
|
/// <param name="options">The <see cref="JsonConverterOptions"/> [optional].</param>
|
||||||
|
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||||
|
IResponseBuilder WithBodyAsProtoBuf(
|
||||||
|
IReadOnlyList<string> protoDefinitions,
|
||||||
|
string messageType,
|
||||||
|
object value,
|
||||||
|
IJsonConverter? jsonConverter = null,
|
||||||
|
JsonConverterOptions? options = null
|
||||||
|
);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// WithBodyAsProtoBuf : Create a ProtoBuf byte[] response based on a proto definition, message type and the value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
/// <param name="messageType">The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".</param>
|
||||||
/// <param name="value">The object to convert to protobuf byte[].</param>
|
/// <param name="value">The object to convert to protobuf byte[].</param>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JsonConverter.Abstractions;
|
using JsonConverter.Abstractions;
|
||||||
using Stef.Validation;
|
using Stef.Validation;
|
||||||
using WireMock.Exceptions;
|
using WireMock.Exceptions;
|
||||||
|
using WireMock.Models;
|
||||||
using WireMock.Types;
|
using WireMock.Types;
|
||||||
using WireMock.Util;
|
using WireMock.Util;
|
||||||
|
|
||||||
@@ -223,7 +225,19 @@ public partial class Response
|
|||||||
JsonConverterOptions? options = null
|
JsonConverterOptions? options = null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Guard.NotNullOrWhiteSpace(protoDefinition);
|
return WithBodyAsProtoBuf([protoDefinition], messageType, value, jsonConverter, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public IResponseBuilder WithBodyAsProtoBuf(
|
||||||
|
IReadOnlyList<string> protoDefinitions,
|
||||||
|
string messageType,
|
||||||
|
object value,
|
||||||
|
IJsonConverter? jsonConverter = null,
|
||||||
|
JsonConverterOptions? options = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Guard.NotNullOrEmpty(protoDefinitions);
|
||||||
Guard.NotNullOrWhiteSpace(messageType);
|
Guard.NotNullOrWhiteSpace(messageType);
|
||||||
Guard.NotNull(value);
|
Guard.NotNull(value);
|
||||||
|
|
||||||
@@ -235,7 +249,7 @@ public partial class Response
|
|||||||
{
|
{
|
||||||
DetectedBodyType = BodyType.ProtoBuf,
|
DetectedBodyType = BodyType.ProtoBuf,
|
||||||
BodyAsJson = value,
|
BodyAsJson = value,
|
||||||
ProtoDefinition = () => new (null, protoDefinition),
|
ProtoDefinition = () => new IdOrTexts(null, protoDefinitions),
|
||||||
ProtoBufMessageType = messageType
|
ProtoBufMessageType = messageType
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -273,7 +273,6 @@ internal class MappingConverter(MatcherMapper mapper)
|
|||||||
WhenStateIs = mapping.ExecutionConditionState,
|
WhenStateIs = mapping.ExecutionConditionState,
|
||||||
SetStateTo = mapping.NextState,
|
SetStateTo = mapping.NextState,
|
||||||
Data = mapping.Data,
|
Data = mapping.Data,
|
||||||
ProtoDefinition = mapping.ProtoDefinition?.Value,
|
|
||||||
Probability = mapping.Probability,
|
Probability = mapping.Probability,
|
||||||
Request = new RequestModel
|
Request = new RequestModel
|
||||||
{
|
{
|
||||||
@@ -304,6 +303,20 @@ internal class MappingConverter(MatcherMapper mapper)
|
|||||||
Response = new ResponseModel()
|
Response = new ResponseModel()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mapping.ProtoDefinition?.Value(
|
||||||
|
id => mappingModel.ProtoDefinition = id,
|
||||||
|
texts =>
|
||||||
|
{
|
||||||
|
if (texts.Count == 1)
|
||||||
|
{
|
||||||
|
mappingModel.ProtoDefinition = texts[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mappingModel.ProtoDefinitions = texts.ToArray();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (methodMatcher != null)
|
if (methodMatcher != null)
|
||||||
{
|
{
|
||||||
mappingModel.Request.Methods = methodMatcher.Methods;
|
mappingModel.Request.Methods = methodMatcher.Methods;
|
||||||
@@ -491,10 +504,22 @@ internal class MappingConverter(MatcherMapper mapper)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BodyType.ProtoBuf:
|
case BodyType.ProtoBuf:
|
||||||
// If the ProtoDefinition is not defined at the MappingModel, get the ProtoDefinition from the ResponseMessage.
|
// If the ProtoDefinition(s) is/are not defined at the MappingModel, get the ProtoDefinition(s) from the ResponseMessage.
|
||||||
if (mappingModel.ProtoDefinition == null)
|
if (mappingModel.ProtoDefinition == null && mappingModel.ProtoDefinitions == null)
|
||||||
{
|
{
|
||||||
mappingModel.Response.ProtoDefinition = response.ResponseMessage.BodyData.ProtoDefinition?.Invoke().Value;
|
response.ResponseMessage.BodyData.ProtoDefinition?.Invoke().Value(
|
||||||
|
id => mappingModel.Response.ProtoDefinition = id,
|
||||||
|
texts =>
|
||||||
|
{
|
||||||
|
if (texts.Count == 1)
|
||||||
|
{
|
||||||
|
mappingModel.Response.ProtoDefinition = texts[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mappingModel.Response.ProtoDefinitions = texts.ToArray();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
mappingModel.Response.ProtoBufMessageType = response.ResponseMessage.BodyData.ProtoBufMessageType;
|
mappingModel.Response.ProtoBufMessageType = response.ResponseMessage.BodyData.ProtoBufMessageType;
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ internal class MatcherMapper
|
|||||||
|
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
case nameof(ProtoBufMatcher):
|
case nameof(ProtoBufMatcher):
|
||||||
return CreateProtoBufMatcher(matchBehaviour, stringPatterns[0].GetPattern(), matcherModel);
|
return CreateProtoBufMatcher(matchBehaviour, stringPatterns.GetPatterns(), matcherModel);
|
||||||
#endif
|
#endif
|
||||||
case nameof(RegexMatcher):
|
case nameof(RegexMatcher):
|
||||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, useRegexExtended, matchOperator);
|
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, useRegexExtended, matchOperator);
|
||||||
@@ -211,7 +211,18 @@ internal class MatcherMapper
|
|||||||
|
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
case ProtoBufMatcher protoBufMatcher:
|
case ProtoBufMatcher protoBufMatcher:
|
||||||
model.Pattern = protoBufMatcher.ProtoDefinition().Value;
|
protoBufMatcher.ProtoDefinition().Value(id => model.Pattern = id, texts =>
|
||||||
|
{
|
||||||
|
if (texts.Count == 1)
|
||||||
|
{
|
||||||
|
model.Pattern = texts[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
model.Patterns = texts.Cast<object>().ToArray();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
model.ProtoBufMessageType = protoBufMatcher.MessageType;
|
model.ProtoBufMessageType = protoBufMatcher.MessageType;
|
||||||
model.ContentMatcher = Map(protoBufMatcher.Matcher);
|
model.ContentMatcher = Map(protoBufMatcher.Matcher);
|
||||||
break;
|
break;
|
||||||
@@ -278,22 +289,30 @@ internal class MatcherMapper
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, string protoDefinitionOrId, MatcherModel matcher)
|
private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, IReadOnlyList<string> protoDefinitions, MatcherModel matcher)
|
||||||
{
|
{
|
||||||
var objectMatcher = Map(matcher.ContentMatcher) as IObjectMatcher;
|
var objectMatcher = Map(matcher.ContentMatcher) as IObjectMatcher;
|
||||||
|
|
||||||
IdOrText protoDefinition;
|
IdOrTexts protoDefinitionAsIdOrTexts;
|
||||||
if (_settings.ProtoDefinitions?.TryGetValue(protoDefinitionOrId, out var protoDefinitionFromSettings) == true)
|
if (protoDefinitions.Count == 1)
|
||||||
{
|
{
|
||||||
protoDefinition = new(protoDefinitionOrId, protoDefinitionFromSettings);
|
var idOrText = protoDefinitions[0];
|
||||||
|
if (_settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitionFromSettings) == true)
|
||||||
|
{
|
||||||
|
protoDefinitionAsIdOrTexts = new(idOrText, protoDefinitionFromSettings);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
protoDefinitionAsIdOrTexts = new(null, protoDefinitions);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
protoDefinition = new(null, protoDefinitionOrId);
|
protoDefinitionAsIdOrTexts = new(null, protoDefinitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ProtoBufMatcher(
|
return new ProtoBufMatcher(
|
||||||
() => protoDefinition,
|
() => protoDefinitionAsIdOrTexts,
|
||||||
matcher!.ProtoBufMessageType!,
|
matcher!.ProtoBufMessageType!,
|
||||||
matchBehaviour ?? MatchBehaviour.AcceptOnMatch,
|
matchBehaviour ?? MatchBehaviour.AcceptOnMatch,
|
||||||
objectMatcher
|
objectMatcher
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ public interface IRespondWithAProvider
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="protoDefinitionOrId">The proto definition as text or as id.</param>
|
/// <param name="protoDefinitionOrId">The proto definition as text or as id.</param>
|
||||||
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
|
||||||
IRespondWithAProvider WithProtoDefinition(string protoDefinitionOrId);
|
IRespondWithAProvider WithProtoDefinition(params string[] protoDefinitionOrId);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Define a GraphQL Schema which is used for the request and the response.
|
/// Define a GraphQL Schema which is used for the request and the response.
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
|||||||
private int _timesInSameState = 1;
|
private int _timesInSameState = 1;
|
||||||
private bool? _useWebhookFireAndForget;
|
private bool? _useWebhookFireAndForget;
|
||||||
private double? _probability;
|
private double? _probability;
|
||||||
private IdOrText? _protoDefinition;
|
private IdOrTexts? _protoDefinition;
|
||||||
private GraphQLSchemaDetails? _graphQLSchemaDetails;
|
private GraphQLSchemaDetails? _graphQLSchemaDetails;
|
||||||
|
|
||||||
public Guid Guid { get; private set; }
|
public Guid Guid { get; private set; }
|
||||||
@@ -351,18 +351,27 @@ internal class RespondWithAProvider : IRespondWithAProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IRespondWithAProvider WithProtoDefinition(string protoDefinitionOrId)
|
public IRespondWithAProvider WithProtoDefinition(params string[] protoDefinitionOrId)
|
||||||
{
|
{
|
||||||
Guard.NotNullOrWhiteSpace(protoDefinitionOrId);
|
Guard.NotNull(protoDefinitionOrId);
|
||||||
|
|
||||||
if (_settings.ProtoDefinitions?.TryGetValue(protoDefinitionOrId, out var protoDefinition) == true)
|
if (protoDefinitionOrId.Length == 1)
|
||||||
{
|
{
|
||||||
_protoDefinition = new (protoDefinitionOrId, protoDefinition);
|
var idOrText = protoDefinitionOrId[0];
|
||||||
|
if (_settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitions) == true)
|
||||||
|
{
|
||||||
|
_protoDefinition = new(idOrText, protoDefinitions);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_protoDefinition = new(null, protoDefinitionOrId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_protoDefinition = new(null, protoDefinitionOrId);
|
_protoDefinition = new(null, protoDefinitionOrId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -595,12 +595,12 @@ public partial class WireMockServer : IWireMockServer
|
|||||||
/// <param name="protoDefinition">The ProtoDefinition as text.</param>
|
/// <param name="protoDefinition">The ProtoDefinition as text.</param>
|
||||||
/// <returns><see cref="WireMockServer"/></returns>
|
/// <returns><see cref="WireMockServer"/></returns>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public WireMockServer AddProtoDefinition(string id, string protoDefinition)
|
public WireMockServer AddProtoDefinition(string id, params string[] protoDefinition)
|
||||||
{
|
{
|
||||||
Guard.NotNullOrWhiteSpace(id);
|
Guard.NotNullOrWhiteSpace(id);
|
||||||
Guard.NotNullOrWhiteSpace(protoDefinition);
|
Guard.NotNullOrEmpty(protoDefinition);
|
||||||
|
|
||||||
_settings.ProtoDefinitions ??= new Dictionary<string, string>();
|
_settings.ProtoDefinitions ??= new Dictionary<string, string[]>();
|
||||||
|
|
||||||
_settings.ProtoDefinitions[id] = protoDefinition;
|
_settings.ProtoDefinitions[id] = protoDefinition;
|
||||||
|
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ public class WireMockServerSettings
|
|||||||
public IDictionary<string, Func<MatcherModel, IMatcher>>? CustomMatcherMappings { get; set; }
|
public IDictionary<string, Func<MatcherModel, IMatcher>>? CustomMatcherMappings { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="JsonSerializerSettings"/> used when the a JSON response is generated.
|
/// The <see cref="JsonSerializerSettings"/> used when the JSON response is generated.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI, JsonIgnore]
|
[PublicAPI, JsonIgnore]
|
||||||
public JsonSerializerSettings? JsonSerializerSettings { get; set; }
|
public JsonSerializerSettings? JsonSerializerSettings { get; set; }
|
||||||
@@ -315,7 +315,7 @@ public class WireMockServerSettings
|
|||||||
/// A list of Grpc ProtoDefinitions which can be used.
|
/// A list of Grpc ProtoDefinitions which can be used.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public Dictionary<string, string>? ProtoDefinitions { get; set; }
|
public Dictionary<string, string[]>? ProtoDefinitions { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of GraphQL Schemas which can be used.
|
/// A list of GraphQL Schemas which can be used.
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public static class WireMockServerSettingsParser
|
|||||||
HandleRequestsSynchronously = parser.GetBoolValue(nameof(WireMockServerSettings.HandleRequestsSynchronously)),
|
HandleRequestsSynchronously = parser.GetBoolValue(nameof(WireMockServerSettings.HandleRequestsSynchronously)),
|
||||||
HostingScheme = parser.GetEnumValue<HostingScheme>(nameof(WireMockServerSettings.HostingScheme)),
|
HostingScheme = parser.GetEnumValue<HostingScheme>(nameof(WireMockServerSettings.HostingScheme)),
|
||||||
MaxRequestLogCount = parser.GetIntValue(nameof(WireMockServerSettings.MaxRequestLogCount)),
|
MaxRequestLogCount = parser.GetIntValue(nameof(WireMockServerSettings.MaxRequestLogCount)),
|
||||||
ProtoDefinitions = parser.GetObjectValueFromJson<Dictionary<string, string>>(nameof(settings.ProtoDefinitions)),
|
ProtoDefinitions = parser.GetObjectValueFromJson<Dictionary<string, string[]>>(nameof(settings.ProtoDefinitions)),
|
||||||
QueryParameterMultipleValueSupport = parser.GetEnumValue<QueryParameterMultipleValueSupport>(nameof(WireMockServerSettings.QueryParameterMultipleValueSupport)),
|
QueryParameterMultipleValueSupport = parser.GetEnumValue<QueryParameterMultipleValueSupport>(nameof(WireMockServerSettings.QueryParameterMultipleValueSupport)),
|
||||||
ReadStaticMappings = parser.GetBoolValue(nameof(WireMockServerSettings.ReadStaticMappings)),
|
ReadStaticMappings = parser.GetBoolValue(nameof(WireMockServerSettings.ReadStaticMappings)),
|
||||||
RequestLogExpirationDuration = parser.GetIntValue(nameof(WireMockServerSettings.RequestLogExpirationDuration)),
|
RequestLogExpirationDuration = parser.GetIntValue(nameof(WireMockServerSettings.RequestLogExpirationDuration)),
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright © WireMock.Net
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
#if PROTOBUF
|
#if PROTOBUF
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JsonConverter.Abstractions;
|
using JsonConverter.Abstractions;
|
||||||
@@ -13,31 +13,25 @@ namespace WireMock.Util;
|
|||||||
internal static class ProtoBufUtils
|
internal static class ProtoBufUtils
|
||||||
{
|
{
|
||||||
internal static async Task<byte[]> GetProtoBufMessageWithHeaderAsync(
|
internal static async Task<byte[]> GetProtoBufMessageWithHeaderAsync(
|
||||||
string? protoDefinition,
|
IReadOnlyList<string>? protoDefinitions,
|
||||||
string? messageType,
|
string? messageType,
|
||||||
object? value,
|
object? value,
|
||||||
IJsonConverter? jsonConverter = null,
|
IJsonConverter? jsonConverter = null,
|
||||||
JsonConverterOptions? options = null,
|
|
||||||
CancellationToken cancellationToken = default
|
CancellationToken cancellationToken = default
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(protoDefinition) || string.IsNullOrWhiteSpace(messageType) || value is null)
|
if (protoDefinitions == null || string.IsNullOrWhiteSpace(messageType) || value is null)
|
||||||
{
|
{
|
||||||
return Array.Empty<byte>();
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = new ConvertToProtoBufRequest(protoDefinition, messageType, value, true);
|
var resolver = new WireMockProtoFileResolver(protoDefinitions);
|
||||||
|
var request = new ConvertToProtoBufRequest(protoDefinitions[0], messageType, value, true)
|
||||||
|
.WithProtoFileResolver(resolver);
|
||||||
|
|
||||||
if (jsonConverter != null)
|
return await SingletonFactory<Converter>
|
||||||
{
|
.GetInstance()
|
||||||
request = request.WithJsonConverter(jsonConverter);
|
.ConvertAsync(request, cancellationToken).ConfigureAwait(false);
|
||||||
if (options != null)
|
|
||||||
{
|
|
||||||
request = request.WithJsonConverterOptions(options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return await SingletonFactory<Converter>.GetInstance().ConvertAsync(request, cancellationToken).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
46
src/WireMock.Net/Util/WireMockProtoFileResolver.cs
Normal file
46
src/WireMock.Net/Util/WireMockProtoFileResolver.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Copyright © WireMock.Net
|
||||||
|
|
||||||
|
#if PROTOBUF
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using ProtoBufJsonConverter;
|
||||||
|
using Stef.Validation;
|
||||||
|
|
||||||
|
namespace WireMock.Util;
|
||||||
|
|
||||||
|
internal class WireMockProtoFileResolver : IProtoFileResolver
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, string> _files = new();
|
||||||
|
|
||||||
|
public WireMockProtoFileResolver(IReadOnlyCollection<string> protoDefinitions)
|
||||||
|
{
|
||||||
|
if (Guard.NotNullOrEmpty(protoDefinitions).Count() > 1)
|
||||||
|
{
|
||||||
|
foreach (var extraProtoDefinition in protoDefinitions.Skip(1))
|
||||||
|
{
|
||||||
|
var firstNonEmptyLine = extraProtoDefinition.Split(['\r', '\n']).FirstOrDefault(l => !string.IsNullOrEmpty(l));
|
||||||
|
if (firstNonEmptyLine != null)
|
||||||
|
{
|
||||||
|
_files.Add(firstNonEmptyLine.TrimStart(['\r', '\n', '/', ' ']), extraProtoDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Exists(string path)
|
||||||
|
{
|
||||||
|
return _files.ContainsKey(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextReader OpenText(string path)
|
||||||
|
{
|
||||||
|
if (_files.TryGetValue(path, out var extraProtoDefinition))
|
||||||
|
{
|
||||||
|
return new StringReader(extraProtoDefinition);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FileNotFoundException($"The ProtoDefinition '{path}' was not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
<PackageReference Include="GraphQL" Version="7.5.0" />
|
<PackageReference Include="GraphQL" Version="7.5.0" />
|
||||||
<PackageReference Include="GraphQL.NewtonsoftJson" Version="7.5.0" />
|
<PackageReference Include="GraphQL.NewtonsoftJson" Version="7.5.0" />
|
||||||
<PackageReference Include="MimeKitLite" Version="4.1.0.1" />
|
<PackageReference Include="MimeKitLite" Version="4.1.0.1" />
|
||||||
<PackageReference Include="ProtoBufJsonConverter" Version="0.3.0" />
|
<PackageReference Include="ProtoBufJsonConverter" Version="0.4.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||||
|
|||||||
@@ -35,6 +35,69 @@ message HelloRequest {
|
|||||||
message HelloReply {
|
message HelloReply {
|
||||||
string message = 1;
|
string message = 1;
|
||||||
}
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
private const string ProtoDefinitionWithWellKnownTypes = @"
|
||||||
|
syntax = ""proto3"";
|
||||||
|
|
||||||
|
package communication.api.v1;
|
||||||
|
|
||||||
|
import ""google/protobuf/empty.proto"";
|
||||||
|
import ""google/protobuf/timestamp.proto"";
|
||||||
|
import ""google/protobuf/duration.proto"";
|
||||||
|
|
||||||
|
service Greeter {
|
||||||
|
rpc SayNothing (google.protobuf.Empty) returns (google.protobuf.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
message MyMessageTimestamp {
|
||||||
|
google.protobuf.Timestamp ts = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message MyMessageDuration {
|
||||||
|
google.protobuf.Duration du = 1;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
private const string ProtoDefinitionMain = @"
|
||||||
|
syntax = ""proto3"";
|
||||||
|
|
||||||
|
package greet;
|
||||||
|
|
||||||
|
import ""other.proto"";
|
||||||
|
import ""google/protobuf/empty.proto"";
|
||||||
|
|
||||||
|
service Greeter {
|
||||||
|
rpc Nothing (google.protobuf.Empty) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
rpc SayHello (HelloRequest) returns (HelloReply);
|
||||||
|
|
||||||
|
rpc SayOther (Other) returns (HelloReply);
|
||||||
|
}
|
||||||
|
|
||||||
|
message HelloRequest {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message HelloReply {
|
||||||
|
string message = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Person {
|
||||||
|
string name = 1;
|
||||||
|
int32 id = 2;
|
||||||
|
string email = 3;
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
|
private const string ProtoDefinitionOther = @"// other.proto
|
||||||
|
syntax = ""proto3"";
|
||||||
|
|
||||||
|
package greet;
|
||||||
|
|
||||||
|
message Other {
|
||||||
|
string name = 1;
|
||||||
|
}
|
||||||
";
|
";
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
@@ -80,6 +143,129 @@ message HelloReply {
|
|||||||
server.Stop();
|
server.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WireMockServer_WithBodyAsProtoBuf_WithWellKnownTypes()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
|
||||||
|
using var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create()
|
||||||
|
.UsingPost()
|
||||||
|
.WithPath("/grpc/Greeter/SayNothing")
|
||||||
|
.WithBody(new NotNullOrEmptyMatcher())
|
||||||
|
)
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBodyAsProtoBuf(ProtoDefinitionWithWellKnownTypes, "google.protobuf.Empty",
|
||||||
|
new { }
|
||||||
|
)
|
||||||
|
.WithTrailingHeader("grpc-status", "0")
|
||||||
|
.WithTransformer()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var protoBuf = new ByteArrayContent(bytes);
|
||||||
|
protoBuf.Headers.ContentType = new MediaTypeHeaderValue("application/grpc-web");
|
||||||
|
|
||||||
|
var client = server.CreateClient();
|
||||||
|
var response = await client.PostAsync("/grpc/Greeter/SayNothing", protoBuf);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
var responseBytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
|
||||||
|
Convert.ToBase64String(responseBytes).Should().Be("");
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WireMockServer_WithBodyAsProtoBuf_ServerProtoDefinition_WithWellKnownTypes()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
|
||||||
|
using var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
var id = $"proto-{Guid.NewGuid()}";
|
||||||
|
|
||||||
|
server
|
||||||
|
.AddProtoDefinition(id, ProtoDefinitionWithWellKnownTypes)
|
||||||
|
.Given(Request.Create()
|
||||||
|
.UsingPost()
|
||||||
|
.WithPath("/grpc/Greeter/SayNothing")
|
||||||
|
.WithBody(new NotNullOrEmptyMatcher())
|
||||||
|
)
|
||||||
|
.WithProtoDefinition(id)
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBodyAsProtoBuf("google.protobuf.Empty",
|
||||||
|
new { }
|
||||||
|
)
|
||||||
|
.WithTrailingHeader("grpc-status", "0")
|
||||||
|
.WithTransformer()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var protoBuf = new ByteArrayContent(bytes);
|
||||||
|
protoBuf.Headers.ContentType = new MediaTypeHeaderValue("application/grpc-web");
|
||||||
|
|
||||||
|
var client = server.CreateClient();
|
||||||
|
var response = await client.PostAsync("/grpc/Greeter/SayNothing", protoBuf);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
var responseBytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
|
||||||
|
Convert.ToBase64String(responseBytes).Should().Be("");
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task WireMockServer_WithBodyAsProtoBuf_MultipleFiles()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
var jsonMatcher = new JsonMatcher(new { name = "stef" });
|
||||||
|
|
||||||
|
using var server = WireMockServer.Start();
|
||||||
|
|
||||||
|
var protoFiles = new [] { ProtoDefinitionMain, ProtoDefinitionOther };
|
||||||
|
|
||||||
|
server
|
||||||
|
.Given(Request.Create()
|
||||||
|
.UsingPost()
|
||||||
|
.WithPath("/grpc/greet.Greeter/SayOther")
|
||||||
|
.WithBodyAsProtoBuf(protoFiles, "greet.Other", jsonMatcher)
|
||||||
|
)
|
||||||
|
.RespondWith(Response.Create()
|
||||||
|
.WithBodyAsProtoBuf(protoFiles, "greet.HelloReply",
|
||||||
|
new
|
||||||
|
{
|
||||||
|
message = "hello"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.WithTrailingHeader("grpc-status", "0")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var protoBuf = new ByteArrayContent(bytes);
|
||||||
|
protoBuf.Headers.ContentType = new MediaTypeHeaderValue("application/grpc-web");
|
||||||
|
|
||||||
|
var client = server.CreateClient();
|
||||||
|
var response = await client.PostAsync("/grpc/greet.Greeter/SayOther", protoBuf);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
response.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||||
|
var responseBytes = await response.Content.ReadAsByteArrayAsync();
|
||||||
|
|
||||||
|
Convert.ToBase64String(responseBytes).Should().Be("AAAAAAcKBWhlbGxv");
|
||||||
|
|
||||||
|
server.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task WireMockServer_WithBodyAsProtoBuf_InlineProtoDefinition_UsingGrpcGeneratedClient()
|
public async Task WireMockServer_WithBodyAsProtoBuf_InlineProtoDefinition_UsingGrpcGeneratedClient()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ namespace WireMock.Net.Tests.Matchers;
|
|||||||
public class ProtoBufMatcherTests
|
public class ProtoBufMatcherTests
|
||||||
{
|
{
|
||||||
private const string MessageType = "greet.HelloRequest";
|
private const string MessageType = "greet.HelloRequest";
|
||||||
private readonly IdOrText _protoDefinition = new(null, @"
|
|
||||||
|
private static IdOrTexts ProtoDefinition => new(null, @"
|
||||||
syntax = ""proto3"";
|
syntax = ""proto3"";
|
||||||
|
|
||||||
package greet;
|
package greet;
|
||||||
@@ -30,7 +31,7 @@ message HelloRequest {
|
|||||||
message HelloReply {
|
message HelloReply {
|
||||||
string message = 1;
|
string message = 1;
|
||||||
}
|
}
|
||||||
");
|
" + "\r\n// Dummy " + Guid.NewGuid());
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ProtoBufMatcher_For_ValidProtoBuf_And_ValidMethod_DecodeAsync()
|
public async Task ProtoBufMatcher_For_ValidProtoBuf_And_ValidMethod_DecodeAsync()
|
||||||
@@ -39,7 +40,7 @@ message HelloReply {
|
|||||||
var bytes = Convert.FromBase64String("CgRzdGVm");
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var matcher = new ProtoBufMatcher(() => _protoDefinition, MessageType);
|
var matcher = new ProtoBufMatcher(() => ProtoDefinition, MessageType);
|
||||||
var result = await matcher.DecodeAsync(bytes).ConfigureAwait(false);
|
var result = await matcher.DecodeAsync(bytes).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
@@ -53,7 +54,7 @@ message HelloReply {
|
|||||||
var bytes = Convert.FromBase64String("CgRzdGVm");
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var matcher = new ProtoBufMatcher(() => _protoDefinition, MessageType);
|
var matcher = new ProtoBufMatcher(() => ProtoDefinition, MessageType);
|
||||||
var result = await matcher.IsMatchAsync(bytes).ConfigureAwait(false);
|
var result = await matcher.IsMatchAsync(bytes).ConfigureAwait(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
@@ -69,7 +70,7 @@ message HelloReply {
|
|||||||
var bytes = Convert.FromBase64String("CgRzdGVm");
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var matcher = new ProtoBufMatcher(() => _protoDefinition, MessageType, matcher: jsonMatcher);
|
var matcher = new ProtoBufMatcher(() => ProtoDefinition, MessageType, matcher: jsonMatcher);
|
||||||
var result = await matcher.IsMatchAsync(bytes);
|
var result = await matcher.IsMatchAsync(bytes);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
@@ -84,7 +85,7 @@ message HelloReply {
|
|||||||
var bytes = new byte[] { 1, 2, 3 };
|
var bytes = new byte[] { 1, 2, 3 };
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var matcher = new ProtoBufMatcher(() => _protoDefinition, MessageType);
|
var matcher = new ProtoBufMatcher(() => ProtoDefinition, MessageType);
|
||||||
var result = await matcher.IsMatchAsync(bytes);
|
var result = await matcher.IsMatchAsync(bytes);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
@@ -99,7 +100,7 @@ message HelloReply {
|
|||||||
var bytes = Convert.FromBase64String("CgRzdGVm");
|
var bytes = Convert.FromBase64String("CgRzdGVm");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var matcher = new ProtoBufMatcher(() => _protoDefinition, "greet.Greeter.X");
|
var matcher = new ProtoBufMatcher(() => ProtoDefinition, "greet.Greeter.X");
|
||||||
var result = await matcher.IsMatchAsync(bytes);
|
var result = await matcher.IsMatchAsync(bytes);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ message HelloReply {
|
|||||||
matchers.Should().HaveCount(1);
|
matchers.Should().HaveCount(1);
|
||||||
|
|
||||||
var protoBufMatcher = (ProtoBufMatcher)((RequestMessageProtoBufMatcher)matchers[0]).Matcher!;
|
var protoBufMatcher = (ProtoBufMatcher)((RequestMessageProtoBufMatcher)matchers[0]).Matcher!;
|
||||||
protoBufMatcher.ProtoDefinition().Text.Should().Be(TestProtoDefinition);
|
protoBufMatcher.ProtoDefinition().Texts.Should().Contain(TestProtoDefinition);
|
||||||
protoBufMatcher.MessageType.Should().Be(MessageType);
|
protoBufMatcher.MessageType.Should().Be(MessageType);
|
||||||
protoBufMatcher.Matcher.Should().BeNull();
|
protoBufMatcher.Matcher.Should().BeNull();
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ message HelloReply {
|
|||||||
matchers.Should().HaveCount(1);
|
matchers.Should().HaveCount(1);
|
||||||
|
|
||||||
var protoBufMatcher = (ProtoBufMatcher)((RequestMessageProtoBufMatcher)matchers[0]).Matcher!;
|
var protoBufMatcher = (ProtoBufMatcher)((RequestMessageProtoBufMatcher)matchers[0]).Matcher!;
|
||||||
protoBufMatcher.ProtoDefinition().Text.Should().Be(TestProtoDefinition);
|
protoBufMatcher.ProtoDefinition().Texts.Should().Contain(TestProtoDefinition);
|
||||||
protoBufMatcher.MessageType.Should().Be(MessageType);
|
protoBufMatcher.MessageType.Should().Be(MessageType);
|
||||||
protoBufMatcher.Matcher.Should().BeOfType<JsonMatcher>();
|
protoBufMatcher.Matcher.Should().BeOfType<JsonMatcher>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
Guid: Guid_1,
|
Guid: Guid_1,
|
||||||
UpdatedAt: 2022-12-04 11:12:13,
|
UpdatedAt: 2022-12-04 11:12:13,
|
||||||
TimeSettings: {
|
TimeSettings: {
|
||||||
Start: 2023-01-14 15:16:17,
|
Start: 2023-01-14 15:16:17 Utc,
|
||||||
End: 2023-01-14 15:17:57,
|
End: 2023-01-14 15:17:57 Utc,
|
||||||
TTL: 100
|
TTL: 100
|
||||||
},
|
},
|
||||||
Title: ,
|
Title: ,
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ message HelloReply {
|
|||||||
public Task ToMappingModel_WithTimeSettings_ReturnsCorrectTimeSettings()
|
public Task ToMappingModel_WithTimeSettings_ReturnsCorrectTimeSettings()
|
||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
var start = new DateTime(2023, 1, 14, 15, 16, 17);
|
var start = new DateTime(2023, 1, 14, 15, 16, 17, DateTimeKind.Utc);
|
||||||
var ttl = 100;
|
var ttl = 100;
|
||||||
var end = start.AddSeconds(ttl);
|
var end = start.AddSeconds(ttl);
|
||||||
var request = Request.Create();
|
var request = Request.Create();
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class MatcherMapperTests
|
|||||||
// Assign
|
// Assign
|
||||||
var matcherMock = new Mock<IStringMatcher>();
|
var matcherMock = new Mock<IStringMatcher>();
|
||||||
matcherMock.Setup(m => m.Name).Returns("test");
|
matcherMock.Setup(m => m.Name).Returns("test");
|
||||||
matcherMock.Setup(m => m.GetPatterns()).Returns(new AnyOf<string, StringPattern>[] { "p1", "p2" });
|
matcherMock.Setup(m => m.GetPatterns()).Returns(["p1", "p2"]);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var model = _sut.Map(matcherMock.Object)!;
|
var model = _sut.Map(matcherMock.Object)!;
|
||||||
@@ -206,7 +206,7 @@ public class MatcherMapperTests
|
|||||||
public void MatcherMapper_Map_Matcher_ProtoBufMatcher()
|
public void MatcherMapper_Map_Matcher_ProtoBufMatcher()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
IdOrText protoDefinition = new(null, @"
|
IdOrTexts protoDefinition = new(null, @"
|
||||||
syntax = ""proto3"";
|
syntax = ""proto3"";
|
||||||
|
|
||||||
package greet;
|
package greet;
|
||||||
@@ -235,7 +235,7 @@ message HelloReply {
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
model.Name.Should().Be(nameof(ProtoBufMatcher));
|
model.Name.Should().Be(nameof(ProtoBufMatcher));
|
||||||
model.Pattern.Should().Be(protoDefinition.Text);
|
model.Pattern.Should().Be(protoDefinition.Texts[0]);
|
||||||
model.ProtoBufMessageType.Should().Be(messageType);
|
model.ProtoBufMessageType.Should().Be(messageType);
|
||||||
model.ContentMatcher?.Name.Should().Be("JsonMatcher");
|
model.ContentMatcher?.Name.Should().Be("JsonMatcher");
|
||||||
model.ContentMatcher?.Pattern.Should().Be(jsonPattern);
|
model.ContentMatcher?.Pattern.Should().Be(jsonPattern);
|
||||||
@@ -246,7 +246,7 @@ message HelloReply {
|
|||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
string id = "abc123";
|
string id = "abc123";
|
||||||
IdOrText protoDefinition = new(id, @"
|
IdOrTexts protoDefinition = new(id, @"
|
||||||
syntax = ""proto3"";
|
syntax = ""proto3"";
|
||||||
|
|
||||||
package greet;
|
package greet;
|
||||||
@@ -327,7 +327,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "LinqMatcher",
|
Name = "LinqMatcher",
|
||||||
Patterns = new[] { "p1", "p2" }
|
Patterns = ["p1", "p2"]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -362,7 +362,7 @@ message HelloReply {
|
|||||||
{
|
{
|
||||||
// Assign
|
// Assign
|
||||||
var pattern = "{ \"post1\": \"value1\", \"post2\": \"value2\" }";
|
var pattern = "{ \"post1\": \"value1\", \"post2\": \"value2\" }";
|
||||||
var patterns = new[] { pattern };
|
object[] patterns = [pattern];
|
||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "JsonMatcher",
|
Name = "JsonMatcher",
|
||||||
@@ -383,7 +383,7 @@ message HelloReply {
|
|||||||
// Assign
|
// Assign
|
||||||
var pattern1 = "{ \"AccountIds\": [ 1, 2, 3 ] }";
|
var pattern1 = "{ \"AccountIds\": [ 1, 2, 3 ] }";
|
||||||
var pattern2 = "{ \"post1\": \"value1\", \"post2\": \"value2\" }";
|
var pattern2 = "{ \"post1\": \"value1\", \"post2\": \"value2\" }";
|
||||||
var patterns = new[] { pattern1, pattern2 };
|
object[] patterns = [pattern1, pattern2];
|
||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "JsonMatcher",
|
Name = "JsonMatcher",
|
||||||
@@ -690,7 +690,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "CSharpCodeMatcher",
|
Name = "CSharpCodeMatcher",
|
||||||
Patterns = new[] { "return it == \"x\";" }
|
Patterns = ["return it == \"x\";"]
|
||||||
};
|
};
|
||||||
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = true });
|
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = true });
|
||||||
|
|
||||||
@@ -716,7 +716,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "CSharpCodeMatcher",
|
Name = "CSharpCodeMatcher",
|
||||||
Patterns = new[] { "x" }
|
Patterns = ["x"]
|
||||||
};
|
};
|
||||||
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = false });
|
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = false });
|
||||||
|
|
||||||
@@ -734,7 +734,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "ExactMatcher",
|
Name = "ExactMatcher",
|
||||||
Patterns = new[] { "x" }
|
Patterns = ["x"]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -751,7 +751,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "ExactMatcher",
|
Name = "ExactMatcher",
|
||||||
Patterns = new[] { "x", "y" }
|
Patterns = ["x", "y"]
|
||||||
};
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
@@ -819,7 +819,7 @@ message HelloReply {
|
|||||||
var matcher = (ExactObjectMatcher)_sut.Map(model)!;
|
var matcher = (ExactObjectMatcher)_sut.Map(model)!;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Check.That((byte[])matcher.Value).ContainsExactly(new byte[] { 115, 116, 101, 102 });
|
Check.That((byte[])matcher.Value).ContainsExactly(115, 116, 101, 102);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -846,7 +846,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "RegexMatcher",
|
Name = "RegexMatcher",
|
||||||
Patterns = new[] { "x", "y" },
|
Patterns = ["x", "y"],
|
||||||
IgnoreCase = true,
|
IgnoreCase = true,
|
||||||
MatchOperator = matchOperator.ToString()
|
MatchOperator = matchOperator.ToString()
|
||||||
};
|
};
|
||||||
@@ -871,7 +871,7 @@ message HelloReply {
|
|||||||
var model = new MatcherModel
|
var model = new MatcherModel
|
||||||
{
|
{
|
||||||
Name = "WildcardMatcher",
|
Name = "WildcardMatcher",
|
||||||
Patterns = new[] { "x", "y" },
|
Patterns = ["x", "y"],
|
||||||
IgnoreCase = true,
|
IgnoreCase = true,
|
||||||
MatchOperator = matchOperator.ToString()
|
MatchOperator = matchOperator.ToString()
|
||||||
};
|
};
|
||||||
@@ -1127,7 +1127,7 @@ message HelloReply {
|
|||||||
var matcher = (ProtoBufMatcher)_sut.Map(model)!;
|
var matcher = (ProtoBufMatcher)_sut.Map(model)!;
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
matcher.ProtoDefinition().Text.Should().Be(protoDefinition);
|
matcher.ProtoDefinition().Texts.Should().ContainSingle(protoDefinition);
|
||||||
matcher.Name.Should().Be(nameof(ProtoBufMatcher));
|
matcher.Name.Should().Be(nameof(ProtoBufMatcher));
|
||||||
matcher.MessageType.Should().Be(messageType);
|
matcher.MessageType.Should().Be(messageType);
|
||||||
matcher.Matcher?.Value.Should().Be(jsonMatcherPattern);
|
matcher.Matcher?.Value.Should().Be(jsonMatcherPattern);
|
||||||
|
|||||||
@@ -759,8 +759,8 @@ public class WireMockServerProxyTests
|
|||||||
var brokenJpegHeader = new byte[]
|
var brokenJpegHeader = new byte[]
|
||||||
{0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00};
|
{0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0xEF, 0xBF, 0xBD, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46, 0x00};
|
||||||
|
|
||||||
bool HasCorrectHeader(byte[] bytes) => bytes.SequenceEqual(jpegHeader);
|
bool HasCorrectHeader(byte[]? bytes) => bytes?.SequenceEqual(jpegHeader) == true;
|
||||||
bool HasBrokenHeader(byte[] bytes) => bytes.SequenceEqual(brokenJpegHeader);
|
bool HasBrokenHeader(byte[]? bytes) => bytes?.SequenceEqual(brokenJpegHeader) == true;
|
||||||
|
|
||||||
var serverForProxyForwarding = WireMockServer.Start();
|
var serverForProxyForwarding = WireMockServer.Start();
|
||||||
serverForProxyForwarding
|
serverForProxyForwarding
|
||||||
|
|||||||
Reference in New Issue
Block a user