Skip to content

Commit

Permalink
x
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Dec 29, 2023
1 parent 84deb58 commit 49d1877
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 43 deletions.
19 changes: 19 additions & 0 deletions examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,25 @@ public static void Run()
.WithTrailingHeader("grpc-status", "0")
.WithTransformer()
);

server
.Given(Request.Create()
.UsingPost()
.WithPath("/grpc2/greet.Greeter/SayHello")
.WithBodyAsProtoBuf("greet.HelloRequest", protoBufJsonMatcher)
)
.WithProtoDefinition(ProtoDefinition)
.RespondWith(Response.Create()
.WithHeader("Content-Type", "application/grpc")
.WithBodyAsProtoBuf("greet.HelloReply",
new
{
message = "hello stef"
}
)
.WithTrailingHeader("grpc-status", "0")
.WithTransformer()
);
#endif

#if GRAPHQL
Expand Down
5 changes: 5 additions & 0 deletions src/WireMock.Net.Abstractions/Admin/Mappings/MappingModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,9 @@ public class MappingModel
/// The probability when this request should be matched. Value is between 0 and 1. [Optional]
/// </summary>
public double? Probability { get; set; }

/// <summary>
/// The Grpc ProtoDefinition which is used for this mapping (request and response). [Optional]
/// </summary>
public string? ProtoDefinition { get; set; }
}
2 changes: 1 addition & 1 deletion src/WireMock.Net.Abstractions/Models/IBodyData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public interface IBodyData
/// <summary>
/// Gets or sets the proto definition.
/// </summary>
public Func<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
17 changes: 17 additions & 0 deletions src/WireMock.Net/Enums/ValueSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace WireMock.Enums;

/// <summary>
/// ValueSource
/// </summary>
public enum ValueSource
{
/// <summary>
/// From the Mapping
/// </summary>
FromMapping,

/// <summary>
/// From the Request
/// </summary>
FromRequest
}
2 changes: 1 addition & 1 deletion src/WireMock.Net/Models/BodyData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class BodyData : IBodyData

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

/// <inheritdoc />
public string? ProtoBufMessageType { get; set; }
Expand Down
3 changes: 2 additions & 1 deletion src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Threading.Tasks;
using JsonConverter.Abstractions;
using Stef.Validation;
using WireMock.Exceptions;
using WireMock.Types;
using WireMock.Util;

Expand Down Expand Up @@ -254,7 +255,7 @@ public IResponseBuilder WithBodyAsProtoBuf(
{
DetectedBodyType = BodyType.ProtoBuf,
BodyAsJson = value,
ProtoDefinition = () => Mapping.ProtoDefinition,
ProtoDefinition = () => Mapping.ProtoDefinition ?? throw new WireMockException("ProtoDefinition cannot be resolved. You probably forgot to call .WithProtoDefinition(...) on the mapping."),
ProtoBufMessageType = messageType
};
#endif
Expand Down
23 changes: 20 additions & 3 deletions src/WireMock.Net/Serialization/MappingConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ public MappingModel ToMappingModel(IMapping mapping)
WhenStateIs = mapping.ExecutionConditionState,
SetStateTo = mapping.NextState,
Data = mapping.Data,
ProtoDefinition = mapping.ProtoDefinition,
Probability = mapping.Probability,
Request = new RequestModel
{
Expand Down Expand Up @@ -370,15 +371,26 @@ public MappingModel ToMappingModel(IMapping mapping)

if (bodyMatchers != null)
{
void AfterMap(MatcherModel matcherModel)
{
#if PROTOBUF
// In case the ProtoDefinition is defined at the Mapping level, clear the Pattern at the Matcher level
if (bodyMatchers?.OfType<ProtoBufMatcher>().Any() == true && mappingModel.ProtoDefinition != null)
{
matcherModel.Pattern = null;
}
#endif
}

mappingModel.Request.Body = new BodyModel();

if (bodyMatchers.Length == 1)
{
mappingModel.Request.Body.Matcher = _mapper.Map(bodyMatchers[0]);
mappingModel.Request.Body.Matcher = _mapper.Map(bodyMatchers[0], AfterMap);
}
else if (bodyMatchers.Length > 1)
{
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatchers);
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatchers, AfterMap);
mappingModel.Request.Body.MatchOperator = matchOperator.ToString();
}
}
Expand Down Expand Up @@ -471,7 +483,12 @@ private static void MapResponse(Response response, MappingModel mappingModel)
break;

case BodyType.ProtoBuf:
mappingModel.Response.ProtoDefinition = response.ResponseMessage.BodyData.ProtoDefinition?.Invoke();
// If the ProtoDefinition is not defined at the MappingModel, get the ProtoDefinition from the ResponseMessage.
if (mappingModel.ProtoDefinition == null)
{
mappingModel.Response.ProtoDefinition = response.ResponseMessage.BodyData.ProtoDefinition?.Invoke();
}

mappingModel.Response.ProtoBufMessageType = response.ResponseMessage.BodyData.ProtoBufMessageType;
mappingModel.Response.BodyAsBytes = null;
mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyData.BodyAsJson;
Expand Down
8 changes: 5 additions & 3 deletions src/WireMock.Net/Serialization/MatcherMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,12 @@ public MatcherMapper(WireMockServerSettings settings)
}
}

public MatcherModel[]? Map(IEnumerable<IMatcher>? matchers)
public MatcherModel[]? Map(IEnumerable<IMatcher>? matchers, Action<MatcherModel>? afterMap = null)
{
return matchers?.Select(Map).OfType<MatcherModel>().ToArray();
return matchers?.Select(m => Map(m, afterMap)).OfType<MatcherModel>().ToArray();
}

public MatcherModel? Map(IMatcher? matcher)
public MatcherModel? Map(IMatcher? matcher, Action<MatcherModel>? afterMap = null)
{
if (matcher == null)
{
Expand Down Expand Up @@ -218,6 +218,8 @@ public MatcherMapper(WireMockServerSettings settings)
#endif
}

afterMap?.Invoke(model);

return model;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
Guid: Guid_1,
UpdatedAt: DateTime_1,
Title: ,
Description: ,
Priority: 41,
Request: {
Path: {
Matchers: [
{
Name: WildcardMatcher,
Pattern: /grpc/greet.Greeter/SayHello,
IgnoreCase: false
}
]
},
Methods: [
POST
],
Body: {
Matcher: {
Name: ProtoBufMatcher,
ContentMatcher: {
Name: JsonMatcher,
Pattern: {
name: stef
},
IgnoreCase: false
},
ProtoBufMessageType: greet.HelloRequest
}
}
},
Response: {
BodyAsJson: {
message: hello
},
TrailingHeaders: {
grpc-status: 0
},
ProtoBufMessageType: greet.HelloReply
},
UseWebhooksFireAndForget: false,
ProtoDefinition:
syntax = "proto3";

package greet;

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
string name = 1;
}

message HelloReply {
string message = 1;
}

}
86 changes: 52 additions & 34 deletions test/WireMock.Net.Tests/Serialization/MappingConverterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ public partial class MappingConverterTests
private readonly Guid _guid = new("c8eeaf99-d5c4-4341-8543-4597c3fd40d9");
private readonly DateTime _updatedAt = new(2022, 12, 4, 11, 12, 13);
private readonly WireMockServerSettings _settings = new();
private const string ProtoDefinition = @"
syntax = ""proto3"";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
";

private readonly MappingConverter _sut;

Expand Down Expand Up @@ -550,29 +567,12 @@ type Student {
public Task ToMappingModel_Request_WithBodyAsProtoBuf_ReturnsCorrectModel()
{
// Arrange
const string protoDefinition = @"
syntax = ""proto3"";
package greet;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
";
var jsonMatcher = new JsonMatcher(new { name = "stef" });

var request = Request.Create()
.UsingPost()
.WithPath("/grpc/greet.Greeter/SayHello")
.WithBodyAsProtoBuf(protoDefinition, "greet.HelloRequest", jsonMatcher);
.WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloRequest", jsonMatcher);

var response = Response.Create();

Expand All @@ -592,35 +592,53 @@ message HelloReply {
public Task ToMappingModel_Response_WithBodyAsProtoBuf_ReturnsCorrectModel()
{
// Arrange
const string protoDefinition = @"
syntax = ""proto3"";
var protobufResponse = new
{
message = "hello"
};

package greet;
var request = Request.Create();

service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
var response = Response.Create()
.WithBodyAsProtoBuf(ProtoDefinition, "greet.HelloReply", protobufResponse)
.WithTrailingHeader("grpc-status", "0");

message HelloRequest {
string name = 1;
}
var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 43, null, null, null, null, null, false, null, null);

message HelloReply {
string message = 1;
}
";
// Act
var model = _sut.ToMappingModel(mapping);

// Assert
model.Should().NotBeNull();

// Verify
return Verifier.Verify(model);
}

[Fact]
public Task ToMappingModel_Mapping_WithBodyAsProtoBuf_ReturnsCorrectModel()
{
// Arrange
var jsonMatcher = new JsonMatcher(new { name = "stef" });
var protobufResponse = new
{
message = "hello"
};

var request = Request.Create();
var request = Request.Create()
.UsingPost()
.WithPath("/grpc/greet.Greeter/SayHello")
.WithBodyAsProtoBuf("greet.HelloRequest", jsonMatcher);

var response = Response.Create()
.WithBodyAsProtoBuf(protoDefinition, "greet.HelloReply", protobufResponse)
.WithBodyAsProtoBuf("greet.HelloReply", protobufResponse)
.WithTrailingHeader("grpc-status", "0");

var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 43, null, null, null, null, null, false, null, null);
var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 41, null, null, null, null, null, false, null, null)
.WithProtoDefinition(ProtoDefinition);

((Request)request).Mapping = mapping;
((Response)response).Mapping = mapping;

// Act
var model = _sut.ToMappingModel(mapping);
Expand Down

0 comments on commit 49d1877

Please sign in to comment.