Skip to content

Commit

Permalink
Update WireMockProtoFileResolver and add tests for ProtoBufUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
StefH committed Feb 1, 2025
1 parent 29bf9b4 commit e7a8f4d
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 7 deletions.
35 changes: 28 additions & 7 deletions src/WireMock.Net/Util/WireMockProtoFileResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,37 @@

#if PROTOBUF
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using ProtoBufJsonConverter;
using Stef.Validation;

namespace WireMock.Util;

/// <summary>
/// This resolver is used to resolve the extra ProtoDefinition files.
/// It assumes that:
/// - the first ProtoDefinition file is the main ProtoDefinition file.
/// - the first commented line of each extra ProtoDefinition file is the filename which is used in the import of the other ProtoDefinition file(s).
/// </summary>
internal class WireMockProtoFileResolver : IProtoFileResolver
{
private readonly Dictionary<string, string> _files = new();

public WireMockProtoFileResolver(IReadOnlyCollection<string> protoDefinitions)
{
if (Guard.NotNullOrEmpty(protoDefinitions).Count() > 1)
if (Guard.NotNullOrEmpty(protoDefinitions).Count() <= 1)
{
foreach (var extraProtoDefinition in protoDefinitions.Skip(1))
return;
}

foreach (var extraProtoDefinition in protoDefinitions.Skip(1))
{
var firstNonEmptyLine = extraProtoDefinition.Split(['\r', '\n']).FirstOrDefault(l => !string.IsNullOrEmpty(l));
if (firstNonEmptyLine != null && TryGetValidFileName(firstNonEmptyLine.TrimStart(['\r', '\n', '/', ' ']), out var validFileName))
{
var firstNonEmptyLine = extraProtoDefinition.Split(['\r', '\n']).FirstOrDefault(l => !string.IsNullOrEmpty(l));
if (firstNonEmptyLine != null)
{
_files.Add(firstNonEmptyLine.TrimStart(['\r', '\n', '/', ' ']), extraProtoDefinition);
}
_files.Add(validFileName, extraProtoDefinition);
}
}
}
Expand All @@ -42,5 +51,17 @@ public TextReader OpenText(string path)

throw new FileNotFoundException($"The ProtoDefinition '{path}' was not found.");
}

private static bool TryGetValidFileName(string fileName, [NotNullWhen(true)] out string? validFileName)
{
if (!fileName.Any(c => Path.GetInvalidFileNameChars().Contains(c)))
{
validFileName = fileName;
return true;
}

validFileName = null;
return false;
}
}
#endif
41 changes: 41 additions & 0 deletions test/WireMock.Net.Tests/Grpc/ProtoBufUtilsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright © WireMock.Net

#if PROTOBUF
using System;
using System.IO;
using System.Threading.Tasks;
using FluentAssertions;
using WireMock.Util;
using Xunit;

namespace WireMock.Net.Tests.Grpc;

public class ProtoBufUtilsTests
{
[Fact]
public async Task GetProtoBufMessageWithHeader_MultipleProtoFiles()
{
// Arrange
var greet = await ReadProtoFileAsync("greet1.proto");
var request = await ReadProtoFileAsync("request.proto");

// Act
var responseBytes = await ProtoBufUtils.GetProtoBufMessageWithHeaderAsync(
[greet, request],
"greet.HelloRequest",
new
{
name = "hello"
}
);

// Assert
Convert.ToBase64String(responseBytes).Should().Be("AAAAAAcKBWhlbGxv");
}

private static Task<string> ReadProtoFileAsync(string filename)
{
return File.ReadAllTextAsync(Path.Combine(Directory.GetCurrentDirectory(), "Grpc", filename));
}
}
#endif
13 changes: 13 additions & 0 deletions test/WireMock.Net.Tests/Grpc/greet1.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
syntax = "proto3";

import "request.proto";

package greet;

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

message HelloReply {
string message = 1;
}
8 changes: 8 additions & 0 deletions test/WireMock.Net.Tests/Grpc/request.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// request.proto
syntax = "proto3";

package greet;

message HelloRequest {
string name = 1;
}
8 changes: 8 additions & 0 deletions test/WireMock.Net.Tests/WireMock.Net.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@
<None Update="cert.pem">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Grpc\request.proto">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<!--<GrpcServices>Client</GrpcServices>-->
</None>
<None Update="Grpc\greet1.proto">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<!--<GrpcServices>Client</GrpcServices>-->
</None>
<None Update="Grpc\policy.proto">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<GrpcServices>Client</GrpcServices>
Expand Down

0 comments on commit e7a8f4d

Please sign in to comment.