Summary

Class:WireMock.Server.FluentMockServer
Assembly:WireMock.Net
File(s):C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.Admin.cs
C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.cs
C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.LogEntries.cs
Covered lines:393
Uncovered lines:328
Coverable lines:721
Total lines:1265
Line coverage:54.5%
Branch coverage:49.4%

Metrics

MethodCyclomatic complexity  NPath complexity  Sequence coverage  Branch coverage  
InitAdmin()10100100
ReadStaticMappings(...)6470.5960
WatchStaticMappings(...)3400
ReadStaticMappingAndAddOrUpdate(...)22100100
InitProxyAndRecord(...)10100100
ToMapping(...)2210066.67
SettingsGet(...)5000
SettingsUpdate(...)4400
MappingGet(...)2200
MappingPut(...)2000
MappingDelete(...)2200
MappingsSave(...)4000
SaveMappingToFile(...)3200
SanitizeFileName(...)1000
MappingsGet(...)4000
MappingsPost(...)2046.67100
DeserializeAndAddOrUpdateMapping(...)1225685.7176.47
MappingsDelete(...)1000
RequestGet(...)2200
RequestDelete(...)2200
RequestsGet(...)20100100
ToLogEntryModel(...)8810057.14
RequestsDelete(...)1000
RequestsFind(...)8210066.67
ScenariosGet(...)2000
ScenariosReset(...)1000
InitRequestBuilder(...)3226214437.548.65
InitResponseBuilder(...)18409644.2644
ToJson(...)10100100
ToEncoding(...)32100100
.ctor(...)2713107272.2262.86
.cctor()10100100
ProxyAndRecordAsync()6886.6771.43
Start(...)10100100
Start(...)10100100
Start(...)10100100
StartWithAdminInterface(...)10100100
StartWithAdminInterface(...)1000
StartWithAdminInterfaceAndReadStaticMappings(...)1000
Stop()2210066.67
AddCatchAllMapping()2000
Dispose()3210066.67
Reset()1000
ResetMappings()40100100
DeleteMapping(...)2200
DeleteMapping(...)1000
AddGlobalProcessingDelay(...)10100100
AllowPartialMapping(...)1000
SetBasicAuthentication(...)1000
RemoveBasicAuthentication()1000
SetMaxRequestLogCount(...)10100100
SetRequestLogExpirationDuration(...)1000
ResetScenarios()1000
Given(...)10100100
RegisterMapping(...)22100100
add_LogEntriesChanged(...)10100100
remove_LogEntriesChanged(...)1000
FindLogEntries(...)72100100
ResetLogEntries()10100100
DeleteLogEntry(...)2200

File(s)

C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.Admin.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.IO;
 4using System.Linq;
 5using System.Net.Http;
 6using System.Text;
 7using System.Threading.Tasks;
 8using JetBrains.Annotations;
 9using Newtonsoft.Json;
 10using Newtonsoft.Json.Linq;
 11using WireMock.Admin.Mappings;
 12using WireMock.Admin.Requests;
 13using WireMock.Admin.Settings;
 14using WireMock.Http;
 15using WireMock.Logging;
 16using WireMock.Matchers;
 17using WireMock.Matchers.Request;
 18using WireMock.RequestBuilders;
 19using WireMock.ResponseBuilders;
 20using WireMock.ResponseProviders;
 21using WireMock.Serialization;
 22using WireMock.Settings;
 23using WireMock.Util;
 24using WireMock.Validation;
 25
 26namespace WireMock.Server
 27{
 28    /// <summary>
 29    /// The fluent mock server.
 30    /// </summary>
 31    public partial class FluentMockServer
 32    {
 133        private static readonly string AdminMappingsFolder = Path.Combine("__admin", "mappings");
 34        private const string ContentTypeJson = "application/json";
 35        private const string AdminMappings = "/__admin/mappings";
 36        private const string AdminRequests = "/__admin/requests";
 37        private const string AdminSettings = "/__admin/settings";
 38        private const string AdminScenarios = "/__admin/scenarios";
 4739        private readonly RegexMatcher _adminMappingsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/mappings\/(\{{0,1}(
 4740        private readonly RegexMatcher _adminRequestsGuidPathMatcher = new RegexMatcher(@"^\/__admin\/requests\/(\{{0,1}(
 41
 4742        private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
 4743        {
 4744            Formatting = Formatting.Indented,
 4745            NullValueHandling = NullValueHandling.Ignore,
 4746        };
 47
 48        #region InitAdmin
 49        private void InitAdmin()
 350        {
 51            // __admin/settings
 352            Given(Request.Create().WithPath(AdminSettings).UsingGet()).RespondWith(new DynamicResponseProvider(SettingsG
 353            Given(Request.Create().WithPath(AdminSettings).UsingVerb("PUT", "POST").WithHeader(HttpKnownHeaderNames.Cont
 54
 55
 56            // __admin/mappings
 357            Given(Request.Create().WithPath(AdminMappings).UsingGet()).RespondWith(new DynamicResponseProvider(MappingsG
 358            Given(Request.Create().WithPath(AdminMappings).UsingPost().WithHeader(HttpKnownHeaderNames.ContentType, Cont
 359            Given(Request.Create().WithPath(AdminMappings).UsingDelete()).RespondWith(new DynamicResponseProvider(Mappin
 60
 61            // __admin/mappings/reset
 362            Given(Request.Create().WithPath(AdminMappings + "/reset").UsingPost()).RespondWith(new DynamicResponseProvid
 63
 64            // __admin/mappings/{guid}
 365            Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponsePr
 366            Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingPut().WithHeader(HttpKnownHeaderNames.Co
 367            Given(Request.Create().WithPath(_adminMappingsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicRespons
 68
 69            // __admin/mappings/save
 370            Given(Request.Create().WithPath(AdminMappings + "/save").UsingPost()).RespondWith(new DynamicResponseProvide
 71
 72
 73            // __admin/requests
 374            Given(Request.Create().WithPath(AdminRequests).UsingGet()).RespondWith(new DynamicResponseProvider(RequestsG
 375            Given(Request.Create().WithPath(AdminRequests).UsingDelete()).RespondWith(new DynamicResponseProvider(Reques
 76
 77            // __admin/requests/reset
 378            Given(Request.Create().WithPath(AdminRequests + "/reset").UsingPost()).RespondWith(new DynamicResponseProvid
 79
 80            // __admin/request/{guid}
 381            Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingGet()).RespondWith(new DynamicResponsePr
 382            Given(Request.Create().WithPath(_adminRequestsGuidPathMatcher).UsingDelete()).RespondWith(new DynamicRespons
 83
 84            // __admin/requests/find
 385            Given(Request.Create().WithPath(AdminRequests + "/find").UsingPost()).RespondWith(new DynamicResponseProvide
 86
 87
 88            // __admin/scenarios
 389            Given(Request.Create().WithPath(AdminScenarios).UsingGet()).RespondWith(new DynamicResponseProvider(Scenario
 390            Given(Request.Create().WithPath(AdminScenarios).UsingDelete()).RespondWith(new DynamicResponseProvider(Scena
 91
 92            // __admin/scenarios/reset
 393            Given(Request.Create().WithPath(AdminScenarios + "/reset").UsingPost()).RespondWith(new DynamicResponseProvi
 394        }
 95        #endregion
 96
 97        #region StaticMappings
 98        /// <summary>
 99        /// Reads the static mappings from a folder.
 100        /// </summary>
 101        /// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
 102        [PublicAPI]
 103        public void ReadStaticMappings([CanBeNull] string folder = null)
 1104        {
 1105             if (folder == null)
 0106            {
 0107                folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
 0108            }
 109
 1110             if (!Directory.Exists(folder))
 0111            {
 0112                return;
 113            }
 114
 9115            foreach (string filename in Directory.EnumerateFiles(folder).OrderBy(f => f))
 2116            {
 2117                _logger.Info("Reading Static MappingFile : '{0}'", filename);
 2118                ReadStaticMappingAndAddOrUpdate(filename);
 2119            }
 1120        }
 121
 122        /// <summary>
 123        /// Watches the static mappings for changes.
 124        /// </summary>
 125        /// <param name="folder">The optional folder. If not defined, use \__admin\mappings\</param>
 126        [PublicAPI]
 127        public void WatchStaticMappings([CanBeNull] string folder = null)
 0128        {
 0129             if (folder == null)
 0130            {
 0131                folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
 0132            }
 133
 0134             if (!Directory.Exists(folder))
 0135            {
 0136                return;
 137            }
 138
 0139            _logger.Info("Watching folder '{0}' for new, updated and deleted MappingFiles.", folder);
 140
 0141            var watcher = new EnhancedFileSystemWatcher(folder, "*.json", 1000);
 0142            watcher.Created += (sender, args) =>
 0143            {
 0144                _logger.Info("New MappingFile created : '{0}'", args.FullPath);
 0145                ReadStaticMappingAndAddOrUpdate(args.FullPath);
 0146            };
 0147            watcher.Changed += (sender, args) =>
 0148            {
 0149                _logger.Info("New MappingFile updated : '{0}'", args.FullPath);
 0150                ReadStaticMappingAndAddOrUpdate(args.FullPath);
 0151            };
 0152            watcher.Deleted += (sender, args) =>
 0153            {
 0154                _logger.Info("New MappingFile deleted : '{0}'", args.FullPath);
 0155                string filenameWithoutExtension = Path.GetFileNameWithoutExtension(args.FullPath);
 0156
 0157                 if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
 0158                {
 0159                    DeleteMapping(guidFromFilename);
 0160                }
 0161                else
 0162                {
 0163                    DeleteMapping(args.FullPath);
 0164                }
 0165            };
 166
 0167            watcher.EnableRaisingEvents = true;
 0168        }
 169
 170        /// <summary>
 171        /// Reads a static mapping file and adds or updates the mapping.
 172        /// </summary>
 173        /// <param name="path">The path.</param>
 174        [PublicAPI]
 175        public void ReadStaticMappingAndAddOrUpdate([NotNull] string path)
 4176        {
 4177            Check.NotNull(path, nameof(path));
 178
 4179            string filenameWithoutExtension = Path.GetFileNameWithoutExtension(path);
 180
 4181            MappingModel mappingModel = JsonConvert.DeserializeObject<MappingModel>(FileHelper.ReadAllText(path));
 4182             if (Guid.TryParse(filenameWithoutExtension, out Guid guidFromFilename))
 2183            {
 2184                DeserializeAndAddOrUpdateMapping(mappingModel, guidFromFilename, path);
 2185            }
 186            else
 2187            {
 2188                DeserializeAndAddOrUpdateMapping(mappingModel, null, path);
 2189            }
 4190        }
 191        #endregion
 192
 193        #region Proxy and Record
 194        private HttpClient _httpClientForProxy;
 195
 196        private void InitProxyAndRecord(IProxyAndRecordSettings settings)
 2197        {
 2198            _httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.ClientX509Certificate2ThumbprintOrSubjectNa
 2199            Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRec
 2200        }
 201
 202        private async Task<ResponseMessage> ProxyAndRecordAsync(RequestMessage requestMessage, IProxyAndRecordSettings s
 2203        {
 2204            var requestUri = new Uri(requestMessage.Url);
 2205            var proxyUri = new Uri(settings.Url);
 2206            var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
 207
 2208            var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequ
 209
 2210             if (settings.SaveMapping)
 2211            {
 2212                 var mapping = ToMapping(requestMessage, responseMessage, settings.BlackListedHeaders ?? new string[] { }
 2213                _options.Mappings.Add(mapping.Guid, mapping);
 214
 2215                 if (settings.SaveMappingToFile)
 0216                {
 0217                    SaveMappingToFile(mapping);
 0218                }
 2219            }
 220
 2221            return responseMessage;
 2222        }
 223
 224        private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage, string[] blacklistedHe
 2225        {
 2226            var request = Request.Create();
 2227            request.WithPath(requestMessage.Path);
 2228            request.UsingVerb(requestMessage.Method);
 229
 2230            requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
 2231            requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
 232
 2233            var allBlackListedHeaders = new List<string>(blacklistedHeaders) { "Cookie" };
 2234            requestMessage.Headers.Loop((key, value) =>
 15235            {
 34236                 if (!allBlackListedHeaders.Any(b => string.Equals(key, b, StringComparison.OrdinalIgnoreCase)))
 14237                {
 14238                    request.WithHeader(key, value.ToArray());
 14239                }
 15240            });
 241
 2242             if (requestMessage.Body != null)
 2243            {
 2244                request.WithBody(new ExactMatcher(requestMessage.Body));
 2245            }
 246
 2247            var response = Response.Create(responseMessage);
 248
 2249            return new Mapping(Guid.NewGuid(), string.Empty, null, request, response, 0, null, null, null);
 2250        }
 251        #endregion
 252
 253        #region Settings
 254        private ResponseMessage SettingsGet(RequestMessage requestMessage)
 0255        {
 0256            var model = new SettingsModel
 0257            {
 0258                AllowPartialMapping = _options.AllowPartialMapping,
 0259                MaxRequestLogCount = _options.MaxRequestLogCount,
 0260                RequestLogExpirationDuration = _options.RequestLogExpirationDuration,
 0261                GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds
 0262            };
 263
 0264            return ToJson(model);
 0265        }
 266
 267        private ResponseMessage SettingsUpdate(RequestMessage requestMessage)
 0268        {
 0269            var settings = requestMessage.Body != null ? JsonConvert.DeserializeObject<SettingsModel>(requestMessage.Bod
 270
 0271             if (settings.AllowPartialMapping != null)
 0272                _options.AllowPartialMapping = settings.AllowPartialMapping.Value;
 273
 0274            _options.MaxRequestLogCount = settings.MaxRequestLogCount;
 275
 0276            _options.RequestLogExpirationDuration = settings.RequestLogExpirationDuration;
 277
 0278             if (settings.GlobalProcessingDelay != null)
 0279                _options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
 280
 0281            return new ResponseMessage { Body = "Settings updated" };
 0282        }
 283        #endregion Settings
 284
 285        #region Mapping/{guid}
 286        private ResponseMessage MappingGet(RequestMessage requestMessage)
 0287        {
 0288            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
 0289            var mapping = Mappings.FirstOrDefault(m => !m.IsAdminInterface && m.Guid == guid);
 290
 0291             if (mapping == null)
 0292            {
 0293                _logger.Warn("HttpStatusCode set to 404 : Mapping not found");
 0294                return new ResponseMessage { StatusCode = 404, Body = "Mapping not found" };
 295            }
 296
 0297            var model = MappingConverter.ToMappingModel(mapping);
 298
 0299            return ToJson(model);
 0300        }
 301
 302        private ResponseMessage MappingPut(RequestMessage requestMessage)
 0303        {
 0304            Guid guid = Guid.Parse(requestMessage.Path.TrimStart(AdminMappings.ToCharArray()));
 305
 0306            MappingModel mappingModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<MappingModel>(reques
 0307            DeserializeAndAddOrUpdateMapping(mappingModel, guid);
 308
 0309            return new ResponseMessage { Body = "Mapping added or updated" };
 0310        }
 311
 312        private ResponseMessage MappingDelete(RequestMessage requestMessage)
 0313        {
 0314            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminMappings.Length + 1));
 315
 0316             if (DeleteMapping(guid))
 0317            {
 0318                return new ResponseMessage { Body = "Mapping removed" };
 319            }
 320
 0321            return new ResponseMessage { Body = "Mapping not found" };
 0322        }
 323        #endregion Mapping/{guid}
 324
 325        #region Mappings
 326        private ResponseMessage MappingsSave(RequestMessage requestMessage)
 0327        {
 0328            foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
 0329            {
 0330                SaveMappingToFile(mapping);
 0331            }
 332
 0333            return new ResponseMessage { Body = "Mappings saved to disk" };
 0334        }
 335
 336        private void SaveMappingToFile(Mapping mapping)
 0337        {
 0338            string folder = Path.Combine(Directory.GetCurrentDirectory(), AdminMappingsFolder);
 0339             if (!Directory.Exists(folder))
 0340            {
 0341                Directory.CreateDirectory(folder);
 0342            }
 343
 0344            var model = MappingConverter.ToMappingModel(mapping);
 0345            string filename = !string.IsNullOrEmpty(mapping.Title) ? SanitizeFileName(mapping.Title) : mapping.Guid.ToSt
 346
 0347            string filePath = Path.Combine(folder, filename + ".json");
 0348            _logger.Info("Saving Mapping to file {0}", filePath);
 349
 0350            File.WriteAllText(filePath, JsonConvert.SerializeObject(model, _settings));
 0351        }
 352
 353        private static string SanitizeFileName(string name, char replaceChar = '_')
 0354        {
 0355            return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, replaceChar));
 0356        }
 357
 358        private ResponseMessage MappingsGet(RequestMessage requestMessage)
 0359        {
 0360            var result = new List<MappingModel>();
 0361            foreach (var mapping in Mappings.Where(m => !m.IsAdminInterface))
 0362            {
 0363                var model = MappingConverter.ToMappingModel(mapping);
 0364                result.Add(model);
 0365            }
 366
 0367            return ToJson(result);
 0368        }
 369
 370        private ResponseMessage MappingsPost(RequestMessage requestMessage)
 1371        {
 372            try
 1373            {
 1374                MappingModel mappingModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<MappingModel>(re
 1375                DeserializeAndAddOrUpdateMapping(mappingModel);
 1376            }
 0377            catch (ArgumentException a)
 0378            {
 0379                _logger.Error("HttpStatusCode set to 400 {0}", a);
 0380                return new ResponseMessage { StatusCode = 400, Body = a.Message };
 381            }
 0382            catch (Exception e)
 0383            {
 0384                _logger.Error("HttpStatusCode set to 500 {0}", e);
 0385                return new ResponseMessage { StatusCode = 500, Body = e.ToString() };
 386            }
 387
 1388            return new ResponseMessage { StatusCode = 201, Body = "Mapping added" };
 1389        }
 390
 391        private void DeserializeAndAddOrUpdateMapping(MappingModel mappingModel, Guid? guid = null, string path = null)
 5392        {
 5393            Check.NotNull(mappingModel, nameof(mappingModel));
 5394            Check.NotNull(mappingModel.Request, nameof(mappingModel.Request));
 5395            Check.NotNull(mappingModel.Response, nameof(mappingModel.Response));
 396
 5397            var requestBuilder = InitRequestBuilder(mappingModel.Request);
 5398            var responseBuilder = InitResponseBuilder(mappingModel.Response);
 399
 5400            IRespondWithAProvider respondProvider = Given(requestBuilder);
 401
 5402             if (guid != null)
 2403            {
 2404                respondProvider = respondProvider.WithGuid(guid.Value);
 2405            }
 3406             else if (mappingModel.Guid != null && mappingModel.Guid != Guid.Empty)
 2407            {
 2408                respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
 2409            }
 410
 5411             if (path != null)
 4412            {
 4413                respondProvider = respondProvider.WithPath(path);
 4414            }
 415
 5416             if (!string.IsNullOrEmpty(mappingModel.Title))
 3417            {
 3418                respondProvider = respondProvider.WithTitle(mappingModel.Title);
 3419            }
 420
 5421             if (mappingModel.Priority != null)
 5422            {
 5423                respondProvider = respondProvider.AtPriority(mappingModel.Priority.Value);
 5424            }
 425
 5426             if (mappingModel.Scenario != null)
 0427            {
 0428                respondProvider = respondProvider.InScenario(mappingModel.Scenario);
 0429                respondProvider = respondProvider.WhenStateIs(mappingModel.WhenStateIs);
 0430                respondProvider = respondProvider.WillSetStateTo(mappingModel.SetStateTo);
 0431            }
 432
 5433            respondProvider.RespondWith(responseBuilder);
 5434        }
 435
 436        private ResponseMessage MappingsDelete(RequestMessage requestMessage)
 0437        {
 0438            ResetMappings();
 439
 0440            ResetScenarios();
 441
 0442            return new ResponseMessage { Body = "Mappings deleted" };
 0443        }
 444        #endregion Mappings
 445
 446        #region Request/{guid}
 447        private ResponseMessage RequestGet(RequestMessage requestMessage)
 0448        {
 0449            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));
 0450            var entry = LogEntries.FirstOrDefault(r => !r.RequestMessage.Path.StartsWith("/__admin/") && r.Guid == guid)
 451
 0452             if (entry == null)
 0453            {
 0454                _logger.Warn("HttpStatusCode set to 404 : Request not found");
 0455                return new ResponseMessage { StatusCode = 404, Body = "Request not found" };
 456            }
 457
 0458            var model = ToLogEntryModel(entry);
 459
 0460            return ToJson(model);
 0461        }
 462
 463        private ResponseMessage RequestDelete(RequestMessage requestMessage)
 0464        {
 0465            Guid guid = Guid.Parse(requestMessage.Path.Substring(AdminRequests.Length + 1));
 466
 0467             if (DeleteLogEntry(guid))
 0468                return new ResponseMessage { Body = "Request removed" };
 469
 0470            return new ResponseMessage { Body = "Request not found" };
 0471        }
 472        #endregion Request/{guid}
 473
 474        #region Requests
 475        private ResponseMessage RequestsGet(RequestMessage requestMessage)
 1476        {
 1477            var result = LogEntries
 2478                .Where(r => !r.RequestMessage.Path.StartsWith("/__admin/"))
 1479                .Select(ToLogEntryModel);
 480
 1481            return ToJson(result);
 1482        }
 483
 484        private LogEntryModel ToLogEntryModel(LogEntry logEntry)
 2485        {
 2486             return new LogEntryModel
 2487            {
 2488                Guid = logEntry.Guid,
 2489                Request = new LogRequestModel
 2490                {
 2491                    DateTime = logEntry.RequestMessage.DateTime,
 2492                    ClientIP = logEntry.RequestMessage.ClientIP,
 2493                    Path = logEntry.RequestMessage.Path,
 2494                    AbsoluteUrl = logEntry.RequestMessage.Url,
 2495                    Query = logEntry.RequestMessage.Query,
 2496                    Method = logEntry.RequestMessage.Method,
 2497                    Body = logEntry.RequestMessage.Body,
 2498                    BodyAsJson = logEntry.RequestMessage.BodyAsJson,
 2499                    BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
 2500                    Headers = logEntry.RequestMessage.Headers,
 2501                    Cookies = logEntry.RequestMessage.Cookies,
 2502                    BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
 2503                    {
 2504                        EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
 2505                        CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
 2506                        WebName = logEntry.RequestMessage.BodyEncoding.WebName
 2507                    } : null
 2508                },
 2509                Response = new LogResponseModel
 2510                {
 2511                    StatusCode = logEntry.ResponseMessage.StatusCode,
 2512                    BodyDestination = logEntry.ResponseMessage.BodyDestination,
 2513                    Body = logEntry.ResponseMessage.Body,
 2514                    BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
 2515                    BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
 2516                    BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
 2517                    BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
 2518                    BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
 2519                    Headers = logEntry.ResponseMessage.Headers,
 2520                    BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
 2521                    {
 2522                        EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
 2523                        CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
 2524                        WebName = logEntry.ResponseMessage.BodyEncoding.WebName
 2525                    } : null
 2526                },
 2527                MappingGuid = logEntry.MappingGuid,
 2528                MappingTitle = logEntry.MappingTitle,
 2529                RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
 2530                {
 2531                    TotalScore = logEntry.RequestMatchResult.TotalScore,
 2532                    TotalNumber = logEntry.RequestMatchResult.TotalNumber,
 2533                    IsPerfectMatch = logEntry.RequestMatchResult.IsPerfectMatch,
 2534                    AverageTotalScore = logEntry.RequestMatchResult.AverageTotalScore,
 2535                    MatchDetails = logEntry.RequestMatchResult.MatchDetails.Select(x => new
 2536                    {
 2537                        Name = x.Key.Name.Replace("RequestMessage", string.Empty),
 2538                        Score = x.Value
 2539                    } as object).ToList()
 2540                } : null
 2541            };
 2542        }
 543
 544        private ResponseMessage RequestsDelete(RequestMessage requestMessage)
 0545        {
 0546            ResetLogEntries();
 547
 0548            return new ResponseMessage { Body = "Requests deleted" };
 0549        }
 550        #endregion Requests
 551
 552        #region Requests/find
 553        private ResponseMessage RequestsFind(RequestMessage requestMessage)
 1554        {
 1555            var requestModel = requestMessage.Body != null ? JsonConvert.DeserializeObject<RequestModel>(requestMessage.
 556
 1557            var request = (Request)InitRequestBuilder(requestModel);
 558
 1559            var dict = new Dictionary<LogEntry, RequestMatchResult>();
 6560            foreach (var logEntry in LogEntries.Where(le => !le.RequestMessage.Path.StartsWith("/__admin/")))
 1561            {
 1562                var requestMatchResult = new RequestMatchResult();
 1563                 if (request.GetMatchingScore(logEntry.RequestMessage, requestMatchResult) > MatchScores.AlmostPerfect)
 1564                {
 1565                    dict.Add(logEntry, requestMatchResult);
 1566                }
 1567            }
 568
 3569            var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(ToLogEntryModel);
 570
 1571            return ToJson(result);
 1572        }
 573        #endregion Requests/find
 574
 575        #region Scenarios
 576        private ResponseMessage ScenariosGet(RequestMessage requestMessage)
 0577        {
 0578            var scenarios = Scenarios.Select(s => new
 0579            {
 0580                Name = s.Key,
 0581                Started = s.Value != null,
 0582                NextState = s.Value
 0583            });
 0584            return ToJson(scenarios);
 0585        }
 586
 587        private ResponseMessage ScenariosReset(RequestMessage requestMessage)
 0588        {
 0589            ResetScenarios();
 590
 0591            return new ResponseMessage { Body = "Scenarios reset" };
 0592        }
 593        #endregion
 594
 595        private IRequestBuilder InitRequestBuilder(RequestModel requestModel)
 6596        {
 6597            IRequestBuilder requestBuilder = Request.Create();
 598
 6599             if (requestModel.ClientIP != null)
 0600            {
 0601                string clientIP = requestModel.ClientIP as string;
 0602                 if (clientIP != null)
 0603                {
 0604                    requestBuilder = requestBuilder.WithClientIP(clientIP);
 0605                }
 606                else
 0607                {
 0608                    var clientIPModel = JsonUtils.ParseJTokenToObject<ClientIPModel>(requestModel.ClientIP);
 0609                     if (clientIPModel?.Matchers != null)
 0610                    {
 0611                        requestBuilder = requestBuilder.WithPath(clientIPModel.Matchers.Select(MatcherModelMapper.Map).C
 0612                    }
 0613                }
 0614            }
 615
 6616             if (requestModel.Path != null)
 5617            {
 5618                string path = requestModel.Path as string;
 5619                 if (path != null)
 1620                {
 1621                    requestBuilder = requestBuilder.WithPath(path);
 1622                }
 623                else
 4624                {
 4625                    var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
 4626                     if (pathModel?.Matchers != null)
 4627                    {
 4628                        requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MatcherModelMapper.Map).Cast<
 4629                    }
 4630                }
 5631            }
 632
 6633             if (requestModel.Url != null)
 0634            {
 0635                string url = requestModel.Url as string;
 0636                 if (url != null)
 0637                {
 0638                    requestBuilder = requestBuilder.WithUrl(url);
 0639                }
 640                else
 0641                {
 0642                    var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
 0643                     if (urlModel?.Matchers != null)
 0644                    {
 0645                        requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MatcherModelMapper.Map).Cast<IS
 0646                    }
 0647                }
 0648            }
 649
 6650             if (requestModel.Methods != null)
 5651            {
 5652                requestBuilder = requestBuilder.UsingVerb(requestModel.Methods);
 5653            }
 654
 6655             if (requestModel.Headers != null)
 0656            {
 0657                foreach (var headerModel in requestModel.Headers.Where(h => h.Matchers != null))
 0658                {
 0659                    requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(MatcherMode
 0660                }
 0661            }
 662
 6663             if (requestModel.Cookies != null)
 0664            {
 0665                foreach (var cookieModel in requestModel.Cookies.Where(c => c.Matchers != null))
 0666                {
 0667                    requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(MatcherMode
 0668                }
 0669            }
 670
 6671             if (requestModel.Params != null)
 0672            {
 0673                foreach (var paramModel in requestModel.Params)
 0674                {
 0675                    requestBuilder = paramModel.Values == null ? requestBuilder.WithParam(paramModel.Name) : requestBuil
 0676                }
 0677            }
 678
 6679             if (requestModel.Body?.Matcher != null)
 2680            {
 2681                var bodyMatcher = MatcherModelMapper.Map(requestModel.Body.Matcher);
 2682                requestBuilder = requestBuilder.WithBody(bodyMatcher);
 2683            }
 684
 6685            return requestBuilder;
 6686        }
 687
 688        private IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
 5689        {
 5690            IResponseBuilder responseBuilder = Response.Create();
 691
 5692             if (responseModel.Delay > 0)
 0693            {
 0694                responseBuilder = responseBuilder.WithDelay(responseModel.Delay.Value);
 0695            }
 696
 5697             if (!string.IsNullOrEmpty(responseModel.ProxyUrl))
 0698            {
 0699                 if (string.IsNullOrEmpty(responseModel.X509Certificate2ThumbprintOrSubjectName))
 0700                {
 0701                    return responseBuilder.WithProxy(responseModel.ProxyUrl);
 702                }
 703
 0704                return responseBuilder.WithProxy(responseModel.ProxyUrl, responseModel.X509Certificate2ThumbprintOrSubje
 705            }
 706
 5707             if (responseModel.StatusCode.HasValue)
 5708            {
 5709                responseBuilder = responseBuilder.WithStatusCode(responseModel.StatusCode.Value);
 5710            }
 711
 5712             if (responseModel.Headers != null)
 4713            {
 116714                foreach (var entry in responseModel.Headers)
 52715                {
 52716                    responseBuilder = entry.Value is string value ?
 52717                        responseBuilder.WithHeader(entry.Key, value) :
 52718                        responseBuilder.WithHeader(entry.Key, JsonUtils.ParseJTokenToObject<string[]>(entry.Value));
 52719                }
 4720            }
 1721             else if (responseModel.HeadersRaw != null)
 0722            {
 0723                foreach (string headerLine in responseModel.HeadersRaw.Split(new[] { "\n", "\r\n" }, StringSplitOptions.
 0724                {
 0725                    int indexColon = headerLine.IndexOf(":", StringComparison.Ordinal);
 0726                    string key = headerLine.Substring(0, indexColon).TrimStart(' ', '\t');
 0727                    string value = headerLine.Substring(indexColon + 1).TrimStart(' ', '\t');
 0728                    responseBuilder = responseBuilder.WithHeader(key, value);
 0729                }
 0730            }
 731
 5732             if (responseModel.BodyAsBytes != null)
 0733            {
 0734                responseBuilder = responseBuilder.WithBody(responseModel.BodyAsBytes, responseModel.BodyDestination, ToE
 0735            }
 5736             else if (responseModel.Body != null)
 5737            {
 5738                responseBuilder = responseBuilder.WithBody(responseModel.Body, responseModel.BodyDestination, ToEncoding
 5739            }
 0740             else if (responseModel.BodyAsJson != null)
 0741            {
 0742                responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.Body
 0743            }
 0744             else if (responseModel.BodyFromBase64 != null)
 0745            {
 0746                responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseMo
 0747            }
 748
 5749             if (responseModel.UseTransformer)
 0750            {
 0751                responseBuilder = responseBuilder.WithTransformer();
 0752            }
 753
 5754            return responseBuilder;
 5755        }
 756
 757        private ResponseMessage ToJson<T>(T result)
 2758        {
 2759            return new ResponseMessage
 2760            {
 2761                Body = JsonConvert.SerializeObject(result, _settings),
 2762                StatusCode = 200,
 2763                Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMoc
 2764            };
 2765        }
 766
 767        private Encoding ToEncoding(EncodingModel encodingModel)
 5768        {
 5769             return encodingModel != null ? Encoding.GetEncoding(encodingModel.CodePage) : null;
 5770        }
 771    }
 772}

C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.cs

#LineLine coverage
 1using System;
 2using System.Collections.Concurrent;
 3using System.Collections.Generic;
 4using System.Linq;
 5using System.Text;
 6using System.Threading.Tasks;
 7using JetBrains.Annotations;
 8using Newtonsoft.Json;
 9using WireMock.Http;
 10using WireMock.Logging;
 11using WireMock.Matchers;
 12using WireMock.Matchers.Request;
 13using WireMock.RequestBuilders;
 14using WireMock.Settings;
 15using WireMock.Validation;
 16using WireMock.Owin;
 17using WireMock.ResponseProviders;
 18
 19namespace WireMock.Server
 20{
 21    /// <summary>
 22    /// The fluent mock server.
 23    /// </summary>
 24    public partial class FluentMockServer : IDisposable
 25    {
 26        private readonly IWireMockLogger _logger;
 27        private const int ServerStartDelay = 100;
 28        private readonly IOwinSelfHost _httpServer;
 4729        private readonly WireMockMiddlewareOptions _options = new WireMockMiddlewareOptions();
 30
 31        /// <summary>
 32        /// Gets a value indicating whether this server is started.
 33        /// </summary>
 34        [PublicAPI]
 035        public bool IsStarted { get; }
 36
 37        /// <summary>
 38        /// Gets the ports.
 39        /// </summary>
 40        [PublicAPI]
 2941        public List<int> Ports { get; }
 42
 43        /// <summary>
 44        /// Gets the urls.
 45        /// </summary>
 46        [PublicAPI]
 7447        public string[] Urls { get; }
 48
 49        /// <summary>
 50        /// Gets the mappings.
 51        /// </summary>
 52        [PublicAPI]
 1253        public IEnumerable<Mapping> Mappings => _options.Mappings.Values.ToArray();
 54
 55        /// <summary>
 56        /// Gets the scenarios.
 57        /// </summary>
 58        [PublicAPI]
 059        public IDictionary<string, object> Scenarios => new ConcurrentDictionary<string, object>(_options.Scenarios);
 60
 61        #region Start/Stop
 62        /// <summary>
 63        /// Starts the specified settings.
 64        /// </summary>
 65        /// <param name="settings">The FluentMockServerSettings.</param>
 66        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 67        [PublicAPI]
 68        public static FluentMockServer Start(IFluentMockServerSettings settings)
 469        {
 470            Check.NotNull(settings, nameof(settings));
 71
 472            return new FluentMockServer(settings);
 473        }
 74
 75        /// <summary>
 76        /// Start this FluentMockServer.
 77        /// </summary>
 78        /// <param name="port">The port.</param>
 79        /// <param name="ssl">The SSL support.</param>
 80        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 81        [PublicAPI]
 82        public static FluentMockServer Start([CanBeNull] int? port = 0, bool ssl = false)
 4083        {
 4084            return new FluentMockServer(new FluentMockServerSettings
 4085            {
 4086                Port = port,
 4087                UseSSL = ssl
 4088            });
 4089        }
 90
 91        /// <summary>
 92        /// Start this FluentMockServer.
 93        /// </summary>
 94        /// <param name="urls">The urls to listen on.</param>
 95        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 96        [PublicAPI]
 97        public static FluentMockServer Start(params string[] urls)
 298        {
 299            Check.NotNullOrEmpty(urls, nameof(urls));
 100
 2101            return new FluentMockServer(new FluentMockServerSettings
 2102            {
 2103                Urls = urls
 2104            });
 2105        }
 106
 107        /// <summary>
 108        /// Start this FluentMockServer with the admin interface.
 109        /// </summary>
 110        /// <param name="port">The port.</param>
 111        /// <param name="ssl">The SSL support.</param>
 112        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 113        [PublicAPI]
 114        public static FluentMockServer StartWithAdminInterface(int? port = 0, bool ssl = false)
 1115        {
 1116            return new FluentMockServer(new FluentMockServerSettings
 1117            {
 1118                Port = port,
 1119                UseSSL = ssl,
 1120                StartAdminInterface = true
 1121            });
 1122        }
 123
 124        /// <summary>
 125        /// Start this FluentMockServer with the admin interface.
 126        /// </summary>
 127        /// <param name="urls">The urls.</param>
 128        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 129        [PublicAPI]
 130        public static FluentMockServer StartWithAdminInterface(params string[] urls)
 0131        {
 0132            Check.NotNullOrEmpty(urls, nameof(urls));
 133
 0134            return new FluentMockServer(new FluentMockServerSettings
 0135            {
 0136                Urls = urls,
 0137                StartAdminInterface = true
 0138            });
 0139        }
 140
 141        /// <summary>
 142        /// Start this FluentMockServer with the admin interface and read static mappings.
 143        /// </summary>
 144        /// <param name="urls">The urls.</param>
 145        /// <returns>The <see cref="FluentMockServer"/>.</returns>
 146        [PublicAPI]
 147        public static FluentMockServer StartWithAdminInterfaceAndReadStaticMappings(params string[] urls)
 0148        {
 0149            Check.NotNullOrEmpty(urls, nameof(urls));
 150
 0151            return new FluentMockServer(new FluentMockServerSettings
 0152            {
 0153                Urls = urls,
 0154                StartAdminInterface = true,
 0155                ReadStaticMappings = true
 0156            });
 0157        }
 158
 47159        private FluentMockServer(IFluentMockServerSettings settings)
 47160        {
 47161             settings.Logger = settings.Logger ?? new WireMockConsoleLogger();
 47162            _logger = settings.Logger;
 163
 47164            _logger.Debug("WireMock.Net server settings {0}", JsonConvert.SerializeObject(settings, Formatting.Indented)
 165
 47166             if (settings.Urls != null)
 2167            {
 4168                Urls = settings.Urls.Select(u => u.EndsWith("/") ? u : $"{u}/").ToArray();
 2169            }
 170            else
 45171            {
 45172                 int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort();
 45173                 Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
 45174            }
 175
 47176            _options.PreWireMockMiddlewareInit = settings.PreWireMockMiddlewareInit;
 47177            _options.PostWireMockMiddlewareInit = settings.PostWireMockMiddlewareInit;
 47178            _options.Logger = _logger;
 179
 180#if NETSTANDARD
 181            _httpServer = new AspNetCoreSelfHost(_options, Urls);
 182#else
 47183            _httpServer = new OwinSelfHost(_options, Urls);
 184#endif
 47185            Ports = _httpServer.Ports;
 186
 47187            _httpServer.StartAsync();
 188
 189            // Fix for 'Bug: Server not listening after Start() returns (on macOS)'
 47190            Task.Delay(ServerStartDelay).Wait();
 191
 47192            IsStarted = _httpServer.IsStarted;
 193
 47194             if (settings.AllowPartialMapping == true)
 0195            {
 0196                AllowPartialMapping();
 0197            }
 198
 47199             if (settings.StartAdminInterface == true)
 3200            {
 3201                 if (!string.IsNullOrEmpty(settings.AdminUsername) && !string.IsNullOrEmpty(settings.AdminPassword))
 0202                {
 0203                    SetBasicAuthentication(settings.AdminUsername, settings.AdminPassword);
 0204                }
 205
 3206                InitAdmin();
 3207            }
 208
 47209             if (settings.ReadStaticMappings == true)
 0210            {
 0211                ReadStaticMappings();
 0212            }
 213
 47214             if (settings.WatchStaticMappings == true)
 0215            {
 0216                WatchStaticMappings();
 0217            }
 218
 47219             if (settings.ProxyAndRecordSettings != null)
 2220            {
 2221                InitProxyAndRecord(settings.ProxyAndRecordSettings);
 2222            }
 223
 47224             if (settings.MaxRequestLogCount != null)
 0225            {
 0226                SetMaxRequestLogCount(settings.MaxRequestLogCount);
 0227            }
 47228        }
 229
 230        /// <summary>
 231        /// Stop this server.
 232        /// </summary>
 233        [PublicAPI]
 234        public void Stop()
 42235        {
 42236             _httpServer?.StopAsync();
 42237        }
 238        #endregion
 239
 240        /// <summary>
 241        /// Adds the catch all mapping.
 242        /// </summary>
 243        [PublicAPI]
 244        public void AddCatchAllMapping()
 0245        {
 0246            Given(Request.Create().WithPath("/*").UsingAnyVerb())
 0247                .WithGuid(Guid.Parse("90008000-0000-4444-a17e-669cd84f1f05"))
 0248                .AtPriority(1000)
 0249                .RespondWith(new DynamicResponseProvider(request => new ResponseMessage { StatusCode = 404, Body = "No m
 0250        }
 251
 252        /// <summary>
 253        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 254        /// </summary>
 255        public void Dispose()
 5256        {
 5257             if (_httpServer != null && _httpServer.IsStarted)
 5258            {
 5259                _httpServer.StopAsync();
 5260            }
 5261        }
 262
 263        /// <summary>
 264        /// Resets LogEntries and Mappings.
 265        /// </summary>
 266        [PublicAPI]
 267        public void Reset()
 0268        {
 0269            ResetLogEntries();
 270
 0271            ResetMappings();
 0272        }
 273
 274        /// <summary>
 275        /// Resets the Mappings.
 276        /// </summary>
 277        [PublicAPI]
 278        public void ResetMappings()
 1279        {
 6280            foreach (var nonAdmin in _options.Mappings.Where(m => !m.Value.IsAdminInterface))
 1281            {
 1282                _options.Mappings.Remove(nonAdmin);
 1283            }
 1284        }
 285
 286        /// <summary>
 287        /// Deletes the mapping.
 288        /// </summary>
 289        /// <param name="guid">The unique identifier.</param>
 290        [PublicAPI]
 291        public bool DeleteMapping(Guid guid)
 0292        {
 293            // Check a mapping exists with the same GUID, if so, remove it.
 0294             if (_options.Mappings.ContainsKey(guid))
 0295            {
 0296                return _options.Mappings.Remove(guid);
 297            }
 298
 0299            return false;
 0300        }
 301
 302        private bool DeleteMapping(string path)
 0303        {
 304            // Check a mapping exists with the same path, if so, remove it.
 0305            var mapping = _options.Mappings.FirstOrDefault(entry => string.Equals(entry.Value.Path, path, StringComparis
 0306            return DeleteMapping(mapping.Key);
 0307        }
 308
 309        /// <summary>
 310        /// The add request processing delay.
 311        /// </summary>
 312        /// <param name="delay">The delay.</param>
 313        [PublicAPI]
 314        public void AddGlobalProcessingDelay(TimeSpan delay)
 1315        {
 1316            _options.RequestProcessingDelay = delay;
 1317        }
 318
 319        /// <summary>
 320        /// Allows the partial mapping.
 321        /// </summary>
 322        [PublicAPI]
 323        public void AllowPartialMapping(bool allow = true)
 0324        {
 0325            _logger.Info("AllowPartialMapping is set to {0}", allow);
 0326            _options.AllowPartialMapping = allow;
 0327        }
 328
 329        /// <summary>
 330        /// Sets the basic authentication.
 331        /// </summary>
 332        /// <param name="username">The username.</param>
 333        /// <param name="password">The password.</param>
 334        [PublicAPI]
 335        public void SetBasicAuthentication([NotNull] string username, [NotNull] string password)
 0336        {
 0337            Check.NotNull(username, nameof(username));
 0338            Check.NotNull(password, nameof(password));
 339
 0340            string authorization = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1").GetBytes(username + ":" + p
 0341            _options.AuthorizationMatcher = new RegexMatcher("^(?i)BASIC " + authorization + "$");
 0342        }
 343
 344        /// <summary>
 345        /// Removes the basic authentication.
 346        /// </summary>
 347        [PublicAPI]
 348        public void RemoveBasicAuthentication()
 0349        {
 0350            _options.AuthorizationMatcher = null;
 0351        }
 352
 353        /// <summary>
 354        /// Sets the maximum RequestLog count.
 355        /// </summary>
 356        /// <param name="maxRequestLogCount">The maximum RequestLog count.</param>
 357        [PublicAPI]
 358        public void SetMaxRequestLogCount([CanBeNull] int? maxRequestLogCount)
 1359        {
 1360            _options.MaxRequestLogCount = maxRequestLogCount;
 361
 1362        }
 363
 364        /// <summary>
 365        /// Sets RequestLog expiration in hours.
 366        /// </summary>
 367        /// <param name="requestLogExpirationDuration">The RequestLog expiration in hours.</param>
 368        [PublicAPI]
 369        public void SetRequestLogExpirationDuration([CanBeNull] int? requestLogExpirationDuration)
 0370        {
 0371            _options.RequestLogExpirationDuration = requestLogExpirationDuration;
 0372        }
 373
 374        /// <summary>
 375        /// Resets the Scenarios.
 376        /// </summary>
 377        [PublicAPI]
 378        public void ResetScenarios()
 0379        {
 0380            _options.Scenarios.Clear();
 0381        }
 382
 383        /// <summary>
 384        /// The given.
 385        /// </summary>
 386        /// <param name="requestMatcher">The request matcher.</param>
 387        /// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
 388        [PublicAPI]
 389        public IRespondWithAProvider Given(IRequestMatcher requestMatcher)
 103390        {
 103391            return new RespondWithAProvider(RegisterMapping, requestMatcher);
 103392        }
 393
 394        private void RegisterMapping(Mapping mapping)
 103395        {
 396            // Check a mapping exists with the same Guid, if so, replace it.
 103397             if (_options.Mappings.ContainsKey(mapping.Guid))
 1398            {
 1399                _options.Mappings[mapping.Guid] = mapping;
 1400            }
 401            else
 102402            {
 102403                _options.Mappings.Add(mapping.Guid, mapping);
 102404            }
 103405        }
 406    }
 407}

C:\Users\azureuser\Documents\Github\WireMock.Net\src\WireMock.Net\Server\FluentMockServer.LogEntries.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Collections.ObjectModel;
 5using System.Collections.Specialized;
 6using JetBrains.Annotations;
 7using WireMock.Logging;
 8using WireMock.Matchers.Request;
 9using System.Linq;
 10using WireMock.Matchers;
 11
 12namespace WireMock.Server
 13{
 14    public partial class FluentMockServer
 15    {
 16        /// <summary>
 17        /// Occurs when [log entries changed].
 18        /// </summary>
 19        [PublicAPI]
 20        public event NotifyCollectionChangedEventHandler LogEntriesChanged
 21        {
 222            add => _options.LogEntries.CollectionChanged += value;
 023            remove => _options.LogEntries.CollectionChanged -= value;
 24        }
 25
 26        /// <summary>
 27        /// Gets the request logs.
 28        /// </summary>
 29        [PublicAPI]
 1430        public IEnumerable<LogEntry> LogEntries => new ReadOnlyCollection<LogEntry>(_options.LogEntries);
 31
 32        /// <summary>
 33        /// The search log-entries based on matchers.
 34        /// </summary>
 35        /// <param name="matchers">The matchers.</param>
 36        /// <returns>The <see cref="IEnumerable"/>.</returns>
 37        [PublicAPI]
 38        public IEnumerable<LogEntry> FindLogEntries([NotNull] params IRequestMatcher[] matchers)
 139        {
 140            var results = new Dictionary<LogEntry, RequestMatchResult>();
 41
 742            foreach (var log in _options.LogEntries)
 243            {
 244                var requestMatchResult = new RequestMatchResult();
 1045                foreach (var matcher in matchers)
 246                {
 247                    matcher.GetMatchingScore(log.RequestMessage, requestMatchResult);
 248                }
 49
 250                 if (requestMatchResult.AverageTotalScore > MatchScores.AlmostPerfect)
 151                {
 152                    results.Add(log, requestMatchResult);
 153                }
 254            }
 55
 356            return new ReadOnlyCollection<LogEntry>(results.OrderBy(x => x.Value).Select(x => x.Key).ToList());
 157        }
 58
 59        /// <summary>
 60        /// Resets the LogEntries.
 61        /// </summary>
 62        [PublicAPI]
 63        public void ResetLogEntries()
 164        {
 165            _options.LogEntries.Clear();
 166        }
 67
 68        /// <summary>
 69        /// Deletes a LogEntry.
 70        /// </summary>
 71        /// <param name="guid">The unique identifier.</param>
 72        [PublicAPI]
 73        public bool DeleteLogEntry(Guid guid)
 074        {
 75            // Check a logentry exists with the same GUID, if so, remove it.
 076            var existing = _options.LogEntries.FirstOrDefault(m => m.Guid == guid);
 077             if (existing != null)
 078            {
 079                _options.LogEntries.Remove(existing);
 080                return true;
 81            }
 82
 083            return false;
 084        }
 85    }
 86}

Methods/Properties

.cctor()
.ctor(WireMock.Settings.IFluentMockServerSettings)
InitAdmin()
ReadStaticMappings(System.String)
WatchStaticMappings(System.String)
ReadStaticMappingAndAddOrUpdate(System.String)
InitProxyAndRecord(WireMock.Settings.IProxyAndRecordSettings)
ProxyAndRecordAsync()
ToMapping(WireMock.RequestMessage,WireMock.ResponseMessage,System.String[])
SettingsGet(WireMock.RequestMessage)
SettingsUpdate(WireMock.RequestMessage)
MappingGet(WireMock.RequestMessage)
MappingPut(WireMock.RequestMessage)
MappingDelete(WireMock.RequestMessage)
MappingsSave(WireMock.RequestMessage)
SaveMappingToFile(WireMock.Mapping)
SanitizeFileName(System.String,System.Char)
MappingsGet(WireMock.RequestMessage)
MappingsPost(WireMock.RequestMessage)
DeserializeAndAddOrUpdateMapping(WireMock.Admin.Mappings.MappingModel,System.Nullable`1<System.Guid>,System.String)
MappingsDelete(WireMock.RequestMessage)
RequestGet(WireMock.RequestMessage)
RequestDelete(WireMock.RequestMessage)
RequestsGet(WireMock.RequestMessage)
ToLogEntryModel(WireMock.Logging.LogEntry)
RequestsDelete(WireMock.RequestMessage)
RequestsFind(WireMock.RequestMessage)
ScenariosGet(WireMock.RequestMessage)
ScenariosReset(WireMock.RequestMessage)
InitRequestBuilder(WireMock.Admin.Mappings.RequestModel)
InitResponseBuilder(WireMock.Admin.Mappings.ResponseModel)
ToJson(T)
ToEncoding(WireMock.Admin.Mappings.EncodingModel)
IsStarted()
Ports()
Urls()
Mappings()
Scenarios()
Start(WireMock.Settings.IFluentMockServerSettings)
Start(System.Nullable`1<System.Int32>,System.Boolean)
Start(System.String[])
StartWithAdminInterface(System.Nullable`1<System.Int32>,System.Boolean)
StartWithAdminInterface(System.String[])
StartWithAdminInterfaceAndReadStaticMappings(System.String[])
Stop()
AddCatchAllMapping()
Dispose()
Reset()
ResetMappings()
DeleteMapping(System.Guid)
DeleteMapping(System.String)
AddGlobalProcessingDelay(System.TimeSpan)
AllowPartialMapping(System.Boolean)
SetBasicAuthentication(System.String,System.String)
RemoveBasicAuthentication()
SetMaxRequestLogCount(System.Nullable`1<System.Int32>)
SetRequestLogExpirationDuration(System.Nullable`1<System.Int32>)
ResetScenarios()
Given(WireMock.Matchers.Request.IRequestMatcher)
RegisterMapping(WireMock.Mapping)
add_LogEntriesChanged(System.Collections.Specialized.NotifyCollectionChangedEventHandler)
remove_LogEntriesChanged(System.Collections.Specialized.NotifyCollectionChangedEventHandler)
LogEntries()
FindLogEntries(WireMock.Matchers.Request.IRequestMatcher[])
ResetLogEntries()
DeleteLogEntry(System.Guid)