Skip to content

Commit

Permalink
mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Dec 29, 2023
1 parent 8436a84 commit 84deb58
Show file tree
Hide file tree
Showing 32 changed files with 317 additions and 98 deletions.
3 changes: 2 additions & 1 deletion src/WireMock.Net.Abstractions/Models/IBodyData.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using WireMock.Types;
Expand Down Expand Up @@ -75,7 +76,7 @@ public interface IBodyData
/// <summary>
/// Gets or sets the proto definition.
/// </summary>
public string? ProtoDefinition { get; set; }
public Func<string?>? ProtoDefinition { get; set; }

/// <summary>
/// Gets or sets the full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
Expand Down
51 changes: 48 additions & 3 deletions src/WireMock.Net/IMapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ public interface IMapping
int? StateTimes { get; }

/// <summary>
/// The Request matcher.
/// The RequestMatcher.
/// </summary>
IRequestMatcher RequestMatcher { get; }

/// <summary>
/// The Provider.
/// The ResponseProvider.
/// </summary>
IResponseProvider Provider { get; }

Expand Down Expand Up @@ -136,6 +136,11 @@ public interface IMapping
/// </summary>
double? Probability { get; }

/// <summary>
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
/// </summary>
string? ProtoDefinition { get; }

/// <summary>
/// ProvideResponseAsync
/// </summary>
Expand All @@ -150,4 +155,44 @@ public interface IMapping
/// <param name="nextState">The Next State.</param>
/// <returns>The <see cref="IRequestMatchResult"/>.</returns>
IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage, string? nextState);
}

/// <summary>
/// Define a Grpc ProtoDefinition which is used for this mapping (request and response).
/// </summary>
/// <param name="protoDefinition">The proto definition as a string.</param>
/// <returns>The <see cref="IMapping"/>.</returns>
IMapping WithProtoDefinition(string protoDefinition);

/// <summary>
/// Define the scenario.
/// </summary>
/// <param name="scenario">The scenario.</param>
/// <returns>The <see cref="IMapping"/>.</returns>
IMapping WithScenario(string scenario);

/// <summary>
/// Define the probability when this request should be matched. [Optional]
/// </summary>
/// <param name="probability">The probability.</param>
/// <returns>The <see cref="IMapping"/>.</returns>
IMapping WithProbability(double probability);
}

/*
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,
*/
37 changes: 30 additions & 7 deletions src/WireMock.Net/Mapping.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using Stef.Validation;
using WireMock.Matchers.Request;
using WireMock.Models;
using WireMock.ResponseProviders;
Expand Down Expand Up @@ -31,7 +32,7 @@ public class Mapping : IMapping
public int Priority { get; }

/// <inheritdoc />
public string? Scenario { get; }
public string? Scenario { get; private set; }

/// <inheritdoc />
public string? ExecutionConditionState { get; }
Expand Down Expand Up @@ -76,7 +77,10 @@ public class Mapping : IMapping
public object? Data { get; }

/// <inheritdoc />
public double? Probability { get; }
public double? Probability { get; private set; }

/// <inheritdoc />
public string? ProtoDefinition { get; private set; }

/// <summary>
/// Initializes a new instance of the <see cref="Mapping"/> class.
Expand All @@ -98,7 +102,6 @@ public class Mapping : IMapping
/// <param name="useWebhooksFireAndForget">Use Fire and Forget for the defined webhook(s). [Optional]</param>
/// <param name="timeSettings">The TimeSettings. [Optional]</param>
/// <param name="data">The data object. [Optional]</param>
/// <param name="probability">Define the probability when this request should be matched. [Optional]</param>
public Mapping(
Guid guid,
DateTime updatedAt,
Expand All @@ -116,8 +119,8 @@ public Mapping(
IWebhook[]? webhooks,
bool? useWebhooksFireAndForget,
ITimeSettings? timeSettings,
object? data,
double? probability)
object? data
)
{
Guid = guid;
UpdatedAt = updatedAt;
Expand All @@ -136,9 +139,8 @@ public Mapping(
UseWebhooksFireAndForget = useWebhooksFireAndForget;
TimeSettings = timeSettings;
Data = data;
Probability = probability;
}

/// <inheritdoc />
public Task<(IResponseMessage Message, IMapping? Mapping)> ProvideResponseAsync(IRequestMessage requestMessage)
{
Expand Down Expand Up @@ -168,4 +170,25 @@ public IRequestMatchResult GetRequestMatchResult(IRequestMessage requestMessage,

return result;
}

/// <inheritdoc />
public IMapping WithProtoDefinition(string protoDefinition)
{
ProtoDefinition = Guard.NotNullOrWhiteSpace(protoDefinition);
return this;
}

/// <inheritdoc />
public IMapping WithScenario(string scenario)
{
Scenario = Guard.NotNullOrWhiteSpace(scenario);
return this;
}

/// <inheritdoc />
public IMapping WithProbability(double probability)
{
Probability = Guard.NotNull(probability);
return this;
}
}
11 changes: 11 additions & 0 deletions src/WireMock.Net/MappingBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using WireMock.Admin.Mappings;
using WireMock.Matchers.Request;
using WireMock.Owin;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using WireMock.Serialization;
using WireMock.Server;
using WireMock.Settings;
Expand Down Expand Up @@ -146,6 +148,15 @@ private void RegisterMapping(IMapping mapping, bool saveToFile)
{
_mappingToFileSaver.SaveMappingToFile(mapping);
}

// Link this mapping to the Request
((Request)mapping.RequestMatcher).Mapping = mapping;

// Link this mapping to the Response
if (mapping.Provider is Response response)
{
response.Mapping = mapping;
}
}

private static string ToJson(object value)
Expand Down
10 changes: 5 additions & 5 deletions src/WireMock.Net/Matchers/ProtoBufMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public class ProtoBufMatcher : IBytesMatcher
public MatchBehaviour MatchBehaviour { get; }

/// <summary>
/// The proto definition.
/// The Func to define the proto definition as a string.
/// </summary>
public string ProtoDefinition { get; }
public Func<string> ProtoDefinition { get; }

/// <summary>
/// The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".
Expand All @@ -44,13 +44,13 @@ public class ProtoBufMatcher : IBytesMatcher
/// <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>
public ProtoBufMatcher(
string protoDefinition,
Func<string> protoDefinition,
string messageType,
MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch,
IObjectMatcher? matcher = null
)
{
ProtoDefinition = Guard.NotNullOrWhiteSpace(protoDefinition);
ProtoDefinition = Guard.NotNull(protoDefinition);
MessageType = Guard.NotNullOrWhiteSpace(messageType);
Matcher = matcher;
MatchBehaviour = matchBehaviour;
Expand All @@ -63,7 +63,7 @@ public MatchResult IsMatch(byte[]? input)

if (input != null)
{
var request = new ConvertToObjectRequest(ProtoDefinition, MessageType, input);
var request = new ConvertToObjectRequest(ProtoDefinition(), MessageType, input);

try
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System;

namespace WireMock.Matchers.Request;

/// <summary>
Expand All @@ -14,10 +16,10 @@ public class RequestMessageProtoBufMatcher : IRequestMatcher
/// Initializes a new instance of the <see cref="RequestMessageProtoBufMatcher"/> class.
/// </summary>
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
/// <param name="protoDefinition">The proto definition as a string.</param>
/// <param name="protoDefinition">The Func to define the proto definition as a string.</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>
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, string protoDefinition, string messageType, IObjectMatcher? matcher = null)
public RequestMessageProtoBufMatcher(MatchBehaviour matchBehaviour, Func<string> protoDefinition, string messageType, IObjectMatcher? matcher = null)
{
#if PROTOBUF
Matcher = new ProtoBufMatcher(protoDefinition, messageType, matchBehaviour, matcher);
Expand Down
3 changes: 2 additions & 1 deletion src/WireMock.Net/Models/BodyData.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text;
using WireMock.Types;
Expand Down Expand Up @@ -48,7 +49,7 @@ public class BodyData : IBodyData

#region ProtoBuf
/// <inheritdoc />
public string? ProtoDefinition { get; set; }
public Func<string?>? ProtoDefinition { get; set; }

/// <inheritdoc />
public string? ProtoBufMessageType { get; set; }
Expand Down
23 changes: 11 additions & 12 deletions src/WireMock.Net/Owin/Mappers/IOwinResponseMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
using IResponse = Microsoft.AspNetCore.Http.HttpResponse;
#endif

namespace WireMock.Owin.Mappers
namespace WireMock.Owin.Mappers;

/// <summary>
/// IOwinResponseMapper
/// </summary>
internal interface IOwinResponseMapper
{
/// <summary>
/// IOwinResponseMapper
/// Map ResponseMessage to IResponse.
/// </summary>
internal interface IOwinResponseMapper
{
/// <summary>
/// Map ResponseMessage to IResponse.
/// </summary>
/// <param name="responseMessage">The ResponseMessage</param>
/// <param name="response">The OwinResponse/HttpResponse</param>
Task MapAsync(IResponseMessage? responseMessage, IResponse response);
}
}
/// <param name="responseMessage">The ResponseMessage</param>
/// <param name="response">The OwinResponse/HttpResponse</param>
Task MapAsync(IResponseMessage? responseMessage, IResponse response);
}
3 changes: 2 additions & 1 deletion src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ private bool IsFault(IResponseMessage responseMessage)

#if PROTOBUF
case BodyType.ProtoBuf:
return ProtoBufUtils.GetProtoBufMessageWithHeader(responseMessage.BodyData.ProtoDefinition, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson);
var protoDefinition = responseMessage.BodyData.ProtoDefinition?.Invoke();
return ProtoBufUtils.GetProtoBufMessageWithHeader(protoDefinition, responseMessage.BodyData.ProtoBufMessageType, responseMessage.BodyData.BodyAsJson);
#endif

case BodyType.Bytes:
Expand Down
17 changes: 17 additions & 0 deletions src/WireMock.Net/RequestBuilders/IProtoBufRequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,21 @@ public interface IProtoBufRequestBuilder : IGraphQLRequestBuilder
/// <param name="matchBehaviour">The match behaviour. (default = "AcceptOnMatch")</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);

/// <summary>
/// WithGrpcProto
/// </summary>
/// <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(string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);

/// <summary>
/// WithGrpcProto
/// </summary>
/// <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(string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
}
19 changes: 15 additions & 4 deletions src/WireMock.Net/RequestBuilders/Request.WithGrpcProto.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Linq;
using WireMock.Matchers;
using WireMock.Matchers.Request;

Expand All @@ -8,14 +9,24 @@ public partial class Request
/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageProtoBufMatcher(matchBehaviour, protoDefinition, messageType));
return this;
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => protoDefinition, messageType));
}

/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(string protoDefinition, string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
_requestMatchers.Add(new RequestMessageProtoBufMatcher(matchBehaviour, protoDefinition, messageType, matcher));
return this;
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => protoDefinition, messageType, matcher));
}

/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(string messageType, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => Mapping.ProtoDefinition!, messageType));
}

/// <inheritdoc />
public IRequestBuilder WithBodyAsProtoBuf(string messageType, IObjectMatcher matcher, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
{
return Add(new RequestMessageProtoBufMatcher(matchBehaviour, () => Mapping.ProtoDefinition!, messageType, matcher));
}
}
16 changes: 16 additions & 0 deletions src/WireMock.Net/RequestBuilders/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public partial class Request : RequestMessageCompositeMatcher, IRequestBuilder
{
private readonly IList<IRequestMatcher> _requestMatchers;

/// <summary>
/// The link back to the Mapping.
/// </summary>
public IMapping Mapping { get; set; } = null!;

/// <summary>
/// Creates this instance.
/// </summary>
Expand Down Expand Up @@ -63,4 +68,15 @@ public IList<T> GetRequestMessageMatchers<T>() where T : IRequestMatcher
{
return _requestMatchers.OfType<T>().FirstOrDefault(func);
}

private IRequestBuilder Add<T>(T requestMatcher) where T : IRequestMatcher
{
foreach (var existing in _requestMatchers.OfType<T>().ToArray())
{
_requestMatchers.Remove(existing);
}

_requestMatchers.Add(requestMatcher);
return this;
}
}
Loading

0 comments on commit 84deb58

Please sign in to comment.