Skip to content

Commit ed07da7

Browse files
authored
Fix ProtoBuf mapping.json (#1236)
* Fix ProtoBuf Mappings * [Fact(Skip = "#1233")] * fix? * PortUtils
1 parent 442d8a7 commit ed07da7

25 files changed

+931
-219
lines changed

src/WireMock.Net.Abstractions/Server/IWireMockServer.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,16 @@ public interface IWireMockServer : IDisposable
215215
/// This can be used if you have 1 or more <see cref="MappingModel"/> defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
216216
/// </summary>
217217
/// <param name="mappings">The MappingModels</param>
218+
/// <returns><see cref="IWireMockServer"/></returns>
218219
IWireMockServer WithMapping(params MappingModel[] mappings);
219220

220221
/// <summary>
221222
/// Register the mappings (via json string).
222223
///
223-
/// This can be used if you the mappings as json string defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
224+
/// This can be used if you've the mappings as json string defined and want to register these in WireMock.Net directly instead of using the fluent syntax.
224225
/// </summary>
225226
/// <param name="mappings">The mapping(s) as json string.</param>
227+
/// <returns><see cref="IWireMockServer"/></returns>
226228
IWireMockServer WithMapping(string mappings);
227229

228230
/// <summary>
@@ -238,5 +240,5 @@ public interface IWireMockServer : IDisposable
238240
/// </summary>
239241
/// <param name="converterType">The <see cref="MappingConverterType"/></param>
240242
/// <returns>C# code</returns>
241-
public string MappingsToCSharpCode(MappingConverterType converterType);
243+
string MappingsToCSharpCode(MappingConverterType converterType);
242244
}

src/WireMock.Net.RestClient/IWireMockAdminApi.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,23 @@ public interface IWireMockAdminApi
130130
Task<StatusModel> ReloadStaticMappingsAsync(CancellationToken cancellationToken = default);
131131

132132
/// <summary>
133-
/// Get a mapping based on the guid
133+
/// Get a mapping based on the guid.
134134
/// </summary>
135135
/// <param name="guid">The Guid</param>
136136
/// <returns>MappingModel</returns>
137137
/// <param name="cancellationToken">The optional cancellationToken.</param>
138138
[Get("mappings/{guid}")]
139139
Task<MappingModel> GetMappingAsync([Path] Guid guid, CancellationToken cancellationToken = default);
140140

141+
/// <summary>
142+
/// Get a mapping based on the guid.
143+
/// </summary>
144+
/// <param name="guid">The Guid</param>
145+
/// <returns>MappingModel</returns>
146+
/// <param name="cancellationToken">The optional cancellationToken.</param>
147+
[Get("mappings/{guid}")]
148+
Task<MappingModel> GetMappingAsync([Path] string guid, CancellationToken cancellationToken = default);
149+
141150
/// <summary>
142151
/// Get the C# code from a mapping based on the guid
143152
/// </summary>

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.WithHeaders.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public IResponseBuilder WithHeaders(IDictionary<string, WireMockList<string>> he
4949
public IResponseBuilder WithTrailingHeader(string name, params string[] values)
5050
{
5151
#if !TRAILINGHEADERS
52-
throw new System.NotSupportedException("The WithBodyAsProtoBuf method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
52+
throw new System.NotSupportedException("The WithTrailingHeader method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
5353
#else
5454

5555
Guard.NotNull(name);
@@ -63,7 +63,7 @@ public IResponseBuilder WithTrailingHeader(string name, params string[] values)
6363
public IResponseBuilder WithTrailingHeaders(IDictionary<string, string> headers)
6464
{
6565
#if !TRAILINGHEADERS
66-
throw new System.NotSupportedException("The WithBodyAsProtoBuf method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
66+
throw new System.NotSupportedException("The WithTrailingHeaders method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
6767
#else
6868

6969
Guard.NotNull(headers);
@@ -77,7 +77,7 @@ public IResponseBuilder WithTrailingHeaders(IDictionary<string, string> headers)
7777
public IResponseBuilder WithTrailingHeaders(IDictionary<string, string[]> headers)
7878
{
7979
#if !TRAILINGHEADERS
80-
throw new System.NotSupportedException("The WithBodyAsProtoBuf method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
80+
throw new System.NotSupportedException("The WithTrailingHeaders method can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
8181
#else
8282

8383
Guard.NotNull(headers);

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/MappingConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ public MappingModel ToMappingModel(IMapping mapping)
379379
}
380380

381381
var bodyMatchers =
382-
protoBufMatcher?.Matcher != null ? new[] { protoBufMatcher.Matcher } : null ??
382+
protoBufMatcher?.Matcher != null ? [protoBufMatcher.Matcher] : null ??
383383
multiPartMatcher?.Matchers ??
384384
graphQLMatcher?.Matchers ??
385385
bodyMatcher?.Matchers;

src/WireMock.Net/Serialization/MatcherMapper.cs

+3-21
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public MatcherMapper(WireMockServerSettings settings)
220220
{
221221
model.Pattern = texts[0];
222222
}
223-
else
223+
else if (texts.Count > 1)
224224
{
225225
model.Patterns = texts.Cast<object>().ToArray();
226226
}
@@ -296,27 +296,9 @@ private ProtoBufMatcher CreateProtoBufMatcher(MatchBehaviour? matchBehaviour, IR
296296
{
297297
var objectMatcher = Map(matcher.ContentMatcher) as IObjectMatcher;
298298

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

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

+8-23
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);
@@ -296,7 +297,7 @@ public IRespondWithAProvider WithWebhook(
296297
Guard.NotNull(url);
297298
Guard.NotNull(method);
298299

299-
Webhooks = new[] { InitWebhook(url, method, headers, useTransformer, transformerType) };
300+
Webhooks = [InitWebhook(url, method, headers, useTransformer, transformerType)];
300301

301302
if (body != null)
302303
{
@@ -323,7 +324,7 @@ public IRespondWithAProvider WithWebhook(
323324
Guard.NotNull(url);
324325
Guard.NotNull(method);
325326

326-
Webhooks = new[] { InitWebhook(url, method, headers, useTransformer, transformerType) };
327+
Webhooks = [InitWebhook(url, method, headers, useTransformer, transformerType)];
327328

328329
if (body != null)
329330
{
@@ -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
}

0 commit comments

Comments
 (0)