mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-22 09:09:02 +01:00
GraphQL - custom scalar support (#1012)
* x * CustomScalars * more tests * . * add or set * ... * x
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
#if GRAPHQL
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CSScripting;
|
||||
using FluentAssertions;
|
||||
using GraphQLParser.Exceptions;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
using Xunit;
|
||||
@@ -99,6 +102,62 @@ public class GraphQLMatcherTests
|
||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_CorrectGraphQL_UsingCustomType_Mutation_IsMatch()
|
||||
{
|
||||
// Arrange
|
||||
const string testSchema = @"
|
||||
scalar DateTime
|
||||
scalar MyCustomScalar
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(x: MyCustomScalar, dt: DateTime): Message
|
||||
}";
|
||||
|
||||
var input = @"{
|
||||
""query"": ""mutation CreateMessage($x: MyCustomScalar!, $dt: DateTime!) { createMessage(x: $x, dt: $dt) { id } }"",
|
||||
""variables"": { ""x"": 100, ""dt"": ""2007-12-03T10:15:30Z"" }
|
||||
}";
|
||||
|
||||
var customScalars = new Dictionary<string, Type> { { "MyCustomScalar", typeof(int) } };
|
||||
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(testSchema, customScalars);
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
|
||||
matcher.GetPatterns().Should().Contain(testSchema);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_CorrectGraphQL_UsingCustomType_But_NoDefinedCustomScalars_Mutation_IsNoMatch()
|
||||
{
|
||||
// Arrange
|
||||
const string testSchema = @"
|
||||
scalar DateTime
|
||||
scalar MyCustomScalar
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(x: MyCustomScalar, dt: DateTime): Message
|
||||
}";
|
||||
|
||||
// Act
|
||||
Action action = () => _ = new GraphQLMatcher(testSchema);
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<WireMockException>().WithMessage("The GraphQL Scalar type 'MyCustomScalar' is not defined in the CustomScalars dictionary.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQuery_IsMismatch()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#if GRAPHQL
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using WireMock.Matchers.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Matchers.Models;
|
||||
|
||||
public class WireMockCustomScalarGraphTypeTests
|
||||
{
|
||||
private class MyIntScalarGraphType : WireMockCustomScalarGraphType<int> { }
|
||||
|
||||
private class MyStringScalarGraphType : WireMockCustomScalarGraphType<string> { }
|
||||
|
||||
[Fact]
|
||||
public void ParseValue_ShouldReturnNull_When_ValueIsNull()
|
||||
{
|
||||
// Arrange
|
||||
var intGraphType = new MyIntScalarGraphType();
|
||||
|
||||
// Act
|
||||
var result = intGraphType.ParseValue(null);
|
||||
|
||||
// Assert
|
||||
result.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseValue_ShouldReturnValue_When_ValueIsOfCorrectType()
|
||||
{
|
||||
// Arrange
|
||||
var intGraphType = new MyIntScalarGraphType();
|
||||
|
||||
// Act
|
||||
var result = intGraphType.ParseValue(5);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(5);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("someString")]
|
||||
[InlineData("100")]
|
||||
public void ParseValue_ShouldThrowInvalidCastException_When_ValueIsStringAndTargetIsNotString(string stringValue)
|
||||
{
|
||||
// Arrange
|
||||
var intGraphType = new MyIntScalarGraphType();
|
||||
|
||||
// Act
|
||||
Action act = () => intGraphType.ParseValue(stringValue);
|
||||
|
||||
// Assert
|
||||
act.Should().Throw<InvalidCastException>()
|
||||
.WithMessage("Unable to convert value '*' of type 'System.String' to type 'System.Int32'.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseValue_ShouldConvertValue_WhenTypeIsConvertible()
|
||||
{
|
||||
// Arrange
|
||||
var intGraphType = new MyIntScalarGraphType();
|
||||
|
||||
// Act
|
||||
var result = intGraphType.ParseValue(5L);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(5);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseValue_ShouldThrowException_When_ValueIsMaxLongAndTargetIsInt()
|
||||
{
|
||||
// Arrange
|
||||
var intGraphType = new MyIntScalarGraphType();
|
||||
|
||||
// Act
|
||||
Action act = () => intGraphType.ParseValue(long.MaxValue);
|
||||
|
||||
// Assert
|
||||
act.Should().Throw<OverflowException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseValue_ShouldReturnStringValue_When_TypeIsString()
|
||||
{
|
||||
// Arrange
|
||||
var stringGraphType = new MyStringScalarGraphType();
|
||||
|
||||
// Act
|
||||
var result = stringGraphType.ParseValue("someString");
|
||||
|
||||
// Assert
|
||||
result.Should().Be("someString");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@ public class RequestMessageGraphQLMatcherTests
|
||||
[Fact]
|
||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatcher()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "b",
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AnyOfTypes;
|
||||
using FluentAssertions;
|
||||
using FluentAssertions.Execution;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NFluent;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
using WireMock.Serialization;
|
||||
@@ -165,6 +169,36 @@ public class MatcherMapperTests
|
||||
model.XmlNamespaceMap.Should().BeEquivalentTo(xmlNamespaceMap);
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_GraphQLMatcher()
|
||||
{
|
||||
// Assign
|
||||
const string testSchema = @"
|
||||
scalar DateTime
|
||||
scalar MyCustomScalar
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(x: MyCustomScalar, dt: DateTime): Message
|
||||
}";
|
||||
|
||||
var customScalars = new Dictionary<string, Type> { { "MyCustomScalar", typeof(string) } };
|
||||
var matcher = new GraphQLMatcher(testSchema, customScalars);
|
||||
|
||||
// Act
|
||||
var model = _sut.Map(matcher)!;
|
||||
|
||||
// Assert
|
||||
model.Name.Should().Be(nameof(GraphQLMatcher));
|
||||
model.Pattern.Should().Be(testSchema);
|
||||
model.CustomScalars.Should().BeEquivalentTo(customScalars);
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_Null()
|
||||
{
|
||||
@@ -463,26 +497,6 @@ public class MatcherMapperTests
|
||||
matcher.Regex.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_ExactMatcher_Pattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Pattern = "p",
|
||||
IgnoreCase = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
|
||||
matcher.GetPatterns().Should().Contain("p");
|
||||
matcher.IgnoreCase.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_NotNullOrEmptyMatcher()
|
||||
{
|
||||
@@ -585,4 +599,406 @@ public class MatcherMapperTests
|
||||
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
|
||||
matcher.XmlNamespaceMap.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_CSharpCodeMatcher()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "CSharpCodeMatcher",
|
||||
Patterns = new[] { "return it == \"x\";" }
|
||||
};
|
||||
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = true });
|
||||
|
||||
// Act 1
|
||||
var matcher1 = (ICSharpCodeMatcher)sut.Map(model)!;
|
||||
|
||||
// Assert 1
|
||||
matcher1.Should().NotBeNull();
|
||||
matcher1.IsMatch("x").Score.Should().Be(1.0d);
|
||||
|
||||
// Act 2
|
||||
var matcher2 = (ICSharpCodeMatcher)sut.Map(model)!;
|
||||
|
||||
// Assert 2
|
||||
matcher2.Should().NotBeNull();
|
||||
matcher2.IsMatch("x").Score.Should().Be(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_CSharpCodeMatcher_NotAllowed_ThrowsException()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "CSharpCodeMatcher",
|
||||
Patterns = new[] { "x" }
|
||||
};
|
||||
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = false });
|
||||
|
||||
// Act
|
||||
Action action = () => sut.Map(model);
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_ExactMatcher_Pattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Patterns = new[] { "x" }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.GetPatterns().Should().ContainSingle("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_ExactMatcher_Patterns()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Patterns = new[] { "x", "y" }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_JsonPartialMatcher_RegexFalse()
|
||||
{
|
||||
// Assign
|
||||
var pattern = "{ \"x\": 1 }";
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "JsonPartialMatcher",
|
||||
Regex = false,
|
||||
Pattern = pattern
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (JsonPartialMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
|
||||
matcher.IgnoreCase.Should().BeFalse();
|
||||
matcher.Value.Should().Be(pattern);
|
||||
matcher.Regex.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_JsonPartialMatcher_RegexTrue()
|
||||
{
|
||||
// Assign
|
||||
var pattern = "{ \"x\": 1 }";
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "JsonPartialMatcher",
|
||||
Regex = true,
|
||||
Pattern = pattern
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (JsonPartialMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
|
||||
matcher.IgnoreCase.Should().BeFalse();
|
||||
matcher.Value.Should().Be(pattern);
|
||||
matcher.Regex.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_ExactObjectMatcher_ValidBase64StringPattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactObjectMatcher",
|
||||
Patterns = new object[] { "c3RlZg==" }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactObjectMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.ValueAsBytes).ContainsExactly(new byte[] { 115, 116, 101, 102 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_ExactObjectMatcher_InvalidBase64StringPattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactObjectMatcher",
|
||||
Patterns = new object[] { "_" }
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Check.ThatCode(() => _sut.Map(model)).Throws<ArgumentException>();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(MatchOperator.Or, 1.0d)]
|
||||
[InlineData(MatchOperator.And, 0.0d)]
|
||||
[InlineData(MatchOperator.Average, 0.5d)]
|
||||
public void MatcherMapper_Map_MatcherModel_RegexMatcher(MatchOperator matchOperator, double expected)
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "RegexMatcher",
|
||||
Patterns = new[] { "x", "y" },
|
||||
IgnoreCase = true,
|
||||
MatchOperator = matchOperator.ToString()
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (RegexMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
|
||||
|
||||
var result = matcher.IsMatch("X");
|
||||
result.Score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(MatchOperator.Or, 1.0d)]
|
||||
[InlineData(MatchOperator.And, 0.0d)]
|
||||
[InlineData(MatchOperator.Average, 0.5d)]
|
||||
public void MatcherMapper_Map_MatcherModel_WildcardMatcher_IgnoreCase(MatchOperator matchOperator, double expected)
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "WildcardMatcher",
|
||||
Patterns = new[] { "x", "y" },
|
||||
IgnoreCase = true,
|
||||
MatchOperator = matchOperator.ToString()
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (WildcardMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
|
||||
|
||||
var result = matcher.IsMatch("X");
|
||||
result.Score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_WildcardMatcher_With_PatternAsFile()
|
||||
{
|
||||
// Arrange
|
||||
var file = "c:\\test.txt";
|
||||
var fileContent = "c";
|
||||
var stringPattern = new StringPattern
|
||||
{
|
||||
Pattern = fileContent,
|
||||
PatternAsFile = file
|
||||
};
|
||||
var fileSystemHandleMock = new Mock<IFileSystemHandler>();
|
||||
fileSystemHandleMock.Setup(f => f.ReadFileAsString(file)).Returns(fileContent);
|
||||
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "WildcardMatcher",
|
||||
PatternAsFile = file
|
||||
};
|
||||
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
FileSystemHandler = fileSystemHandleMock.Object
|
||||
};
|
||||
var sut = new MatcherMapper(settings);
|
||||
|
||||
// Act
|
||||
var matcher = (WildcardMatcher)sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.GetPatterns().Should().HaveCount(1).And.Contain(new AnyOf<string, StringPattern>(stringPattern));
|
||||
|
||||
var result = matcher.IsMatch("c");
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_SimMetricsMatcher()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "SimMetricsMatcher",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (SimMetricsMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_SimMetricsMatcher_BlockDistance()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "SimMetricsMatcher.BlockDistance",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (SimMetricsMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_SimMetricsMatcher_Throws1()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "error",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
Check.ThatCode(() => _sut.Map(model)).Throws<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_SimMetricsMatcher_Throws2()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "SimMetricsMatcher.error",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
Check.ThatCode(() => _sut.Map(model)).Throws<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_MatcherModelToCustomMatcher()
|
||||
{
|
||||
// Arrange
|
||||
var patternModel = new CustomPathParamMatcherModel("/customer/{customerId}/document/{documentId}",
|
||||
new Dictionary<string, string>(2)
|
||||
{
|
||||
{ "customerId", @"^[0-9]+$" },
|
||||
{ "documentId", @"^[0-9a-zA-Z\-\_]+\.[a-zA-Z]+$" }
|
||||
});
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = nameof(CustomPathParamMatcher),
|
||||
Pattern = JsonConvert.SerializeObject(patternModel)
|
||||
};
|
||||
|
||||
var settings = new WireMockServerSettings();
|
||||
settings.CustomMatcherMappings = settings.CustomMatcherMappings ?? new Dictionary<string, Func<MatcherModel, IMatcher>>();
|
||||
settings.CustomMatcherMappings[nameof(CustomPathParamMatcher)] = matcherModel =>
|
||||
{
|
||||
var matcherParams = JsonConvert.DeserializeObject<CustomPathParamMatcherModel>((string)matcherModel.Pattern!)!;
|
||||
return new CustomPathParamMatcher(
|
||||
matcherModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||
matcherParams.Path,
|
||||
matcherParams.PathParams
|
||||
);
|
||||
};
|
||||
var sut = new MatcherMapper(settings);
|
||||
|
||||
// Act
|
||||
var matcher = sut.Map(model) as CustomPathParamMatcher;
|
||||
|
||||
// Assert
|
||||
matcher.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_CustomMatcherToMatcherModel()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new CustomPathParamMatcher("/customer/{customerId}/document/{documentId}",
|
||||
new Dictionary<string, string>(2)
|
||||
{
|
||||
{ "customerId", @"^[0-9]+$" },
|
||||
{ "documentId", @"^[0-9a-zA-Z\-\_]+\.[a-zA-Z]+$" }
|
||||
});
|
||||
|
||||
// Act
|
||||
var model = _sut.Map(matcher)!;
|
||||
|
||||
// Assert
|
||||
using (new AssertionScope())
|
||||
{
|
||||
model.Should().NotBeNull();
|
||||
model.Name.Should().Be(nameof(CustomPathParamMatcher));
|
||||
|
||||
var matcherParams = JsonConvert.DeserializeObject<CustomPathParamMatcherModel>((string)model.Pattern!)!;
|
||||
matcherParams.Path.Should().Be("/customer/{customerId}/document/{documentId}");
|
||||
matcherParams.PathParams.Should().BeEquivalentTo(new Dictionary<string, string>(2)
|
||||
{
|
||||
{ "customerId", @"^[0-9]+$" },
|
||||
{ "documentId", @"^[0-9a-zA-Z\-\_]+\.[a-zA-Z]+$" }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
[Fact]
|
||||
public void MatcherMapper_Map_MatcherModel_GraphQLMatcher()
|
||||
{
|
||||
// Arrange
|
||||
const string testSchema = @"
|
||||
scalar DateTime
|
||||
scalar MyCustomScalar
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(x: MyCustomScalar, dt: DateTime): Message
|
||||
}";
|
||||
|
||||
var customScalars = new Dictionary<string, Type> { { "MyCustomScalar", typeof(string) } };
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = nameof(GraphQLMatcher),
|
||||
Pattern = testSchema,
|
||||
CustomScalars = customScalars
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (GraphQLMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.GetPatterns().Should().HaveElementAt(0, testSchema);
|
||||
matcher.Name.Should().Be(nameof(GraphQLMatcher));
|
||||
matcher.CustomScalars.Should().BeEquivalentTo(customScalars);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,406 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AnyOfTypes;
|
||||
using FluentAssertions;
|
||||
using FluentAssertions.Execution;
|
||||
using Moq;
|
||||
using Newtonsoft.Json;
|
||||
using NFluent;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
using WireMock.Serialization;
|
||||
using WireMock.Settings;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Serialization;
|
||||
|
||||
public class MatcherModelMapperTests
|
||||
{
|
||||
private readonly WireMockServerSettings _settings = new();
|
||||
|
||||
private readonly MatcherMapper _sut;
|
||||
|
||||
public MatcherModelMapperTests()
|
||||
{
|
||||
_sut = new MatcherMapper(_settings);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_CSharpCodeMatcher()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "CSharpCodeMatcher",
|
||||
Patterns = new[] { "return it == \"x\";" }
|
||||
};
|
||||
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = true });
|
||||
|
||||
// Act 1
|
||||
var matcher1 = (ICSharpCodeMatcher)sut.Map(model)!;
|
||||
|
||||
// Assert 1
|
||||
matcher1.Should().NotBeNull();
|
||||
matcher1.IsMatch("x").Score.Should().Be(1.0d);
|
||||
|
||||
// Act 2
|
||||
var matcher2 = (ICSharpCodeMatcher)sut.Map(model)!;
|
||||
|
||||
// Assert 2
|
||||
matcher2.Should().NotBeNull();
|
||||
matcher2.IsMatch("x").Score.Should().Be(1.0d);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_CSharpCodeMatcher_NotAllowed_ThrowsException()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "CSharpCodeMatcher",
|
||||
Patterns = new[] { "x" }
|
||||
};
|
||||
var sut = new MatcherMapper(new WireMockServerSettings { AllowCSharpCodeMatcher = false });
|
||||
|
||||
// Act
|
||||
Action action = () => sut.Map(model);
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_Null()
|
||||
{
|
||||
// Act
|
||||
IMatcher matcher = _sut.Map((MatcherModel?)null)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher).IsNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_ExactMatcher_Pattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Patterns = new[] { "x" }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.GetPatterns().Should().ContainSingle("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_ExactMatcher_Patterns()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactMatcher",
|
||||
Patterns = new[] { "x", "y" }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_JsonPartialMatcher_RegexFalse()
|
||||
{
|
||||
// Assign
|
||||
var pattern = "{ \"x\": 1 }";
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "JsonPartialMatcher",
|
||||
Regex = false,
|
||||
Pattern = pattern
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (JsonPartialMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
|
||||
matcher.IgnoreCase.Should().BeFalse();
|
||||
matcher.Value.Should().Be(pattern);
|
||||
matcher.Regex.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_JsonPartialMatcher_RegexTrue()
|
||||
{
|
||||
// Assign
|
||||
var pattern = "{ \"x\": 1 }";
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "JsonPartialMatcher",
|
||||
Regex = true,
|
||||
Pattern = pattern
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (JsonPartialMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.MatchBehaviour.Should().Be(MatchBehaviour.AcceptOnMatch);
|
||||
matcher.IgnoreCase.Should().BeFalse();
|
||||
matcher.Value.Should().Be(pattern);
|
||||
matcher.Regex.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_ExactObjectMatcher_ValidBase64StringPattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactObjectMatcher",
|
||||
Patterns = new object[] { "c3RlZg==" }
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (ExactObjectMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.ValueAsBytes).ContainsExactly(new byte[] { 115, 116, 101, 102 });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_ExactObjectMatcher_InvalidBase64StringPattern()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "ExactObjectMatcher",
|
||||
Patterns = new object[] { "_" }
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
Check.ThatCode(() => _sut.Map(model)).Throws<ArgumentException>();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(MatchOperator.Or, 1.0d)]
|
||||
[InlineData(MatchOperator.And, 0.0d)]
|
||||
[InlineData(MatchOperator.Average, 0.5d)]
|
||||
public void MatcherModelMapper_Map_RegexMatcher(MatchOperator matchOperator, double expected)
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "RegexMatcher",
|
||||
Patterns = new[] { "x", "y" },
|
||||
IgnoreCase = true,
|
||||
MatchOperator = matchOperator.ToString()
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (RegexMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
|
||||
|
||||
var result = matcher.IsMatch("X");
|
||||
result.Score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(MatchOperator.Or, 1.0d)]
|
||||
[InlineData(MatchOperator.And, 0.0d)]
|
||||
[InlineData(MatchOperator.Average, 0.5d)]
|
||||
public void MatcherModelMapper_Map_WildcardMatcher_IgnoreCase(MatchOperator matchOperator, double expected)
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "WildcardMatcher",
|
||||
Patterns = new[] { "x", "y" },
|
||||
IgnoreCase = true,
|
||||
MatchOperator = matchOperator.ToString()
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (WildcardMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x", "y");
|
||||
|
||||
var result = matcher.IsMatch("X");
|
||||
result.Score.Should().Be(expected);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_WildcardMatcher_With_PatternAsFile()
|
||||
{
|
||||
// Arrange
|
||||
var file = "c:\\test.txt";
|
||||
var fileContent = "c";
|
||||
var stringPattern = new StringPattern
|
||||
{
|
||||
Pattern = fileContent,
|
||||
PatternAsFile = file
|
||||
};
|
||||
var fileSystemHandleMock = new Mock<IFileSystemHandler>();
|
||||
fileSystemHandleMock.Setup(f => f.ReadFileAsString(file)).Returns(fileContent);
|
||||
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "WildcardMatcher",
|
||||
PatternAsFile = file
|
||||
};
|
||||
|
||||
var settings = new WireMockServerSettings
|
||||
{
|
||||
FileSystemHandler = fileSystemHandleMock.Object
|
||||
};
|
||||
var sut = new MatcherMapper(settings);
|
||||
|
||||
// Act
|
||||
var matcher = (WildcardMatcher)sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
matcher.GetPatterns().Should().HaveCount(1).And.Contain(new AnyOf<string, StringPattern>(stringPattern));
|
||||
|
||||
var result = matcher.IsMatch("c");
|
||||
result.Score.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_SimMetricsMatcher()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "SimMetricsMatcher",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (SimMetricsMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_SimMetricsMatcher_BlockDistance()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "SimMetricsMatcher.BlockDistance",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = (SimMetricsMatcher)_sut.Map(model)!;
|
||||
|
||||
// Assert
|
||||
Check.That(matcher.GetPatterns()).ContainsExactly("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_SimMetricsMatcher_Throws1()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "error",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
Check.ThatCode(() => _sut.Map(model)).Throws<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_SimMetricsMatcher_Throws2()
|
||||
{
|
||||
// Assign
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = "SimMetricsMatcher.error",
|
||||
Pattern = "x"
|
||||
};
|
||||
|
||||
// Act
|
||||
Check.ThatCode(() => _sut.Map(model)).Throws<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_MatcherModelToCustomMatcher()
|
||||
{
|
||||
// Arrange
|
||||
var patternModel = new CustomPathParamMatcherModel("/customer/{customerId}/document/{documentId}",
|
||||
new Dictionary<string, string>(2)
|
||||
{
|
||||
{ "customerId", @"^[0-9]+$" },
|
||||
{ "documentId", @"^[0-9a-zA-Z\-\_]+\.[a-zA-Z]+$" }
|
||||
});
|
||||
var model = new MatcherModel
|
||||
{
|
||||
Name = nameof(CustomPathParamMatcher),
|
||||
Pattern = JsonConvert.SerializeObject(patternModel)
|
||||
};
|
||||
|
||||
var settings = new WireMockServerSettings();
|
||||
settings.CustomMatcherMappings = settings.CustomMatcherMappings ?? new Dictionary<string, Func<MatcherModel, IMatcher>>();
|
||||
settings.CustomMatcherMappings[nameof(CustomPathParamMatcher)] = matcherModel =>
|
||||
{
|
||||
var matcherParams = JsonConvert.DeserializeObject<CustomPathParamMatcherModel>((string)matcherModel.Pattern!)!;
|
||||
return new CustomPathParamMatcher(
|
||||
matcherModel.RejectOnMatch == true ? MatchBehaviour.RejectOnMatch : MatchBehaviour.AcceptOnMatch,
|
||||
matcherParams.Path,
|
||||
matcherParams.PathParams
|
||||
);
|
||||
};
|
||||
var sut = new MatcherMapper(settings);
|
||||
|
||||
// Act
|
||||
var matcher = sut.Map(model) as CustomPathParamMatcher;
|
||||
|
||||
// Assert
|
||||
matcher.Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MatcherModelMapper_Map_CustomMatcherToMatcherModel()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new CustomPathParamMatcher("/customer/{customerId}/document/{documentId}",
|
||||
new Dictionary<string, string>(2)
|
||||
{
|
||||
{ "customerId", @"^[0-9]+$" },
|
||||
{ "documentId", @"^[0-9a-zA-Z\-\_]+\.[a-zA-Z]+$" }
|
||||
});
|
||||
|
||||
// Act
|
||||
var model = _sut.Map(matcher)!;
|
||||
|
||||
// Assert
|
||||
using (new AssertionScope())
|
||||
{
|
||||
model.Should().NotBeNull();
|
||||
model.Name.Should().Be(nameof(CustomPathParamMatcher));
|
||||
|
||||
var matcherParams = JsonConvert.DeserializeObject<CustomPathParamMatcherModel>((string)model.Pattern!)!;
|
||||
matcherParams.Path.Should().Be("/customer/{customerId}/document/{documentId}");
|
||||
matcherParams.PathParams.Should().BeEquivalentTo(new Dictionary<string, string>(2)
|
||||
{
|
||||
{ "customerId", @"^[0-9]+$" },
|
||||
{ "documentId", @"^[0-9a-zA-Z\-\_]+\.[a-zA-Z]+$" }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user