Skip to content

Commit f406e6e

Browse files
committed
fix?
1 parent 3e06b5d commit f406e6e

16 files changed

+124
-72
lines changed

src/WireMock.Net/Matchers/Helpers/BodyDataMatchScoreCalculator.cs

+6
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ public static MatchResult CalculateMatchScore(IBodyData? requestMessage, IMatche
6666
return stringMatcher.IsMatch(requestMessage.BodyAsString);
6767
}
6868

69+
// In case the matcher is a IProtoBufMatcher, use the BodyAsBytes to match on.
70+
if (matcher is IProtoBufMatcher protoBufMatcher)
71+
{
72+
return protoBufMatcher.IsMatchAsync(requestMessage.BodyAsBytes).GetAwaiter().GetResult();
73+
}
74+
6975
return default;
7076
}
7177
}

src/WireMock.Net/Matchers/ProtoBufMatcher.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
#if PROTOBUF
44
using System;
5-
using System.Linq;
65
using System.Threading;
76
using System.Threading.Tasks;
87
using ProtoBufJsonConverter;
@@ -28,7 +27,7 @@ public class ProtoBufMatcher : IProtoBufMatcher
2827
/// <summary>
2928
/// The Func to define the proto definition as id or texts.
3029
/// </summary>
31-
public Func<IdOrTexts> ProtoDefinition { get; }
30+
public Func<IdOrTexts> ProtoDefinition { get; internal set; }
3231

3332
/// <summary>
3433
/// The full type of the protobuf (request/response) message object. Format is "{package-name}.{type-name}".

src/WireMock.Net/RequestBuilders/IBodyRequestBuilder.cs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
using System;
44
using System.Collections.Generic;
5-
using JsonConverter.Abstractions;
65
using WireMock.Matchers;
76
using WireMock.Util;
87

src/WireMock.Net/RequestBuilders/Request.cs

+15
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Collections.ObjectModel;
8+
using System.Diagnostics.CodeAnalysis;
89
using System.Linq;
910
using Stef.Validation;
11+
using WireMock.Matchers;
1012
using WireMock.Matchers.Request;
1113

1214
namespace WireMock.RequestBuilders;
@@ -71,6 +73,19 @@ public IList<T> GetRequestMessageMatchers<T>() where T : IRequestMatcher
7173
return _requestMatchers.OfType<T>().FirstOrDefault(func);
7274
}
7375

76+
internal bool TryGetProtoBufMatcher([NotNullWhen(true)] out IProtoBufMatcher? protoBufMatcher)
77+
{
78+
protoBufMatcher = GetRequestMessageMatcher<RequestMessageProtoBufMatcher>()?.Matcher;
79+
if (protoBufMatcher != null)
80+
{
81+
return true;
82+
}
83+
84+
var bodyMatcher = GetRequestMessageMatcher<RequestMessageBodyMatcher>();
85+
protoBufMatcher = bodyMatcher?.Matchers?.OfType<IProtoBufMatcher>().FirstOrDefault();
86+
return protoBufMatcher != null;
87+
}
88+
7489
private IRequestBuilder Add<T>(T requestMatcher) where T : IRequestMatcher
7590
{
7691
foreach (var existing in _requestMatchers.OfType<T>().ToArray())

src/WireMock.Net/ResponseBuilders/Response.cs

+5-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using System.Threading.Tasks;
99
using JetBrains.Annotations;
1010
using Stef.Validation;
11-
using WireMock.Matchers.Request;
1211
using WireMock.Proxy;
1312
using WireMock.RequestBuilders;
1413
using WireMock.Settings;
@@ -264,16 +263,15 @@ string RemoveFirstOccurrence(string source, string find)
264263

265264
if (UseTransformer)
266265
{
267-
// Check if the body matcher is a RequestMessageProtoBufMatcher and try to decode the byte-array to a BodyAsJson.
268-
if (mapping.RequestMatcher is Request requestMatcher && requestMessage is RequestMessage request)
266+
// If the body matcher is a RequestMessageProtoBufMatcher or BodyMatcher with a ProtoBufMatcher then try to decode the byte-array to a BodyAsJson.
267+
if (mapping.RequestMatcher is Request request && requestMessage is RequestMessage requestMessageImplementation)
269268
{
270-
var protoBufMatcher = requestMatcher.GetRequestMessageMatcher<RequestMessageProtoBufMatcher>()?.Matcher;
271-
if (protoBufMatcher != null)
269+
if (request.TryGetProtoBufMatcher(out var protoBufMatcher))
272270
{
273-
var decoded = await protoBufMatcher.DecodeAsync(request.BodyData?.BodyAsBytes).ConfigureAwait(false);
271+
var decoded = await protoBufMatcher.DecodeAsync(requestMessage.BodyData?.BodyAsBytes).ConfigureAwait(false);
274272
if (decoded != null)
275273
{
276-
request.BodyAsJson = JsonUtils.ConvertValueToJToken(decoded);
274+
requestMessageImplementation.BodyAsJson = JsonUtils.ConvertValueToJToken(decoded);
277275
}
278276
}
279277
}

src/WireMock.Net/Serialization/MatcherMapper.cs

+2-20
Original file line numberDiff line numberDiff line change
@@ -293,27 +293,9 @@ private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, IR
293293
{
294294
var objectMatcher = Map(matcher.ContentMatcher) as IObjectMatcher;
295295

296-
IdOrTexts protoDefinitionAsIdOrTexts;
297-
if (protoDefinitions.Count == 1)
298-
{
299-
var idOrText = protoDefinitions[0];
300-
if (_settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitionFromSettings) == true)
301-
{
302-
protoDefinitionAsIdOrTexts = new(idOrText, protoDefinitionFromSettings);
303-
}
304-
else
305-
{
306-
protoDefinitionAsIdOrTexts = new(null, protoDefinitions);
307-
}
308-
}
309-
else
310-
{
311-
protoDefinitionAsIdOrTexts = new(null, protoDefinitions);
312-
}
313-
314296
return new ProtoBufMatcher(
315-
() => protoDefinitionAsIdOrTexts,
316-
matcher!.ProtoBufMessageType!,
297+
() => ProtoDefinitionHelper.GetIdOrTexts(_settings, protoDefinitions.ToArray()),
298+
matcher.ProtoBufMessageType!,
317299
matchBehaviour ?? MatchBehaviour.AcceptOnMatch,
318300
objectMatcher
319301
);

src/WireMock.Net/Server/IRespondWithAProvider.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ public interface IRespondWithAProvider
123123
void ThenRespondWithStatusCode(HttpStatusCode code);
124124

125125
/// <summary>
126-
/// Sets the the scenario.
126+
/// Sets the scenario.
127127
/// </summary>
128128
/// <param name="scenario">The scenario.</param>
129129
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
130130
IRespondWithAProvider InScenario(string scenario);
131131

132132
/// <summary>
133-
/// Sets the the scenario with an integer value.
133+
/// Sets the scenario with an integer value.
134134
/// </summary>
135135
/// <param name="scenario">The scenario.</param>
136136
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
@@ -220,7 +220,7 @@ IRespondWithAProvider WithWebhook(
220220

221221
/// <summary>
222222
/// Data Object which can be used when WithTransformer is used.
223-
/// e.g. lookup an path in this object using
223+
/// e.g. lookup a path in this object using
224224
/// <param name="data">The data dictionary object.</param>
225225
/// <example>
226226
/// lookup data "1"

src/WireMock.Net/Server/RespondWithAProvider.cs

+6-21
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
namespace WireMock.Server;
1818

1919
/// <summary>
20-
/// The respond with a provider.
20+
/// The RespondWithAProvider.
2121
/// </summary>
2222
internal class RespondWithAProvider : IRespondWithAProvider
2323
{
@@ -37,7 +37,6 @@ internal class RespondWithAProvider : IRespondWithAProvider
3737
private int _timesInSameState = 1;
3838
private bool? _useWebhookFireAndForget;
3939
private double? _probability;
40-
private IdOrTexts? _protoDefinition;
4140
private GraphQLSchemaDetails? _graphQLSchemaDetails;
4241

4342
public Guid Guid { get; private set; }
@@ -48,6 +47,8 @@ internal class RespondWithAProvider : IRespondWithAProvider
4847

4948
public object? Data { get; private set; }
5049

50+
public IdOrTexts? ProtoDefinition { get; private set; }
51+
5152
/// <summary>
5253
/// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.
5354
/// </summary>
@@ -104,9 +105,9 @@ public void RespondWith(IResponseProvider provider)
104105
mapping.WithProbability(_probability.Value);
105106
}
106107

107-
if (_protoDefinition != null)
108+
if (ProtoDefinition != null)
108109
{
109-
mapping.WithProtoDefinition(_protoDefinition.Value);
110+
mapping.WithProtoDefinition(ProtoDefinition.Value);
110111
}
111112

112113
_registrationCallback(mapping, _saveToFile);
@@ -355,23 +356,7 @@ public IRespondWithAProvider WithProtoDefinition(params string[] protoDefinition
355356
{
356357
Guard.NotNull(protoDefinitionOrId);
357358

358-
if (protoDefinitionOrId.Length == 1)
359-
{
360-
var idOrText = protoDefinitionOrId[0];
361-
if (_settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitions) == true)
362-
{
363-
_protoDefinition = new(idOrText, protoDefinitions);
364-
}
365-
else
366-
{
367-
_protoDefinition = new(null, protoDefinitionOrId);
368-
}
369-
}
370-
else
371-
{
372-
_protoDefinition = new(null, protoDefinitionOrId);
373-
}
374-
359+
ProtoDefinition = ProtoDefinitionHelper.GetIdOrTexts(_settings, protoDefinitionOrId);
375360

376361
return this;
377362
}

src/WireMock.Net/Server/WireMockServer.ConvertMapping.cs

+16-6
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ private Guid ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingMode
4242
Guard.NotNull(mappingModel.Request);
4343
Guard.NotNull(mappingModel.Response);
4444

45-
var requestBuilder = InitRequestBuilder(mappingModel.Request);
45+
var request = (Request)InitRequestBuilder(mappingModel.Request, mappingModel);
4646

47-
var respondProvider = Given(requestBuilder, mappingModel.SaveToFile == true);
47+
var respondProvider = Given(request, mappingModel.SaveToFile == true);
4848

4949
if (guid != null)
5050
{
@@ -116,6 +116,7 @@ private Guid ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingMode
116116
respondProvider.WithProbability(mappingModel.Probability.Value);
117117
}
118118

119+
// ProtoDefinition is defined at Mapping level
119120
if (mappingModel.ProtoDefinition != null)
120121
{
121122
respondProvider.WithProtoDefinition(mappingModel.ProtoDefinition);
@@ -131,7 +132,7 @@ private Guid ConvertMappingAndRegisterAsRespondProvider(MappingModel mappingMode
131132
return respondProvider.Guid;
132133
}
133134

134-
private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
135+
private IRequestBuilder InitRequestBuilder(RequestModel requestModel, MappingModel? mappingModel = null)
135136
{
136137
var requestBuilder = Request.Create();
137138

@@ -225,7 +226,7 @@ private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
225226

226227
if (requestModel.Params != null)
227228
{
228-
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: { } }))
229+
foreach (var paramModel in requestModel.Params.Where(p => p is { Matchers: not null }))
229230
{
230231
var ignoreCase = paramModel.IgnoreCase == true;
231232
requestBuilder = requestBuilder.WithParam(paramModel.Name, ignoreCase, paramModel.Matchers!.Select(_matcherMapper.Map).OfType<IStringMatcher>().ToArray());
@@ -234,7 +235,15 @@ private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
234235

235236
if (requestModel.Body?.Matcher != null)
236237
{
237-
requestBuilder = requestBuilder.WithBody(_matcherMapper.Map(requestModel.Body.Matcher)!);
238+
var bodyMatcher = _matcherMapper.Map(requestModel.Body.Matcher)!;
239+
#if PROTOBUF
240+
// If the BodyMatcher is a ProtoBufMatcher, and if ProtoDefinition is defined on Mapping-level, set the ProtoDefinition from that Mapping.
241+
if (bodyMatcher is ProtoBufMatcher protoBufMatcher && mappingModel?.ProtoDefinition != null)
242+
{
243+
protoBufMatcher.ProtoDefinition = () => ProtoDefinitionHelper.GetIdOrTexts(_settings, mappingModel.ProtoDefinition);
244+
}
245+
#endif
246+
requestBuilder = requestBuilder.WithBody(bodyMatcher);
238247
}
239248
else if (requestModel.Body?.Matchers != null)
240249
{
@@ -317,7 +326,7 @@ private static IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
317326
}
318327
else if (responseModel.HeadersRaw != null)
319328
{
320-
foreach (string headerLine in responseModel.HeadersRaw.Split(["\n", "\r\n"], StringSplitOptions.RemoveEmptyEntries))
329+
foreach (var headerLine in responseModel.HeadersRaw.Split(["\n", "\r\n"], StringSplitOptions.RemoveEmptyEntries))
321330
{
322331
int indexColon = headerLine.IndexOf(":", StringComparison.Ordinal);
323332
string key = headerLine.Substring(0, indexColon).TrimStart(' ', '\t');
@@ -364,6 +373,7 @@ private static IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
364373
}
365374
else
366375
{
376+
// ProtoDefinition(s) is/are defined at Mapping/Server level
367377
responseBuilder = responseBuilder.WithBodyAsProtoBuf(responseModel.ProtoBufMessageType, responseModel.BodyAsJson);
368378
}
369379
}

src/WireMock.Net/Util/PortUtils.cs

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright © WireMock.Net
22

33
using System;
4+
using System.Collections.Generic;
45
using System.Diagnostics.CodeAnalysis;
56
using System.Net;
67
using System.Net.Sockets;
@@ -36,6 +37,33 @@ public static int FindFreeTcpPort()
3637
}
3738
}
3839

40+
/// <summary>
41+
/// Finds a free TCP ports.
42+
/// </summary>
43+
/// <remarks>see http://stackoverflow.com/questions/138043/find-the-next-tcp-port-in-net.</remarks>
44+
public static IReadOnlyList<int> FindFreeTcpPorts(int numPorts)
45+
{
46+
var freePorts = new List<int>();
47+
48+
TcpListener? tcpListener = null;
49+
try
50+
{
51+
for (var i = 0; i < numPorts; i++)
52+
{
53+
tcpListener = new TcpListener(IPAddress.Loopback, 0);
54+
tcpListener.Start();
55+
56+
freePorts.Add(((IPEndPoint)tcpListener.LocalEndpoint).Port);
57+
}
58+
}
59+
finally
60+
{
61+
tcpListener?.Stop();
62+
}
63+
64+
return freePorts;
65+
}
66+
3967
/// <summary>
4068
/// Extract the isHttps, isHttp2, protocol, host and port from a URL.
4169
/// </summary>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright © WireMock.Net
2+
3+
using WireMock.Models;
4+
using WireMock.Settings;
5+
6+
namespace WireMock.Util;
7+
8+
internal static class ProtoDefinitionHelper
9+
{
10+
internal static IdOrTexts GetIdOrTexts(WireMockServerSettings settings, params string[] protoDefinitionOrId)
11+
{
12+
switch (protoDefinitionOrId.Length)
13+
{
14+
case 1:
15+
var idOrText = protoDefinitionOrId[0];
16+
if (settings.ProtoDefinitions?.TryGetValue(idOrText, out var protoDefinitions) == true)
17+
{
18+
return new(idOrText, protoDefinitions);
19+
}
20+
21+
return new(null, protoDefinitionOrId);
22+
23+
default:
24+
return new(null, protoDefinitionOrId);
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)