mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-13 13:53:34 +01:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c51548d2b | ||
|
|
98b8ede826 | ||
|
|
a6f3f976af | ||
|
|
b495eb83b1 | ||
|
|
9443e4f071 | ||
|
|
7a914481e5 | ||
|
|
1ad836659d | ||
|
|
ed7f9c1143 | ||
|
|
c92183558b | ||
|
|
8ce24249d0 | ||
|
|
7ca70309cb | ||
|
|
5d0bf6f4e1 |
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,3 +1,23 @@
|
||||
# 1.5.32 (15 July 2023)
|
||||
- [#966](https://github.com/WireMock-Net/WireMock.Net/pull/966) - Fixed JsonPathMatcher to match nested objects [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#965](https://github.com/WireMock-Net/WireMock.Net/issues/965) - JsonPathMatcher does not match json body nested objects [bug]
|
||||
- [#967](https://github.com/WireMock-Net/WireMock.Net/issues/967) - ⭐10 million downloads ! ⭐ [feature]
|
||||
|
||||
# 1.5.31 (08 July 2023)
|
||||
- [#964](https://github.com/WireMock-Net/WireMock.Net/pull/964) - Add GraphQL Schema matching [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
# 1.5.30 (28 June 2023)
|
||||
- [#959](https://github.com/WireMock-Net/WireMock.Net/pull/959) - Fixed logic for FluentAssertions WithHeader [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#961](https://github.com/WireMock-Net/WireMock.Net/pull/961) - Add unit-test for Param MatcherModel LinqMatcher [test] contributed by [StefH](https://github.com/StefH)
|
||||
- [#962](https://github.com/WireMock-Net/WireMock.Net/pull/962) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.Console.Net472.Classic [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#963](https://github.com/WireMock-Net/WireMock.Net/pull/963) - Bump System.Linq.Dynamic.Core from 1.2.23 to 1.3.0 in /examples/WireMock.Net.StandAlone.Net461 [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#958](https://github.com/WireMock-Net/WireMock.Net/issues/958) - [FluentAssertions] Should().HaveReceivedACall().WithHeader() only checks the first header with the matching key. [bug]
|
||||
|
||||
# 1.5.29 (22 June 2023)
|
||||
- [#954](https://github.com/WireMock-Net/WireMock.Net/pull/954) - Support setting WireMockServerSettings via Environment [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#955](https://github.com/WireMock-Net/WireMock.Net/pull/955) - Fix some SonarCloud issues [refactor] contributed by [StefH](https://github.com/StefH)
|
||||
- [#953](https://github.com/WireMock-Net/WireMock.Net/issues/953) - How to use environment variable [feature]
|
||||
|
||||
# 1.5.28 (11 June 2023)
|
||||
- [#948](https://github.com/WireMock-Net/WireMock.Net/pull/948) - WireMock.Net.Testcontainers [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#951](https://github.com/WireMock-Net/WireMock.Net/pull/951) - Allow setting the Content-Length header for a HTTP method HEAD [feature] contributed by [StefH](https://github.com/StefH)
|
||||
@@ -950,7 +970,7 @@
|
||||
- [#86](https://github.com/WireMock-Net/WireMock.Net/issues/86) - Feature : Add FileSystemWatcher logic for watching static mapping files [feature]
|
||||
|
||||
# 1.0.2.13 (23 January 2018)
|
||||
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [vladimir-fed](https://github.com/vladimir-fed)
|
||||
- [#79](https://github.com/WireMock-Net/WireMock.Net/pull/79) - Fix missed content headers contributed by [volodymyr-fed](https://github.com/volodymyr-fed)
|
||||
- [#57](https://github.com/WireMock-Net/WireMock.Net/issues/57) - ProxyAndRecord does not save query-parameters, headers and body [bug]
|
||||
- [#78](https://github.com/WireMock-Net/WireMock.Net/issues/78) - WireMock not working when attempting to access from anything other than localhost.
|
||||
|
||||
@@ -977,7 +997,7 @@
|
||||
|
||||
# 1.0.2.7 (18 November 2017)
|
||||
- [#62](https://github.com/WireMock-Net/WireMock.Net/pull/62) - Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating contributed by [alastairtree](https://github.com/alastairtree)
|
||||
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [vladimir-fed](https://github.com/vladimir-fed)
|
||||
- [#63](https://github.com/WireMock-Net/WireMock.Net/pull/63) - Fix issue with concurrent logging contributed by [volodymyr-fed](https://github.com/volodymyr-fed)
|
||||
- [#27](https://github.com/WireMock-Net/WireMock.Net/issues/27) - New feature: Record and Save
|
||||
- [#42](https://github.com/WireMock-Net/WireMock.Net/issues/42) - Enhancement - Save/load request logs to/from disk [feature]
|
||||
- [#53](https://github.com/WireMock-Net/WireMock.Net/issues/53) - New feature request: Access to Owin pipeline
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.5.28</VersionPrefix>
|
||||
<VersionPrefix>1.5.32</VersionPrefix>
|
||||
<PackageIcon>WireMock.Net-Logo.png</PackageIcon>
|
||||
<PackageProjectUrl>https://github.com/WireMock-Net/WireMock.Net</PackageProjectUrl>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
rem https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
SET version=1.5.28
|
||||
SET version=1.5.32
|
||||
|
||||
GitHubReleaseNotes --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid doc duplicate --version %version% --token %GH_TOKEN%
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# 1.5.28 (11 June 2023)
|
||||
- #948 WireMock.Net.Testcontainers [feature]
|
||||
- #951 Allow setting the Content-Length header for a HTTP method HEAD [feature]
|
||||
# 1.5.32 (15 July 2023)
|
||||
- #966 Fixed JsonPathMatcher to match nested objects [bug]
|
||||
- #965 JsonPathMatcher does not match json body nested objects [bug]
|
||||
- #967 ⭐10 million downloads ! ⭐ [feature]
|
||||
|
||||
The full release notes can be found here: https://github.com/WireMock-Net/WireMock.Net/blob/master/CHANGELOG.md
|
||||
@@ -14,6 +14,7 @@
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PATCH/@EntryIndexedValue">PATCH</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=POST/@EntryIndexedValue">POST</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PUT/@EntryIndexedValue">PUT</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QL/@EntryIndexedValue">QL</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RSA/@EntryIndexedValue">RSA</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SSL/@EntryIndexedValue">SSL</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TE/@EntryIndexedValue">TE</s:String>
|
||||
|
||||
@@ -27,10 +27,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\WireMock.Net\WireMock.Net.csproj" />
|
||||
<!--<PackageReference Include="Handlebars.Net.Helpers" Version="2.*" />-->
|
||||
<PackageReference Include="log4net" Version="2.0.15" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -42,6 +42,36 @@ namespace WireMock.Net.ConsoleApplication
|
||||
|
||||
public static class MainApp
|
||||
{
|
||||
private const string TestSchema = @"
|
||||
input MessageInput {
|
||||
content: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
content: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(input: MessageInput): Message
|
||||
updateMessage(id: ID!, input: MessageInput): Message
|
||||
}
|
||||
|
||||
type Query {
|
||||
greeting:String
|
||||
students:[Student]
|
||||
studentById(id:ID!):Student
|
||||
}
|
||||
|
||||
type Student {
|
||||
id:ID!
|
||||
firstName:String
|
||||
lastName:String
|
||||
fullName:String
|
||||
}";
|
||||
|
||||
public static void Run()
|
||||
{
|
||||
var mappingBuilder = new MappingBuilder();
|
||||
@@ -137,6 +167,16 @@ namespace WireMock.Net.ConsoleApplication
|
||||
|
||||
// server.AllowPartialMapping();
|
||||
|
||||
server
|
||||
.Given(Request.Create()
|
||||
.WithPath("/graphql")
|
||||
.UsingPost()
|
||||
.WithGraphQLSchema(TestSchema)
|
||||
)
|
||||
.RespondWith(Response.Create()
|
||||
.WithBody("GraphQL is ok")
|
||||
);
|
||||
|
||||
// 400 ms
|
||||
server
|
||||
.Given(Request.Create()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="AnyOf" version="0.3.0" targetFramework="net472" />
|
||||
<package id="Fare" version="2.2.1" targetFramework="net472" />
|
||||
@@ -138,7 +138,7 @@
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="4.5.0" targetFramework="net472" />
|
||||
<package id="System.IdentityModel.Tokens.Jwt" version="6.25.0" targetFramework="net472" />
|
||||
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net472" />
|
||||
<package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net472" />
|
||||
<package id="System.Linq.Dynamic.Core" version="1.3.0" targetFramework="net472" />
|
||||
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
|
||||
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net472" />
|
||||
|
||||
@@ -29,7 +29,7 @@ static class Program
|
||||
|
||||
XmlConfigurator.Configure(LogRepository, new FileInfo("log4net.config"));
|
||||
|
||||
if (!WireMockServerSettingsParser.TryParseArguments(args, out var settings, new WireMockLog4NetLogger()))
|
||||
if (!WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, new WireMockLog4NetLogger()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Handlebars.Net" version="2.1.2" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net461" />
|
||||
@@ -68,7 +68,7 @@
|
||||
<package id="System.ComponentModel.Annotations" version="4.5.0" targetFramework="net461" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net461" />
|
||||
<package id="System.IO.Pipelines" version="4.5.3" targetFramework="net461" />
|
||||
<package id="System.Linq.Dynamic.Core" version="1.2.23" targetFramework="net461" />
|
||||
<package id="System.Linq.Dynamic.Core" version="1.3.0" targetFramework="net461" />
|
||||
<package id="System.Memory" version="4.5.4" targetFramework="net461" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net461" />
|
||||
<package id="System.Reflection.Metadata" version="1.6.0" targetFramework="net461" />
|
||||
|
||||
@@ -149,15 +149,15 @@ public class WireMockAssertions
|
||||
|
||||
using (new AssertionScope($"header \"{expectedKey}\" from requests sent with value(s)"))
|
||||
{
|
||||
var headerValues = _headers.First(h => h.Key == expectedKey).Value;
|
||||
var matchingHeaderValues = _headers.Where(h => h.Key == expectedKey).SelectMany(h => h.Value.ToArray()).ToArray();
|
||||
|
||||
if (expectedValues.Length == 1)
|
||||
{
|
||||
headerValues.Should().Contain(expectedValues.First(), because, becauseArgs);
|
||||
matchingHeaderValues.Should().Contain(expectedValues.First(), because, becauseArgs);
|
||||
}
|
||||
else
|
||||
{
|
||||
var trimmedHeaderValues = string.Join(",", headerValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
|
||||
var trimmedHeaderValues = string.Join(",", matchingHeaderValues.Select(x => x)).Split(',').Select(x => x.Trim()).ToList();
|
||||
foreach (var expectedValue in expectedValues)
|
||||
{
|
||||
trimmedHeaderValues.Should().Contain(expectedValue, because, becauseArgs);
|
||||
|
||||
@@ -320,14 +320,14 @@ internal class OpenApiPathsMapper
|
||||
var mappedHeaders = headers?.ToDictionary(
|
||||
item => item.Key,
|
||||
_ => GetExampleMatcherModel(null, _settings.HeaderPatternToUse).Pattern!
|
||||
);
|
||||
) ?? new Dictionary<string, object>();
|
||||
|
||||
if (!string.IsNullOrEmpty(responseContentType))
|
||||
{
|
||||
mappedHeaders.TryAdd(HeaderContentType, responseContentType!);
|
||||
}
|
||||
|
||||
return mappedHeaders?.Keys.Any() == true ? mappedHeaders : null;
|
||||
return mappedHeaders.Keys.Any() ? mappedHeaders : null;
|
||||
}
|
||||
|
||||
private IList<ParamModel>? MapQueryParameters(IEnumerable<OpenApiParameter> queryParameters)
|
||||
|
||||
@@ -47,9 +47,9 @@ public class WireMockOpenApiParser : IWireMockOpenApiParser
|
||||
|
||||
/// <inheritdoc />
|
||||
[PublicAPI]
|
||||
public IReadOnlyList<MappingModel> FromDocument(OpenApiDocument openApiDocument, WireMockOpenApiParserSettings? settings = null)
|
||||
public IReadOnlyList<MappingModel> FromDocument(OpenApiDocument document, WireMockOpenApiParserSettings? settings = null)
|
||||
{
|
||||
return new OpenApiPathsMapper(settings ?? new WireMockOpenApiParserSettings()).ToMappingModels(openApiDocument.Paths, openApiDocument.Servers);
|
||||
return new OpenApiPathsMapper(settings ?? new WireMockOpenApiParserSettings()).ToMappingModels(document.Paths, document.Servers);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -24,7 +25,7 @@ public static class StandAloneApp
|
||||
[PublicAPI]
|
||||
public static WireMockServer Start(WireMockServerSettings settings)
|
||||
{
|
||||
Guard.NotNull(settings, nameof(settings));
|
||||
Guard.NotNull(settings);
|
||||
|
||||
var server = WireMockServer.Start(settings);
|
||||
|
||||
@@ -42,7 +43,7 @@ public static class StandAloneApp
|
||||
[PublicAPI]
|
||||
public static WireMockServer Start(string[] args, IWireMockLogger? logger = null)
|
||||
{
|
||||
Guard.NotNull(args, nameof(args));
|
||||
Guard.NotNull(args);
|
||||
|
||||
if (TryStart(args, out var server, logger))
|
||||
{
|
||||
@@ -61,9 +62,9 @@ public static class StandAloneApp
|
||||
[PublicAPI]
|
||||
public static bool TryStart(string[] args, [NotNullWhen(true)] out WireMockServer? server, IWireMockLogger? logger = null)
|
||||
{
|
||||
Guard.NotNull(args, nameof(args));
|
||||
Guard.NotNull(args);
|
||||
|
||||
if (WireMockServerSettingsParser.TryParseArguments(args, out var settings, logger))
|
||||
if (WireMockServerSettingsParser.TryParseArguments(args, Environment.GetEnvironmentVariables(), out var settings, logger))
|
||||
{
|
||||
settings.Logger?.Info("Version [{0}]", Version);
|
||||
settings.Logger?.Debug("Server arguments [{0}]", string.Join(", ", args.Select(a => $"'{a}'")));
|
||||
|
||||
29
src/WireMock.Net/Extensions/DictionaryExtensions.cs
Normal file
29
src/WireMock.Net/Extensions/DictionaryExtensions.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Stef.Validation;
|
||||
|
||||
namespace WireMock.Extensions;
|
||||
|
||||
internal static class DictionaryExtensions
|
||||
{
|
||||
public static bool TryGetStringValue(this IDictionary dictionary, string key, [NotNullWhen(true)] out string? value)
|
||||
{
|
||||
Guard.NotNull(dictionary);
|
||||
|
||||
if (dictionary[key] is string valueIsString)
|
||||
{
|
||||
value = valueIsString;
|
||||
return true;
|
||||
}
|
||||
|
||||
var valueToString = dictionary[key]?.ToString();
|
||||
if (valueToString != null)
|
||||
{
|
||||
value = valueToString;
|
||||
return true;
|
||||
}
|
||||
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
139
src/WireMock.Net/Matchers/GraphQLMatcher.cs
Normal file
139
src/WireMock.Net/Matchers/GraphQLMatcher.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
#if GRAPHQL
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AnyOfTypes;
|
||||
using GraphQL;
|
||||
using GraphQL.Types;
|
||||
using Newtonsoft.Json;
|
||||
using Stef.Validation;
|
||||
using WireMock.Models;
|
||||
|
||||
namespace WireMock.Matchers;
|
||||
|
||||
/// <summary>
|
||||
/// GrapQLMatcher Schema Matcher
|
||||
/// </summary>
|
||||
/// <inheritdoc cref="IStringMatcher"/>
|
||||
public class GraphQLMatcher : IStringMatcher
|
||||
{
|
||||
private sealed class GraphQLRequest
|
||||
{
|
||||
public string? Query { get; set; }
|
||||
|
||||
public Dictionary<string, object?>? Variables { get; set; }
|
||||
}
|
||||
|
||||
private readonly AnyOf<string, StringPattern>[] _patterns;
|
||||
|
||||
private readonly ISchema _schema;
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchBehaviour MatchBehaviour { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool ThrowException { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LinqMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="schema">The schema.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="throwException">Throw an exception when the internal matching fails because of invalid input.</param>
|
||||
/// <param name="matchOperator">The <see cref="Matchers.MatchOperator"/> to use. (default = "Or")</param>
|
||||
public GraphQLMatcher(AnyOf<string, StringPattern, ISchema> schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch, bool throwException = false, MatchOperator matchOperator = MatchOperator.Or)
|
||||
{
|
||||
Guard.NotNull(schema);
|
||||
MatchBehaviour = matchBehaviour;
|
||||
ThrowException = throwException;
|
||||
MatchOperator = matchOperator;
|
||||
|
||||
var patterns = new List<AnyOf<string, StringPattern>>();
|
||||
switch (schema.CurrentType)
|
||||
{
|
||||
case AnyOfType.First:
|
||||
patterns.Add(schema.First);
|
||||
_schema = BuildSchema(schema);
|
||||
break;
|
||||
|
||||
case AnyOfType.Second:
|
||||
patterns.Add(schema.Second);
|
||||
_schema = BuildSchema(schema.Second.Pattern);
|
||||
break;
|
||||
|
||||
case AnyOfType.Third:
|
||||
_schema = schema.Third;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
_patterns = patterns.ToArray();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
var match = MatchScores.Mismatch;
|
||||
|
||||
try
|
||||
{
|
||||
var graphQLRequest = JsonConvert.DeserializeObject<GraphQLRequest>(input!)!;
|
||||
|
||||
var executionResult = new DocumentExecuter().ExecuteAsync(_ =>
|
||||
{
|
||||
_.ThrowOnUnhandledException = true;
|
||||
|
||||
_.Schema = _schema;
|
||||
_.Query = graphQLRequest.Query;
|
||||
|
||||
if (graphQLRequest.Variables != null)
|
||||
{
|
||||
_.Variables = new Inputs(graphQLRequest.Variables);
|
||||
}
|
||||
}).GetAwaiter().GetResult();
|
||||
|
||||
if (executionResult.Errors == null || executionResult.Errors.Count == 0)
|
||||
{
|
||||
match = MatchScores.Perfect;
|
||||
}
|
||||
else
|
||||
{
|
||||
var exceptions = executionResult.Errors.OfType<Exception>().ToArray();
|
||||
if (exceptions.Length == 1)
|
||||
{
|
||||
throw exceptions[0];
|
||||
}
|
||||
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (ThrowException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
public string Name => nameof(GraphQLMatcher);
|
||||
|
||||
private static ISchema BuildSchema(string schema)
|
||||
{
|
||||
return Schema.For(schema);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -121,6 +121,32 @@ public class JsonPathMatcher : IStringMatcher, IObjectMatcher
|
||||
|
||||
private double IsMatch(JToken jToken)
|
||||
{
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => jToken.SelectToken(pattern.GetPattern()) != null).ToArray(), MatchOperator);
|
||||
var array = ConvertJTokenToJArrayIfNeeded(jToken);
|
||||
|
||||
return MatchScores.ToScore(_patterns.Select(pattern => array.SelectToken(pattern.GetPattern())?.Any() == true).ToArray(), MatchOperator);
|
||||
}
|
||||
|
||||
// https://github.com/WireMock-Net/WireMock.Net/issues/965
|
||||
// https://stackoverflow.com/questions/66922188/newtonsoft-jsonpath-with-c-sharp-syntax
|
||||
// Filtering using SelectToken() isn't guaranteed to work for objects inside objects -- only objects inside arrays.
|
||||
// So this code checks if it's an JArray, if it's not an array, construct a new JArray.
|
||||
private static JToken ConvertJTokenToJArrayIfNeeded(JToken jToken)
|
||||
{
|
||||
if (jToken.Count() == 1)
|
||||
{
|
||||
var property = jToken.First();
|
||||
var item = property.First();
|
||||
if (item is JArray)
|
||||
{
|
||||
return jToken;
|
||||
}
|
||||
|
||||
return new JObject
|
||||
{
|
||||
[property.Path] = new JArray(item)
|
||||
};
|
||||
}
|
||||
|
||||
return jToken;
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.IsMatch"/>
|
||||
/// <inheritdoc />
|
||||
public double IsMatch(string? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
@@ -95,7 +95,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
/// <inheritdoc />
|
||||
public double IsMatch(object? input)
|
||||
{
|
||||
double match = MatchScores.Mismatch;
|
||||
@@ -110,41 +110,15 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
jArray = new JArray { JToken.FromObject(input) };
|
||||
}
|
||||
|
||||
//enumerable = jArray.ToDynamicClassArray();
|
||||
|
||||
//JObject value;
|
||||
//switch (input)
|
||||
//{
|
||||
// case JObject valueAsJObject:
|
||||
// value = valueAsJObject;
|
||||
// break;
|
||||
|
||||
// case { } valueAsObject:
|
||||
// value = JObject.FromObject(valueAsObject);
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// return MatchScores.Mismatch;
|
||||
//}
|
||||
|
||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||
//var queryable1 = new[] { value }.AsQueryable();
|
||||
var queryable = jArray.ToDynamicClassArray().AsQueryable();
|
||||
|
||||
try
|
||||
{
|
||||
// Generate the DynamicLinq select statement.
|
||||
//string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value);
|
||||
|
||||
// Execute DynamicLinq Select statement.
|
||||
//var queryable2 = queryable1.Select(dynamicSelect);
|
||||
|
||||
// Use the Any(...) method to check if the result matches.
|
||||
|
||||
var patternsAsStringArray = _patterns.Select(p => p.GetPattern()).ToArray();
|
||||
var scores = patternsAsStringArray.Select(p => queryable.Any(p)).ToArray();
|
||||
|
||||
match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern.GetPattern())).ToArray(), MatchOperator);
|
||||
match = MatchScores.ToScore(scores, MatchOperator);
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
@@ -159,7 +133,7 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
/// <inheritdoc />
|
||||
public AnyOf<string, StringPattern>[] GetPatterns()
|
||||
{
|
||||
return _patterns;
|
||||
@@ -168,6 +142,6 @@ public class LinqMatcher : IObjectMatcher, IStringMatcher
|
||||
/// <inheritdoc />
|
||||
public MatchOperator MatchOperator { get; }
|
||||
|
||||
/// <inheritdoc cref="IMatcher.Name"/>
|
||||
/// <inheritdoc />
|
||||
public string Name => "LinqMatcher";
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using System.Linq;
|
||||
using Stef.Validation;
|
||||
using WireMock.Types;
|
||||
|
||||
namespace WireMock.Matchers.Request;
|
||||
|
||||
/// <summary>
|
||||
/// The request body GraphQL matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageGraphQLMatcher : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// The matchers.
|
||||
/// </summary>
|
||||
public IMatcher[]? Matchers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="MatchOperator"/>
|
||||
/// </summary>
|
||||
public MatchOperator MatchOperator { get; } = MatchOperator.Or;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="schema">The schema.</param>
|
||||
public RequestMessageGraphQLMatcher(MatchBehaviour matchBehaviour, string schema) :
|
||||
this(CreateMatcherArray(matchBehaviour, schema))
|
||||
{
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchBehaviour">The match behaviour.</param>
|
||||
/// <param name="schema">The schema.</param>
|
||||
public RequestMessageGraphQLMatcher(MatchBehaviour matchBehaviour, GraphQL.Types.ISchema schema) :
|
||||
this(CreateMatcherArray(matchBehaviour, new AnyOfTypes.AnyOf<string, Models.StringPattern, GraphQL.Types.ISchema>(schema)))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
public RequestMessageGraphQLMatcher(params IMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageGraphQLMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="matchers">The matchers.</param>
|
||||
/// <param name="matchOperator">The <see cref="MatchOperator"/> to use.</param>
|
||||
public RequestMessageGraphQLMatcher(MatchOperator matchOperator, params IMatcher[] matchers)
|
||||
{
|
||||
Matchers = Guard.NotNull(matchers);
|
||||
MatchOperator = matchOperator;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public double GetMatchingScore(IRequestMessage requestMessage, IRequestMatchResult requestMatchResult)
|
||||
{
|
||||
var score = CalculateMatchScore(requestMessage);
|
||||
return requestMatchResult.AddScore(GetType(), score);
|
||||
}
|
||||
|
||||
private static double CalculateMatchScore(IRequestMessage requestMessage, IMatcher matcher)
|
||||
{
|
||||
// Check if the matcher is a IStringMatcher
|
||||
// If the body is a Json or a String, use the BodyAsString to match on.
|
||||
if (matcher is IStringMatcher stringMatcher && requestMessage.BodyData?.DetectedBodyType is BodyType.Json or BodyType.String or BodyType.FormUrlEncoded)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
private double CalculateMatchScore(IRequestMessage requestMessage)
|
||||
{
|
||||
if (Matchers == null)
|
||||
{
|
||||
return MatchScores.Mismatch;
|
||||
}
|
||||
|
||||
var matchersResult = Matchers.Select(matcher => CalculateMatchScore(requestMessage, matcher)).ToArray();
|
||||
return MatchScores.ToScore(matchersResult, MatchOperator);
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
private static IMatcher[] CreateMatcherArray(MatchBehaviour matchBehaviour, AnyOfTypes.AnyOf<string, Models.StringPattern, GraphQL.Types.ISchema> schema)
|
||||
{
|
||||
return new[] { new GraphQLMatcher(schema, matchBehaviour) }.Cast<IMatcher>().ToArray();
|
||||
}
|
||||
#else
|
||||
private static IMatcher[] CreateMatcherArray(MatchBehaviour matchBehaviour, object schema)
|
||||
{
|
||||
throw new System.NotSupportedException("The GrapQLMatcher can not be used for .NETStandard1.3 or .NET Framework 4.6.1 or lower.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace WireMock.RequestBuilders;
|
||||
/// <summary>
|
||||
/// The BodyRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IBodyRequestBuilder : IRequestMatcher
|
||||
public interface IBodyRequestBuilder : IGraphQLRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// WithBody: IMatcher
|
||||
@@ -103,4 +103,12 @@ public interface IBodyRequestBuilder : IRequestMatcher
|
||||
/// <param name="func">The form-urlencoded values.</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBody(Func<IDictionary<string, string>?, bool> func);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyAsGraphQLSchema: Body as GraphQL schema as a string.
|
||||
/// </summary>
|
||||
/// <param name="body">The GraphQL schema.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour. (Default is <c>MatchBehaviour.AcceptOnMatch</c>).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithBodyAsGraphQLSchema(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
}
|
||||
28
src/WireMock.Net/RequestBuilders/IGraphQLRequestBuilder.cs
Normal file
28
src/WireMock.Net/RequestBuilders/IGraphQLRequestBuilder.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
/// <summary>
|
||||
/// The GraphQLRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IGraphQLRequestBuilder : IRequestMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// WithGraphQLSchema: The GraphQL schema as a string.
|
||||
/// </summary>
|
||||
/// <param name="schema">The GraphQL schema.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour. (Default is <c>MatchBehaviour.AcceptOnMatch</c>).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithGraphQLSchema(string schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
|
||||
#if GRAPHQL
|
||||
/// <summary>
|
||||
/// WithGraphQLSchema: The GraphQL schema as a ISchema.
|
||||
/// </summary>
|
||||
/// <param name="schema">The GraphQL schema.</param>
|
||||
/// <param name="matchBehaviour">The match behaviour. (Default is <c>MatchBehaviour.AcceptOnMatch</c>).</param>
|
||||
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
|
||||
IRequestBuilder WithGraphQLSchema(GraphQL.Types.ISchema schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch);
|
||||
#endif
|
||||
}
|
||||
@@ -109,4 +109,10 @@ public partial class Request
|
||||
_requestMatchers.Add(new RequestMessageBodyMatcher(Guard.NotNull(func)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithBodyAsGraphQLSchema(string body, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
return WithGraphQLSchema(body, matchBehaviour);
|
||||
}
|
||||
}
|
||||
23
src/WireMock.Net/RequestBuilders/Request.WithGraphQL.cs
Normal file
23
src/WireMock.Net/RequestBuilders/Request.WithGraphQL.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders;
|
||||
|
||||
public partial class Request
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithGraphQLSchema(string schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageGraphQLMatcher(matchBehaviour, schema));
|
||||
return this;
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
/// <inheritdoc />
|
||||
public IRequestBuilder WithGraphQLSchema(GraphQL.Types.ISchema schema, MatchBehaviour matchBehaviour = MatchBehaviour.AcceptOnMatch)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageGraphQLMatcher(matchBehaviour, schema));
|
||||
return this;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -46,7 +46,8 @@ internal class MappingConverter
|
||||
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
|
||||
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
||||
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
||||
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||
var requestMessageBodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||
var requestMessageGraphQLMatcher = request.GetRequestMessageMatcher<RequestMessageGraphQLMatcher>();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
@@ -105,13 +106,23 @@ internal class MappingConverter
|
||||
sb.AppendLine($" .WithCookie(\"{cookieMatcher.Name}\", {ToValueArguments(GetStringArray(cookieMatcher.Matchers!))}, true)");
|
||||
}
|
||||
|
||||
if (bodyMatcher is { Matchers: { } })
|
||||
#if GRAPHQL
|
||||
if (requestMessageGraphQLMatcher is { Matchers: { } })
|
||||
{
|
||||
if (bodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
|
||||
if (requestMessageGraphQLMatcher.Matchers.OfType<GraphQLMatcher>().FirstOrDefault() is { } graphQLMatcher && graphQLMatcher.GetPatterns().Any())
|
||||
{
|
||||
sb.AppendLine($" .WithGraphQLSchema({GetString(graphQLMatcher)})");
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (requestMessageBodyMatcher is { Matchers: { } })
|
||||
{
|
||||
if (requestMessageBodyMatcher.Matchers.OfType<WildcardMatcher>().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any())
|
||||
{
|
||||
sb.AppendLine($" .WithBody({GetString(wildcardMatcher)})");
|
||||
}
|
||||
else if (bodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
|
||||
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialMatcher>().FirstOrDefault() is { Value: { } } jsonPartialMatcher)
|
||||
{
|
||||
sb.AppendLine(@$" .WithBody(new JsonPartialMatcher(
|
||||
value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())},
|
||||
@@ -120,7 +131,7 @@ internal class MappingConverter
|
||||
regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)}
|
||||
))");
|
||||
}
|
||||
else if (bodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)
|
||||
else if (requestMessageBodyMatcher.Matchers.OfType<JsonPartialWildcardMatcher>().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher)
|
||||
{
|
||||
sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher(
|
||||
value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())},
|
||||
@@ -216,6 +227,7 @@ internal class MappingConverter
|
||||
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
|
||||
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
|
||||
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
|
||||
var graphQLMatcher = request.GetRequestMessageMatcher<RequestMessageGraphQLMatcher>();
|
||||
|
||||
var mappingModel = new MappingModel
|
||||
{
|
||||
@@ -301,7 +313,7 @@ internal class MappingConverter
|
||||
mappingModel.Response.Delay = (int?)(response.Delay == Timeout.InfiniteTimeSpan ? TimeSpan.MaxValue.TotalMilliseconds : response.Delay?.TotalMilliseconds);
|
||||
}
|
||||
|
||||
var nonNullableWebHooks = mapping.Webhooks?.Where(wh => wh != null).ToArray() ?? new IWebhook[0];
|
||||
var nonNullableWebHooks = mapping.Webhooks?.Where(wh => wh != null).ToArray() ?? EmptyArray<IWebhook>.Value;
|
||||
if (nonNullableWebHooks.Length == 1)
|
||||
{
|
||||
mappingModel.Webhook = WebhookMapper.Map(nonNullableWebHooks[0]);
|
||||
@@ -311,18 +323,20 @@ internal class MappingConverter
|
||||
mappingModel.Webhooks = mapping.Webhooks.Select(WebhookMapper.Map).ToArray();
|
||||
}
|
||||
|
||||
if (bodyMatcher?.Matchers != null)
|
||||
var graphQLOrBodyMatchers = graphQLMatcher?.Matchers ?? bodyMatcher?.Matchers;
|
||||
var matchOperator = graphQLMatcher?.MatchOperator ?? bodyMatcher?.MatchOperator;
|
||||
if (graphQLOrBodyMatchers != null && matchOperator != null)
|
||||
{
|
||||
mappingModel.Request.Body = new BodyModel();
|
||||
|
||||
if (bodyMatcher.Matchers.Length == 1)
|
||||
if (graphQLOrBodyMatchers.Length == 1)
|
||||
{
|
||||
mappingModel.Request.Body.Matcher = _mapper.Map(bodyMatcher.Matchers[0]);
|
||||
mappingModel.Request.Body.Matcher = _mapper.Map(graphQLOrBodyMatchers[0]);
|
||||
}
|
||||
else if (bodyMatcher.Matchers.Length > 1)
|
||||
else if (graphQLOrBodyMatchers.Length > 1)
|
||||
{
|
||||
mappingModel.Request.Body.Matchers = _mapper.Map(bodyMatcher.Matchers);
|
||||
mappingModel.Request.Body.MatchOperator = bodyMatcher.MatchOperator.ToString();
|
||||
mappingModel.Request.Body.Matchers = _mapper.Map(graphQLOrBodyMatchers);
|
||||
mappingModel.Request.Body.MatchOperator = matchOperator.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,10 @@ internal class MatcherMapper
|
||||
|
||||
case nameof(ExactObjectMatcher):
|
||||
return CreateExactObjectMatcher(matchBehaviour, stringPatterns[0], throwExceptionWhenMatcherFails);
|
||||
|
||||
#if GRAPHQL
|
||||
case nameof(GraphQLMatcher):
|
||||
return new GraphQLMatcher(stringPatterns[0].GetPattern(), matchBehaviour, throwExceptionWhenMatcherFails, matchOperator);
|
||||
#endif
|
||||
case nameof(RegexMatcher):
|
||||
return new RegexMatcher(matchBehaviour, stringPatterns, ignoreCase, throwExceptionWhenMatcherFails, useRegexExtended, matchOperator);
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using WireMock.Extensions;
|
||||
|
||||
namespace WireMock.Settings;
|
||||
|
||||
// Based on http://blog.gauffin.org/2014/12/simple-command-line-parser/
|
||||
internal class SimpleCommandLineParser
|
||||
internal class SimpleSettingsParser
|
||||
{
|
||||
private const string Sigil = "--";
|
||||
private const string Prefix = $"{nameof(WireMockServerSettings)}__";
|
||||
private static readonly int PrefixLength = Prefix.Length;
|
||||
|
||||
private IDictionary<string, string[]> Arguments { get; } = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public void Parse(string[] arguments)
|
||||
public void Parse(string[] arguments, IDictionary? environment = null)
|
||||
{
|
||||
string currentName = string.Empty;
|
||||
|
||||
@@ -44,6 +48,18 @@ internal class SimpleCommandLineParser
|
||||
{
|
||||
Arguments[currentName] = values.ToArray();
|
||||
}
|
||||
|
||||
// Now also parse environment
|
||||
if (environment != null)
|
||||
{
|
||||
foreach (string key in environment.Keys)
|
||||
{
|
||||
if (key.StartsWith(Prefix, StringComparison.OrdinalIgnoreCase) && environment.TryGetStringValue(key, out var value))
|
||||
{
|
||||
Arguments[key.Substring(PrefixLength)] = value.Split(' ').ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(string name)
|
||||
@@ -85,7 +101,16 @@ internal class SimpleCommandLineParser
|
||||
return Contains(name);
|
||||
}
|
||||
|
||||
public int? GetIntValue(string name, int? defaultValue = null)
|
||||
public int? GetIntValue(string name)
|
||||
{
|
||||
return GetValue<int?>(name, values =>
|
||||
{
|
||||
var value = values.FirstOrDefault();
|
||||
return !string.IsNullOrEmpty(value) ? int.Parse(value) : null;
|
||||
}, null);
|
||||
}
|
||||
|
||||
public int GetIntValue(string name, int defaultValue)
|
||||
{
|
||||
return GetValue(name, values =>
|
||||
{
|
||||
@@ -22,6 +22,8 @@ namespace WireMock.Settings;
|
||||
/// </summary>
|
||||
public class WireMockServerSettings
|
||||
{
|
||||
internal const int DefaultStartTimeout = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the http port.
|
||||
/// </summary>
|
||||
@@ -81,7 +83,7 @@ public class WireMockServerSettings
|
||||
/// StartTimeout
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public int StartTimeout { get; set; } = 10000;
|
||||
public int StartTimeout { get; set; } = DefaultStartTimeout;
|
||||
|
||||
/// <summary>
|
||||
/// Allow Partial Mapping (default set to false).
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -18,16 +19,16 @@ public static class WireMockServerSettingsParser
|
||||
/// Parse commandline arguments into WireMockServerSettings.
|
||||
/// </summary>
|
||||
/// <param name="args">The commandline arguments</param>
|
||||
/// <param name="environment">The environment settings (optional)</param>
|
||||
/// <param name="logger">The logger (optional, can be null)</param>
|
||||
/// <param name="settings">The parsed settings</param>
|
||||
[PublicAPI]
|
||||
public static bool TryParseArguments(string[] args, [NotNullWhen(true)] out WireMockServerSettings? settings,
|
||||
IWireMockLogger? logger = null)
|
||||
public static bool TryParseArguments(string[] args, IDictionary? environment, [NotNullWhen(true)] out WireMockServerSettings? settings, IWireMockLogger? logger = null)
|
||||
{
|
||||
Guard.HasNoNulls(args);
|
||||
|
||||
var parser = new SimpleCommandLineParser();
|
||||
parser.Parse(args);
|
||||
var parser = new SimpleSettingsParser();
|
||||
parser.Parse(args, environment);
|
||||
|
||||
if (parser.GetBoolSwitchValue("help"))
|
||||
{
|
||||
@@ -55,6 +56,7 @@ public static class WireMockServerSettingsParser
|
||||
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
|
||||
SaveUnmatchedRequests = parser.GetBoolValue(nameof(WireMockServerSettings.SaveUnmatchedRequests)),
|
||||
StartAdminInterface = parser.GetBoolValue("StartAdminInterface", true),
|
||||
StartTimeout = parser.GetIntValue(nameof(WireMockServerSettings.StartTimeout), WireMockServerSettings.DefaultStartTimeout),
|
||||
ThrowExceptionWhenMatcherFails = parser.GetBoolValue("ThrowExceptionWhenMatcherFails"),
|
||||
UseRegexExtended = parser.GetBoolValue(nameof(WireMockServerSettings.UseRegexExtended), true),
|
||||
WatchStaticMappings = parser.GetBoolValue("WatchStaticMappings"),
|
||||
@@ -79,8 +81,7 @@ public static class WireMockServerSettingsParser
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void ParseLoggerSettings(WireMockServerSettings settings, IWireMockLogger? logger,
|
||||
SimpleCommandLineParser parser)
|
||||
private static void ParseLoggerSettings(WireMockServerSettings settings, IWireMockLogger? logger, SimpleSettingsParser parser)
|
||||
{
|
||||
var loggerType = parser.GetStringValue("WireMockLogger");
|
||||
switch (loggerType)
|
||||
@@ -103,7 +104,7 @@ public static class WireMockServerSettingsParser
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseProxyAndRecordSettings(WireMockServerSettings settings, SimpleCommandLineParser parser)
|
||||
private static void ParseProxyAndRecordSettings(WireMockServerSettings settings, SimpleSettingsParser parser)
|
||||
{
|
||||
var proxyUrl = parser.GetStringValue("ProxyURL") ?? parser.GetStringValue("ProxyUrl");
|
||||
if (!string.IsNullOrEmpty(proxyUrl))
|
||||
@@ -135,7 +136,7 @@ public static class WireMockServerSettingsParser
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParsePortSettings(WireMockServerSettings settings, SimpleCommandLineParser parser)
|
||||
private static void ParsePortSettings(WireMockServerSettings settings, SimpleSettingsParser parser)
|
||||
{
|
||||
if (parser.Contains(nameof(WireMockServerSettings.Port)))
|
||||
{
|
||||
@@ -147,7 +148,7 @@ public static class WireMockServerSettingsParser
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseCertificateSettings(WireMockServerSettings settings, SimpleCommandLineParser parser)
|
||||
private static void ParseCertificateSettings(WireMockServerSettings settings, SimpleSettingsParser parser)
|
||||
{
|
||||
var certificateSettings = new WireMockCertificateSettings
|
||||
{
|
||||
@@ -163,7 +164,7 @@ public static class WireMockServerSettingsParser
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseWebProxyAddressSettings(ProxyAndRecordSettings settings, SimpleCommandLineParser parser)
|
||||
private static void ParseWebProxyAddressSettings(ProxyAndRecordSettings settings, SimpleSettingsParser parser)
|
||||
{
|
||||
string? proxyAddress = parser.GetStringValue("WebProxyAddress");
|
||||
if (!string.IsNullOrEmpty(proxyAddress))
|
||||
@@ -177,7 +178,7 @@ public static class WireMockServerSettingsParser
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseProxyUrlReplaceSettings(ProxyAndRecordSettings settings, SimpleCommandLineParser parser)
|
||||
private static void ParseProxyUrlReplaceSettings(ProxyAndRecordSettings settings, SimpleSettingsParser parser)
|
||||
{
|
||||
var proxyUrlReplaceOldValue = parser.GetStringValue("ProxyUrlReplaceOldValue");
|
||||
var proxyUrlReplaceNewValue = parser.GetStringValue("ProxyUrlReplaceNewValue");
|
||||
|
||||
@@ -138,7 +138,7 @@ internal static class CSharpFormatter
|
||||
return "\"\"";
|
||||
}
|
||||
|
||||
if (value.Contains("\n"))
|
||||
if (value.Contains('\n'))
|
||||
{
|
||||
var escapedValue = value?.Replace("\"", "\"\"") ?? string.Empty;
|
||||
return $"@\"{escapedValue}\"";
|
||||
|
||||
@@ -50,16 +50,19 @@
|
||||
<DefineConstants>$(DefineConstants);OPENAPIPARSER</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
||||
<DefineConstants>$(DefineConstants);GRAPHQL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Util\FileSystemWatcherExtensions.cs" />
|
||||
<Compile Remove="Matchers\Request\IRequestMatcher.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1" PrivateAssets="All" />
|
||||
<PackageReference Include="JsonConverter.Abstractions" Version="0.4.0" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NJsonSchema.Extensions" Version="0.1.0" />
|
||||
<PackageReference Include="NSwag.Core" Version="13.16.1" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||
@@ -154,6 +157,11 @@
|
||||
<PackageReference Include="Scriban.Signed" Version="5.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
||||
<PackageReference Include="GraphQL" Version="7.5.0" />
|
||||
<PackageReference Include="GraphQL.NewtonsoftJson" Version="7.5.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
|
||||
<PackageReference Include="Nullable" Version="1.3.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections;
|
||||
using FluentAssertions;
|
||||
using WireMock.Extensions;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Extensions;
|
||||
|
||||
public class DictionaryExtensionsTests
|
||||
{
|
||||
[Fact]
|
||||
public void TryGetStringValue_WhenKeyExistsAndValueIsString_ReturnsTrueAndStringValue()
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new Hashtable { { "key", "value" } };
|
||||
|
||||
// Act
|
||||
var result = dictionary.TryGetStringValue("key", out var value);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
value.Should().Be("value");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetStringValue_WhenKeyExistsAndValueIsNotString_ReturnsTrueAndStringValue()
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new Hashtable { { "key", 123 } };
|
||||
|
||||
// Act
|
||||
var result = dictionary.TryGetStringValue("key", out var value);
|
||||
|
||||
// Assert
|
||||
result.Should().BeTrue();
|
||||
value.Should().Be("123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryGetStringValue_WhenKeyDoesNotExist_ReturnsFalseAndNull()
|
||||
{
|
||||
// Arrange
|
||||
var dictionary = new Hashtable { { "otherKey", "value" } };
|
||||
|
||||
// Act
|
||||
var result = dictionary.TryGetStringValue("key", out var value);
|
||||
|
||||
// Assert
|
||||
result.Should().BeFalse();
|
||||
value.Should().BeNull();
|
||||
}
|
||||
}
|
||||
@@ -210,6 +210,36 @@ public class WireMockAssertionsTests : IDisposable
|
||||
.Be($"{string.Join(NewLine, missingValue1Message, missingValue2Message)}{NewLine}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HaveReceivedACall_WithHeader_ShouldCheckAllRequests()
|
||||
{
|
||||
// Arrange
|
||||
using var server = WireMockServer.Start();
|
||||
using var client = server.CreateClient();
|
||||
|
||||
// Act 1
|
||||
await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
|
||||
{
|
||||
Headers =
|
||||
{
|
||||
Authorization = new AuthenticationHeaderValue("Bearer", "invalidToken")
|
||||
}
|
||||
});
|
||||
|
||||
// Act 2
|
||||
await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, "/")
|
||||
{
|
||||
Headers =
|
||||
{
|
||||
Authorization = new AuthenticationHeaderValue("Bearer", "validToken")
|
||||
}
|
||||
});
|
||||
|
||||
// Assert
|
||||
server.Should().HaveReceivedACall().WithHeader("Authorization", "Bearer invalidToken");
|
||||
server.Should().HaveReceivedACall().WithHeader("Authorization", "Bearer validToken");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task HaveReceivedACall_AtUrl_WhenACallWasMadeToUrl_Should_BeOK()
|
||||
{
|
||||
|
||||
@@ -14,6 +14,17 @@
|
||||
},
|
||||
Methods: [
|
||||
GET
|
||||
],
|
||||
Params: [
|
||||
{
|
||||
Name: test,
|
||||
Matchers: [
|
||||
{
|
||||
Name: LinqMatcher,
|
||||
Pattern: it.Length < 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
Response: {
|
||||
|
||||
@@ -14,6 +14,17 @@
|
||||
},
|
||||
Methods: [
|
||||
GET
|
||||
],
|
||||
Params: [
|
||||
{
|
||||
Name: test,
|
||||
Matchers: [
|
||||
{
|
||||
Name: LinqMatcher,
|
||||
Pattern: it.Length < 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
Response: {
|
||||
|
||||
@@ -6,6 +6,7 @@ using VerifyTests;
|
||||
using VerifyXunit;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Net.Tests.VerifyExtensions;
|
||||
using WireMock.Owin;
|
||||
using WireMock.RequestBuilders;
|
||||
@@ -65,6 +66,7 @@ public class MappingBuilderTests
|
||||
|
||||
_sut.Given(Request.Create()
|
||||
.WithPath("/foo")
|
||||
.WithParam("test", new LinqMatcher("it.Length < 10"))
|
||||
.UsingGet()
|
||||
)
|
||||
.WithGuid(MappingGuid)
|
||||
|
||||
142
test/WireMock.Net.Tests/Matchers/GraphQLMatcherTests.cs
Normal file
142
test/WireMock.Net.Tests/Matchers/GraphQLMatcherTests.cs
Normal file
@@ -0,0 +1,142 @@
|
||||
#if GRAPHQL
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using GraphQLParser.Exceptions;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Matchers;
|
||||
|
||||
public class GraphQLMatcherTests
|
||||
{
|
||||
private const string TestSchema = @"
|
||||
input MessageInput {
|
||||
content: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
content: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(input: MessageInput): Message
|
||||
updateMessage(id: ID!, input: MessageInput): Message
|
||||
}
|
||||
|
||||
type Query {
|
||||
greeting:String
|
||||
students:[Student]
|
||||
studentById(id:ID!):Student
|
||||
}
|
||||
|
||||
type Student {
|
||||
id:ID!
|
||||
firstName:String
|
||||
lastName:String
|
||||
fullName:String
|
||||
}";
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_CorrectQuery_IsMatch()
|
||||
{
|
||||
// Arrange
|
||||
var input = "{\"query\":\"{\\r\\n students {\\r\\n fullName\\r\\n id\\r\\n }\\r\\n}\"}";
|
||||
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(TestSchema);
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
|
||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_CorrectGraphQLQuery_IsMatch()
|
||||
{
|
||||
// Arrange
|
||||
var input = @"{
|
||||
""query"": ""query ($sid: ID!)\r\n{\r\n studentById(id: $sid) {\r\n fullName\r\n id\r\n }\r\n}"",
|
||||
""variables"": {
|
||||
""sid"": ""1""
|
||||
}
|
||||
}";
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(TestSchema);
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
|
||||
matcher.GetPatterns().Should().Contain(TestSchema);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQuery_IsMismatch()
|
||||
{
|
||||
// Arrange
|
||||
var input = @"
|
||||
{
|
||||
students {
|
||||
fullName
|
||||
id
|
||||
abc
|
||||
}
|
||||
}";
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(TestSchema);
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Mismatch);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchemaAsStringPattern_And_CorrectQuery_IsMatch()
|
||||
{
|
||||
// Arrange
|
||||
var input = "{\"query\":\"{\\r\\n students {\\r\\n fullName\\r\\n id\\r\\n }\\r\\n}\"}";
|
||||
var schema = new StringPattern
|
||||
{
|
||||
Pattern = TestSchema
|
||||
};
|
||||
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(schema);
|
||||
var result = matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
result.Should().Be(MatchScores.Perfect);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_ValidSchema_And_IncorrectQueryWithError_WithThrowExceptionTrue_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
var input = "{\"query\":\"{\\r\\n studentsX {\\r\\n fullName\\r\\n X\\r\\n }\\r\\n}\"}";
|
||||
|
||||
// Act
|
||||
var matcher = new GraphQLMatcher(TestSchema, MatchBehaviour.AcceptOnMatch, true);
|
||||
Action action = () => matcher.IsMatch(input);
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<Exception>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GraphQLMatcher_For_InvalidSchema_ThrowsGraphQLSyntaxErrorException()
|
||||
{
|
||||
// Act
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
Action action = () => _ = new GraphQLMatcher("in va lid");
|
||||
|
||||
// Assert
|
||||
action.Should().Throw<GraphQLSyntaxErrorException>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -11,7 +11,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_GetName()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("X");
|
||||
|
||||
// Act
|
||||
@@ -24,7 +24,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_GetPatterns()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("X");
|
||||
|
||||
// Act
|
||||
@@ -37,7 +37,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_ByteArray()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var bytes = EmptyArray<byte>.Value;
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
@@ -51,7 +51,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_NullString()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
string? s = null;
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
@@ -65,7 +65,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_NullObject()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
object? o = null;
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
@@ -79,7 +79,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_String_Exception_Mismatch()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("xxx");
|
||||
|
||||
// Act
|
||||
@@ -92,7 +92,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_Object_Exception_Mismatch()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("");
|
||||
|
||||
// Act
|
||||
@@ -105,7 +105,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_AnonymousObject()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
@@ -115,10 +115,51 @@ public class JsonPathMatcherTests
|
||||
Check.That(match).IsEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_AnonymousObject_WithNestedObject()
|
||||
{
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(new { things = new { name = "x" } });
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_String_WithNestedObject()
|
||||
{
|
||||
// Arrange
|
||||
var json = "{ \"things\": { \"name\": \"x\" } }";
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(json);
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsNoMatch_String_WithNestedObject()
|
||||
{
|
||||
// Arrange
|
||||
var json = "{ \"things\": { \"name\": \"y\" } }";
|
||||
var matcher = new JsonPathMatcher("$.things[?(@.name == 'x')]");
|
||||
|
||||
// Act
|
||||
double match = matcher.IsMatch(json);
|
||||
|
||||
// Assert
|
||||
Check.That(match).IsEqualTo(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_JObject()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
string[] patterns = { "$..[?(@.Id == 1)]" };
|
||||
var matcher = new JsonPathMatcher(patterns);
|
||||
|
||||
@@ -137,7 +178,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_JObject_Parsed()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher("$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
@@ -150,7 +191,7 @@ public class JsonPathMatcherTests
|
||||
[Fact]
|
||||
public void JsonPathMatcher_IsMatch_RejectOnMatch()
|
||||
{
|
||||
// Assign
|
||||
// Arrange
|
||||
var matcher = new JsonPathMatcher(MatchBehaviour.RejectOnMatch, false, MatchOperator.Or, "$..[?(@.Id == 1)]");
|
||||
|
||||
// Act
|
||||
|
||||
@@ -42,7 +42,14 @@ public class PactTests
|
||||
})
|
||||
);
|
||||
|
||||
server.SavePact(Path.Combine("../../../", "Pact", "files"), "pact-get.json");
|
||||
var folder = Path.Combine("../../../", "Pact", "files");
|
||||
var file = "pact-get.json";
|
||||
|
||||
// Act
|
||||
server.SavePact(folder, file);
|
||||
|
||||
// Assert
|
||||
File.ReadAllBytes(Path.Combine(folder, file)).Length.Should().BeGreaterThan(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -201,6 +208,13 @@ public class PactTests
|
||||
})
|
||||
);
|
||||
|
||||
server.SavePact(Path.Combine("../../../", "Pact", "files"), "pact-multiple.json");
|
||||
var folder = Path.Combine("../../../", "Pact", "files");
|
||||
var file = "pact-multiple.json";
|
||||
|
||||
// Act
|
||||
server.SavePact(folder, file);
|
||||
|
||||
// Assert
|
||||
File.ReadAllBytes(Path.Combine(folder, file)).Length.Should().BeGreaterThan(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#if GRAPHQL
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using GraphQL.Types;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.RequestBuilders;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.RequestBuilders;
|
||||
|
||||
public class RequestBuilderWithGraphQLSchemaTests
|
||||
{
|
||||
private const string TestSchema = @"
|
||||
input MessageInput {
|
||||
content: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Message {
|
||||
id: ID!
|
||||
content: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
createMessage(input: MessageInput): Message
|
||||
updateMessage(id: ID!, input: MessageInput): Message
|
||||
}
|
||||
|
||||
type Query {
|
||||
greeting:String
|
||||
students:[Student]
|
||||
studentById(id:ID!):Student
|
||||
}
|
||||
|
||||
type Student {
|
||||
id:ID!
|
||||
firstName:String
|
||||
lastName:String
|
||||
fullName:String
|
||||
}";
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_WithGraphQLSchema_SchemaAsString()
|
||||
{
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().WithGraphQLSchema(TestSchema);
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
matchers.Should().HaveCount(1);
|
||||
((RequestMessageGraphQLMatcher)matchers[0]).Matchers.Should().ContainItemsAssignableTo<GraphQLMatcher>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestBuilder_WithGraphQLSchema_SchemaAsISchema()
|
||||
{
|
||||
// Arrange
|
||||
var schema = Schema.For(TestSchema);
|
||||
|
||||
// Act
|
||||
var requestBuilder = (Request)Request.Create().WithGraphQLSchema(schema);
|
||||
|
||||
// Assert
|
||||
var matchers = requestBuilder.GetPrivateFieldValue<IList<IRequestMatcher>>("_requestMatchers");
|
||||
matchers.Should().HaveCount(1);
|
||||
((RequestMessageGraphQLMatcher)matchers[0]).Matchers.Should().ContainItemsAssignableTo<GraphQLMatcher>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,194 @@
|
||||
#if GRAPHQL
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Matchers.Request;
|
||||
using WireMock.Models;
|
||||
using WireMock.Types;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.RequestMatchers;
|
||||
|
||||
public class RequestMessageGraphQLMatcherTests
|
||||
{
|
||||
[Fact]
|
||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatcher()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "b",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var stringMatcherMock = new Mock<IStringMatcher>();
|
||||
stringMatcherMock.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(1d);
|
||||
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
||||
|
||||
var matcher = new RequestMessageGraphQLMatcher(stringMatcherMock.Object);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
score.Should().Be(MatchScores.Perfect);
|
||||
|
||||
// Verify
|
||||
stringMatcherMock.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1d, 1d, 1d)]
|
||||
[InlineData(0d, 1d, 1d)]
|
||||
[InlineData(1d, 0d, 1d)]
|
||||
[InlineData(0d, 0d, 0d)]
|
||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatchers_Or(double one, double two, double expected)
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "b",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var stringMatcherMock1 = new Mock<IStringMatcher>();
|
||||
stringMatcherMock1.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(one);
|
||||
|
||||
var stringMatcherMock2 = new Mock<IStringMatcher>();
|
||||
stringMatcherMock2.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(two);
|
||||
|
||||
var matchers = new[] { stringMatcherMock1.Object, stringMatcherMock2.Object };
|
||||
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
||||
|
||||
var matcher = new RequestMessageGraphQLMatcher(MatchOperator.Or, matchers.Cast<IMatcher>().ToArray());
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
score.Should().Be(expected);
|
||||
|
||||
// Verify
|
||||
stringMatcherMock1.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock1.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
|
||||
stringMatcherMock2.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock2.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
stringMatcherMock2.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1d, 1d, 1d)]
|
||||
[InlineData(0d, 1d, 0d)]
|
||||
[InlineData(1d, 0d, 0d)]
|
||||
[InlineData(0d, 0d, 0d)]
|
||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatchers_And(double one, double two, double expected)
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "b",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var stringMatcherMock1 = new Mock<IStringMatcher>();
|
||||
stringMatcherMock1.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(one);
|
||||
|
||||
var stringMatcherMock2 = new Mock<IStringMatcher>();
|
||||
stringMatcherMock2.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(two);
|
||||
|
||||
var matchers = new[] { stringMatcherMock1.Object, stringMatcherMock2.Object };
|
||||
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
||||
|
||||
var matcher = new RequestMessageGraphQLMatcher(MatchOperator.And, matchers.Cast<IMatcher>().ToArray());
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
score.Should().Be(expected);
|
||||
|
||||
// Verify
|
||||
stringMatcherMock1.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock1.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
|
||||
stringMatcherMock2.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock2.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
stringMatcherMock2.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(1d, 1d, 1d)]
|
||||
[InlineData(0d, 1d, 0.5d)]
|
||||
[InlineData(1d, 0d, 0.5d)]
|
||||
[InlineData(0d, 0d, 0d)]
|
||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsString_IStringMatchers_Average(double one, double two, double expected)
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = "b",
|
||||
DetectedBodyType = BodyType.String
|
||||
};
|
||||
var stringMatcherMock1 = new Mock<IStringMatcher>();
|
||||
stringMatcherMock1.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(one);
|
||||
|
||||
var stringMatcherMock2 = new Mock<IStringMatcher>();
|
||||
stringMatcherMock2.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(two);
|
||||
|
||||
var matchers = new[] { stringMatcherMock1.Object, stringMatcherMock2.Object };
|
||||
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
||||
|
||||
var matcher = new RequestMessageGraphQLMatcher(MatchOperator.Average, matchers.Cast<IMatcher>().ToArray());
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
score.Should().Be(expected);
|
||||
|
||||
// Verify
|
||||
stringMatcherMock1.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock1.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
|
||||
stringMatcherMock2.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock2.Verify(m => m.IsMatch("b"), Times.Once);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RequestMessageGraphQLMatcher_GetMatchingScore_BodyAsBytes_IStringMatcher_ReturnMisMatch()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsBytes = new byte[] { 1 },
|
||||
DetectedBodyType = BodyType.Bytes
|
||||
};
|
||||
var stringMatcherMock = new Mock<IStringMatcher>();
|
||||
stringMatcherMock.Setup(m => m.IsMatch(It.IsAny<string>())).Returns(0.5d);
|
||||
|
||||
var requestMessage = new RequestMessage(new UrlDetails("http://localhost"), "GET", "127.0.0.1", body);
|
||||
|
||||
var matcher = new RequestMessageGraphQLMatcher(stringMatcherMock.Object);
|
||||
|
||||
// Act
|
||||
var result = new RequestMatchResult();
|
||||
double score = matcher.GetMatchingScore(requestMessage, result);
|
||||
|
||||
// Assert
|
||||
score.Should().Be(MatchScores.Mismatch);
|
||||
|
||||
// Verify
|
||||
stringMatcherMock.Verify(m => m.GetPatterns(), Times.Never);
|
||||
stringMatcherMock.Verify(m => m.IsMatch(It.IsAny<string>()), Times.Never);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
Guid: Guid_1,
|
||||
UpdatedAt: DateTime_1,
|
||||
Title: ,
|
||||
Description: ,
|
||||
Priority: 42,
|
||||
Request: {
|
||||
Body: {
|
||||
Matcher: {
|
||||
Name: GraphQLMatcher,
|
||||
Pattern:
|
||||
type Query {
|
||||
greeting:String
|
||||
students:[Student]
|
||||
studentById(id:ID!):Student
|
||||
}
|
||||
|
||||
type Student {
|
||||
id:ID!
|
||||
firstName:String
|
||||
lastName:String
|
||||
fullName:String
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Response: {},
|
||||
UseWebhooksFireAndForget: false
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
Guid: Guid_1,
|
||||
UpdatedAt: DateTime_1,
|
||||
Title: ,
|
||||
Description: ,
|
||||
Priority: 42,
|
||||
Request: {
|
||||
Path: {
|
||||
Matchers: [
|
||||
{
|
||||
Name: WildcardMatcher,
|
||||
Pattern: 1.2.3.4,
|
||||
IgnoreCase: false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
Response: {},
|
||||
UseWebhooksFireAndForget: false
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -260,7 +260,7 @@ public partial class MappingConverterTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToMappingModel_WithDelayAsMilliSeconds_ReturnsCorrectModel()
|
||||
public Task ToMappingModel_WithDelay_ReturnsCorrectModel()
|
||||
{
|
||||
// Assign
|
||||
var delay = 1000;
|
||||
@@ -343,5 +343,56 @@ public partial class MappingConverterTests
|
||||
// Verify
|
||||
return Verifier.Verify(model);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public Task ToMappingModel_Request_WithClientIP_ReturnsCorrectModel()
|
||||
{
|
||||
// Arrange
|
||||
var request = Request.Create().WithClientIP("1.2.3.4");
|
||||
var response = Response.Create();
|
||||
var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 42, null, null, null, null, null, false, null, null, null);
|
||||
|
||||
// Act
|
||||
var model = _sut.ToMappingModel(mapping);
|
||||
|
||||
// Assert
|
||||
model.Should().NotBeNull();
|
||||
|
||||
// Verify
|
||||
return Verifier.Verify(model);
|
||||
}
|
||||
|
||||
#if GRAPHQL
|
||||
[Fact]
|
||||
public Task ToMappingModel_Request_WithBodyAsGraphQLSchema_ReturnsCorrectModel()
|
||||
{
|
||||
// Arrange
|
||||
var schema = @"
|
||||
type Query {
|
||||
greeting:String
|
||||
students:[Student]
|
||||
studentById(id:ID!):Student
|
||||
}
|
||||
|
||||
type Student {
|
||||
id:ID!
|
||||
firstName:String
|
||||
lastName:String
|
||||
fullName:String
|
||||
}";
|
||||
var request = Request.Create().WithBodyAsGraphQLSchema(schema);
|
||||
var response = Response.Create();
|
||||
var mapping = new Mapping(_guid, _updatedAt, string.Empty, string.Empty, null, _settings, request, response, 42, null, null, null, null, null, false, null, null, null);
|
||||
|
||||
// Act
|
||||
var model = _sut.ToMappingModel(mapping);
|
||||
|
||||
// Assert
|
||||
model.Should().NotBeNull();
|
||||
|
||||
// Verify
|
||||
return Verifier.Verify(model);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -1,102 +0,0 @@
|
||||
using NFluent;
|
||||
using WireMock.Settings;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Settings;
|
||||
|
||||
public class SimpleCommandLineParserTests
|
||||
{
|
||||
private readonly SimpleCommandLineParser _parser;
|
||||
|
||||
public SimpleCommandLineParserTests()
|
||||
{
|
||||
_parser = new SimpleCommandLineParser();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_Arguments()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1", "one", "--test2", "two", "--test3", "three" });
|
||||
|
||||
// Act
|
||||
string? value1 = _parser.GetStringValue("test1");
|
||||
string? value2 = _parser.GetStringValue("test2");
|
||||
string? value3 = _parser.GetStringValue("test3");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo("one");
|
||||
Check.That(value2).IsEqualTo("two");
|
||||
Check.That(value3).IsEqualTo("three");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_ArgumentsAsCombinedKeyAndValue()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1 one", "--test2 two", "--test3 three" });
|
||||
|
||||
// Act
|
||||
string? value1 = _parser.GetStringValue("test1");
|
||||
string? value2 = _parser.GetStringValue("test2");
|
||||
string? value3 = _parser.GetStringValue("test3");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo("one");
|
||||
Check.That(value2).IsEqualTo("two");
|
||||
Check.That(value3).IsEqualTo("three");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_ArgumentsMixed()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1 one", "--test2", "two", "--test3 three" });
|
||||
|
||||
// Act
|
||||
string? value1 = _parser.GetStringValue("test1");
|
||||
string? value2 = _parser.GetStringValue("test2");
|
||||
string? value3 = _parser.GetStringValue("test3");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo("one");
|
||||
Check.That(value2).IsEqualTo("two");
|
||||
Check.That(value3).IsEqualTo("three");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_GetBoolValue()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "'--test1", "false'", "--test2 true" });
|
||||
|
||||
// Act
|
||||
bool value1 = _parser.GetBoolValue("test1");
|
||||
bool value2 = _parser.GetBoolValue("test2");
|
||||
bool value3 = _parser.GetBoolValue("test3", true);
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo(false);
|
||||
Check.That(value2).IsEqualTo(true);
|
||||
Check.That(value3).IsEqualTo(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_GetIntValue()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1", "42", "--test2 55" });
|
||||
|
||||
// Act
|
||||
int? value1 = _parser.GetIntValue("test1");
|
||||
int? value2 = _parser.GetIntValue("test2");
|
||||
int? value3 = _parser.GetIntValue("test3", 100);
|
||||
int? value4 = _parser.GetIntValue("test4");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo(42);
|
||||
Check.That(value2).IsEqualTo(55);
|
||||
Check.That(value3).IsEqualTo(100);
|
||||
Check.That(value4).IsNull();
|
||||
}
|
||||
}
|
||||
177
test/WireMock.Net.Tests/Settings/SimpleSettingsParserTests.cs
Normal file
177
test/WireMock.Net.Tests/Settings/SimpleSettingsParserTests.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using System.Collections.Generic;
|
||||
using FluentAssertions;
|
||||
using NFluent;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Types;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Settings;
|
||||
|
||||
public class SimpleSettingsParserTests
|
||||
{
|
||||
private readonly SimpleSettingsParser _parser;
|
||||
|
||||
public SimpleSettingsParserTests()
|
||||
{
|
||||
_parser = new SimpleSettingsParser();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_Arguments()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1", "one", "--test2", "2", "--test3", "3", "--test4", "true", "--test5", "Https" });
|
||||
|
||||
// Act
|
||||
string? stringValue = _parser.GetStringValue("test1");
|
||||
int? intOptional = _parser.GetIntValue("test2");
|
||||
int intWithDefault = _parser.GetIntValue("test3", 42);
|
||||
bool? boolWithDefault = _parser.GetBoolValue("test4");
|
||||
HostingScheme? enumOptional = _parser.GetEnumValue<HostingScheme>("test5");
|
||||
HostingScheme enumWithDefault = _parser.GetEnumValue("test99", HostingScheme.HttpAndHttps);
|
||||
|
||||
// Assert
|
||||
stringValue.Should().Be("one");
|
||||
intOptional.Should().Be(2);
|
||||
intWithDefault.Should().Be(3);
|
||||
boolWithDefault.Should().Be(true);
|
||||
enumOptional.Should().Be(HostingScheme.Https);
|
||||
enumWithDefault.Should().Be(HostingScheme.HttpAndHttps);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_Environment()
|
||||
{
|
||||
// Assign
|
||||
var env = new Dictionary<string, string>
|
||||
{
|
||||
{ "WireMockServerSettings__test1", "one" },
|
||||
{ "WireMockServerSettings__test2", "two" }
|
||||
};
|
||||
_parser.Parse(new string[0], env);
|
||||
|
||||
// Act
|
||||
string? value1 = _parser.GetStringValue("test1");
|
||||
string? value2 = _parser.GetStringValue("test2");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo("one");
|
||||
Check.That(value2).IsEqualTo("two");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_ArgumentsAsCombinedKeyAndValue()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1 one", "--test2 two", "--test3 three" });
|
||||
|
||||
// Act
|
||||
string? value1 = _parser.GetStringValue("test1");
|
||||
string? value2 = _parser.GetStringValue("test2");
|
||||
string? value3 = _parser.GetStringValue("test3");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo("one");
|
||||
Check.That(value2).IsEqualTo("two");
|
||||
Check.That(value3).IsEqualTo("three");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_ArgumentsMixed()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1 one", "--test2", "two", "--test3 three" });
|
||||
|
||||
// Act
|
||||
string? value1 = _parser.GetStringValue("test1");
|
||||
string? value2 = _parser.GetStringValue("test2");
|
||||
string? value3 = _parser.GetStringValue("test3");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo("one");
|
||||
Check.That(value2).IsEqualTo("two");
|
||||
Check.That(value3).IsEqualTo("three");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_GetBoolValue()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "'--test1", "false'", "--test2 true" });
|
||||
|
||||
// Act
|
||||
bool value1 = _parser.GetBoolValue("test1");
|
||||
bool value2 = _parser.GetBoolValue("test2");
|
||||
bool value3 = _parser.GetBoolValue("test3", true);
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo(false);
|
||||
Check.That(value2).IsEqualTo(true);
|
||||
Check.That(value3).IsEqualTo(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_Environment_GetBoolValue()
|
||||
{
|
||||
// Assign
|
||||
var env = new Dictionary<string, string>
|
||||
{
|
||||
{ "WireMockServerSettings__test1", "false" },
|
||||
{ "WireMockServerSettings__test2", "true" }
|
||||
};
|
||||
_parser.Parse(new string[0], env);
|
||||
|
||||
// Act
|
||||
bool value1 = _parser.GetBoolValue("test1");
|
||||
bool value2 = _parser.GetBoolValue("test2");
|
||||
bool value3 = _parser.GetBoolValue("test3", true);
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo(false);
|
||||
Check.That(value2).IsEqualTo(true);
|
||||
Check.That(value3).IsEqualTo(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_GetIntValue()
|
||||
{
|
||||
// Assign
|
||||
_parser.Parse(new[] { "--test1", "42", "--test2 55" });
|
||||
|
||||
// Act
|
||||
int? value1 = _parser.GetIntValue("test1");
|
||||
int? value2 = _parser.GetIntValue("test2");
|
||||
int? value3 = _parser.GetIntValue("test3", 100);
|
||||
int? value4 = _parser.GetIntValue("test4");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo(42);
|
||||
Check.That(value2).IsEqualTo(55);
|
||||
Check.That(value3).IsEqualTo(100);
|
||||
Check.That(value4).IsNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SimpleCommandLineParser_Parse_Environment_GetIntValue()
|
||||
{
|
||||
// Assign
|
||||
var env = new Dictionary<string, string>
|
||||
{
|
||||
{ "WireMockServerSettings__test1", "42" },
|
||||
{ "WireMockServerSETTINGS__TEST2", "55" }
|
||||
};
|
||||
_parser.Parse(new string[0], env);
|
||||
|
||||
// Act
|
||||
int? value1 = _parser.GetIntValue("test1");
|
||||
int? value2 = _parser.GetIntValue("test2");
|
||||
int? value3 = _parser.GetIntValue("test3", 100);
|
||||
int? value4 = _parser.GetIntValue("test4");
|
||||
|
||||
// Assert
|
||||
Check.That(value1).IsEqualTo(42);
|
||||
Check.That(value2).IsEqualTo(55);
|
||||
Check.That(value3).IsEqualTo(100);
|
||||
Check.That(value4).IsNull();
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,12 @@
|
||||
<DefineConstants>NETFRAMEWORK</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' != 'netstandard1.3' and '$(TargetFramework)' != 'net451' and '$(TargetFramework)' != 'net452' and '$(TargetFramework)' != 'net46' and '$(TargetFramework)' != 'net461'">
|
||||
<DefineConstants>$(DefineConstants);GRAPHQL</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Util\JsonUtilsTests.cs" />
|
||||
<Compile Remove="Util\JsonUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -63,11 +67,8 @@
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="Moq" Version="4.17.2" />
|
||||
|
||||
<!--<PackageReference Include="System.Linq.Dynamic.Core" Version="1.3.1" />-->
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="RestEase" Version="1.5.7" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="NFluent" Version="2.8.0" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.5" />
|
||||
<PackageReference Include="AnyOf" Version="0.3.0" />
|
||||
@@ -104,10 +105,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="OpenApiParser\*.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="OpenApiParser\*.yml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="responsebody.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
|
||||
@@ -1,215 +1,210 @@
|
||||
using Moq;
|
||||
using NFluent;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using Moq;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Server;
|
||||
using WireMock.Settings;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests
|
||||
namespace WireMock.Net.Tests;
|
||||
|
||||
public class WireMockServerAdminFilesTests
|
||||
{
|
||||
public class WireMockServerAdminFilesTests
|
||||
private readonly HttpClient _client = new HttpClient();
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Post_Ascii()
|
||||
{
|
||||
private readonly HttpClient _client = new HttpClient();
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("__admin/mappings");
|
||||
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(true);
|
||||
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Post_Ascii()
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("__admin/mappings");
|
||||
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(true);
|
||||
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
||||
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
||||
// Act
|
||||
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
||||
|
||||
// Act
|
||||
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
||||
// Assert
|
||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
// Assert
|
||||
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.OK);
|
||||
Check.That(server.LogEntries.Count().Equals(1));
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Post_MappingFolderDoesNotExistsButWillBeCreated()
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("x");
|
||||
filesystemHandlerMock.Setup(fs => fs.CreateFolder(It.IsAny<string>()));
|
||||
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(false);
|
||||
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Post_MappingFolderDoesNotExistsButWillBeCreated()
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.GetMappingFolder()).Returns("x");
|
||||
filesystemHandlerMock.Setup(fs => fs.CreateFolder(It.IsAny<string>()));
|
||||
filesystemHandlerMock.Setup(fs => fs.FolderExists(It.IsAny<string>())).Returns(false);
|
||||
filesystemHandlerMock.Setup(fs => fs.WriteFile(It.IsAny<string>(), It.IsAny<byte[]>()));
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
||||
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream(Encoding.ASCII.GetBytes("Here's a string."))));
|
||||
// Act
|
||||
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
||||
|
||||
// Act
|
||||
var httpResponseMessage = await _client.PostAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt", multipartFormDataContent).ConfigureAwait(false);
|
||||
// Assert
|
||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
// Assert
|
||||
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.OK);
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.CreateFolder(It.Is<string>(p => p == "x")), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.GetMappingFolder(), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FolderExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.CreateFolder(It.Is<string>(p => p == "x")), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.WriteFile(It.Is<string>(p => p == "filename.txt"), It.IsAny<byte[]>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_GetAscii()
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(Encoding.ASCII.GetBytes("Here's a string."));
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_GetAscii()
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(Encoding.ASCII.GetBytes("Here's a string."));
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
||||
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
||||
// Act
|
||||
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt").ConfigureAwait(false);
|
||||
|
||||
// Act
|
||||
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt").ConfigureAwait(false);
|
||||
// Assert
|
||||
httpResponseMessageGet.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
// Assert
|
||||
Check.That(httpResponseMessageGet.StatusCode).Equals(HttpStatusCode.OK);
|
||||
var result = await httpResponseMessageGet.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
result.Should().Be("Here's a string.");
|
||||
|
||||
Check.That(httpResponseMessageGet.Content.ReadAsStringAsync().Result).Equals("Here's a string.");
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
Check.That(server.LogEntries.Count().Equals(2));
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_GetUTF16()
|
||||
{
|
||||
// Arrange
|
||||
byte[] symbol = Encoding.UTF32.GetBytes(char.ConvertFromUtf32(0x1D161));
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(symbol);
|
||||
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.txt")), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_GetUTF16()
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
// Arrange
|
||||
byte[] symbol = Encoding.UTF32.GetBytes(char.ConvertFromUtf32(0x1D161));
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||
filesystemHandlerMock.Setup(fs => fs.ReadFile(It.IsAny<string>())).Returns(symbol);
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
||||
|
||||
var multipartFormDataContent = new MultipartFormDataContent();
|
||||
multipartFormDataContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||
multipartFormDataContent.Add(new StreamContent(new MemoryStream()));
|
||||
// Act
|
||||
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.bin").ConfigureAwait(false);
|
||||
|
||||
// Act
|
||||
var httpResponseMessageGet = await _client.GetAsync("http://localhost:" + server.Ports[0] + "/__admin/files/filename.bin").ConfigureAwait(false);
|
||||
// Assert
|
||||
httpResponseMessageGet.StatusCode.Should().Be(HttpStatusCode.OK);
|
||||
|
||||
// Assert
|
||||
Check.That(httpResponseMessageGet.StatusCode).Equals(HttpStatusCode.OK);
|
||||
Check.That(httpResponseMessageGet.Content.ReadAsByteArrayAsync().Result).Equals(symbol);
|
||||
Check.That(server.LogEntries.Count().Equals(2));
|
||||
var result = await httpResponseMessageGet.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
|
||||
result.Should().BeEquivalentTo(symbol);
|
||||
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.ReadFile(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.Is<string>(p => p == "filename.bin")), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Head()
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Head()
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(true);
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
// Act
|
||||
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||
|
||||
// Act
|
||||
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||
// Assert
|
||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.NoContent);
|
||||
|
||||
// Assert
|
||||
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.NoContent);
|
||||
Check.That(server.LogEntries.Count().Equals(1));
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Head_FileDoesNotExistsReturns404()
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(false);
|
||||
|
||||
[Fact]
|
||||
public async Task WireMockServer_Admin_Files_Head_FileDoesNotExistsReturns404()
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
// Arrange
|
||||
var filesystemHandlerMock = new Mock<IFileSystemHandler>(MockBehavior.Strict);
|
||||
filesystemHandlerMock.Setup(fs => fs.FileExists(It.IsAny<string>())).Returns(false);
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
|
||||
var server = WireMockServer.Start(new WireMockServerSettings
|
||||
{
|
||||
UseSSL = false,
|
||||
StartAdminInterface = true,
|
||||
FileSystemHandler = filesystemHandlerMock.Object
|
||||
});
|
||||
// Act
|
||||
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||
|
||||
// Act
|
||||
var requestUri = "http://localhost:" + server.Ports[0] + "/__admin/files/filename.txt";
|
||||
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Head, requestUri);
|
||||
var httpResponseMessage = await _client.SendAsync(httpRequestMessage).ConfigureAwait(false);
|
||||
// Assert
|
||||
httpResponseMessage.StatusCode.Should().Be(HttpStatusCode.NotFound);
|
||||
|
||||
// Assert
|
||||
Check.That(httpResponseMessage.StatusCode).Equals(HttpStatusCode.NotFound);
|
||||
Check.That(server.LogEntries.Count().Equals(1));
|
||||
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
// Verify
|
||||
filesystemHandlerMock.Verify(fs => fs.FileExists(It.IsAny<string>()), Times.Once);
|
||||
filesystemHandlerMock.VerifyNoOtherCalls();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user