public void QueryStringConditionChecker_Validate_StubsFound_OnlyOneQueryStringCorrect_ShouldReturnInvalid() { // arrange var query = new Dictionary <string, string> { { "q", "1" }, { "y", "2" } }; var conditions = new StubConditionsModel { Url = new StubUrlConditionModel { Query = new Dictionary <string, string> { { "q", "1" }, { "y", "3" } } } }; _httpContextServiceMock .Setup(m => m.GetQueryStringDictionary()) .Returns(query); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Invalid, result.ConditionValidation); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { var pair = request.Headers.FirstOrDefault(p => p.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)); var contentType = pair.Value; if (string.IsNullOrWhiteSpace(contentType)) { return(Task.FromResult(false)); } var supportedContentTypes = new[] { Constants.UrlEncodedFormMime, Constants.MultipartFormDataMime }; if ( !supportedContentTypes.Any(sc => contentType.StartsWith(sc, StringComparison.OrdinalIgnoreCase)) || string.IsNullOrWhiteSpace(request.Body)) { return(Task.FromResult(false)); } // If the body condition is already set, clear it here. conditions.Body = Array.Empty <string>(); var reader = new FormReader(request.Body); var form = reader.ReadForm(); conditions.Form = form.Select(f => new StubFormModel { Key = f.Key, Value = f.Value }); return(Task.FromResult(true)); }
public void HeaderConditionCheckerValidateAsync_StubsFound_OnlyOneHeaderCorrect_ShouldReturnInvalid() { // arrange var headers = new Dictionary <string, string> { { "X-Api-Key", "1" }, { "X-Another-Secret", "2" } }; var conditions = new StubConditionsModel { Headers = new Dictionary <string, string> { { "X-Api-Key", "1" }, { "X-Another-Secret", "3" } } }; _httpContextServiceMock .Setup(m => m.GetHeaders()) .Returns(headers); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Invalid, result.ConditionValidation); }
public void HeaderConditionCheckerValidateAsync_StubsFound_HappyFlow() { // arrange var headers = new Dictionary <string, string> { { "X-Api-Key", "123abc" }, { "X-Another-Secret", "blaaaaah 123" } }; var conditions = new StubConditionsModel { Headers = new Dictionary <string, string> { { "X-Api-Key", "123abc" }, { "X-Another-Secret", @"\bblaaaaah\b" } } }; _httpContextServiceMock .Setup(m => m.GetHeaders()) .Returns(headers); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Valid, result.ConditionValidation); }
public ConditionCheckResultModel Validate(string stubId, StubConditionsModel conditions) { var result = new ConditionCheckResultModel(); var bodyConditions = conditions?.Body?.ToArray(); if (bodyConditions == null || bodyConditions?.Any() != true) { return(result); } var body = _httpContextService.GetBody(); var validBodyConditions = 0; foreach (var condition in bodyConditions) { if (!StringHelper.IsRegexMatchOrSubstring(body, condition)) { // If the check failed, it means the query string is incorrect and the condition should fail. result.Log = $"Body condition '{condition}' failed."; break; } validBodyConditions++; } // If the number of succeeded conditions is equal to the actual number of conditions, // the body condition is passed and the stub ID is passed to the result. result.ConditionValidation = validBodyConditions == bodyConditions.Length ? ConditionValidationType.Valid : ConditionValidationType.Invalid; return(result); }
public ConditionCheckResultModel Validate(string stubId, StubConditionsModel conditions) { var result = new ConditionCheckResultModel(); var jsonPathConditions = conditions?.JsonPath?.ToArray(); if (jsonPathConditions == null || jsonPathConditions?.Any() != true) { return(result); } var validJsonPaths = 0; var body = _httpContextService.GetBody(); var jsonObject = JObject.Parse(body); foreach (var condition in jsonPathConditions) { var elements = jsonObject.SelectToken(condition); if (elements == null) { // No suitable JSON results found. result.Log = $"No suitable JSON results found with JSONPath query '{condition}'."; break; } validJsonPaths++; } // If the number of succeeded conditions is equal to the actual number of conditions, // the header condition is passed and the stub ID is passed to the result. result.ConditionValidation = validJsonPaths == jsonPathConditions.Length ? ConditionValidationType.Valid : ConditionValidationType.Invalid; return(result); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { var pair = request.Headers.FirstOrDefault(p => p.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrWhiteSpace(pair.Value) || !pair.Value.Trim().ToLower().StartsWith("Basic", StringComparison.OrdinalIgnoreCase)) { return(Task.FromResult(false)); } var value = pair.Value; value = value.Replace("Basic ", string.Empty); var basicAuth = Encoding.UTF8.GetString(Convert.FromBase64String(value)); var parts = basicAuth.Split(':'); if (parts.Length != 2) { return(Task.FromResult(false)); } conditions.BasicAuthentication = new StubBasicAuthenticationModel { Username = parts[0], Password = parts[1] }; // Make sure the original Authorization header is removed here. conditions.Headers = conditions.Headers .Where(h => !h.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase)) .ToDictionary(d => d.Key, d => d.Value); return(Task.FromResult(true)); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { var uri = new Uri(request.Url); conditions.Url.Path = uri.LocalPath; return(Task.FromResult(true)); }
public void XPathConditionChecker_Validate_StubsFound_HappyFlow_WithoutNamespaces() { // arrange const string body = @"<?xml version=""1.0""?> <object> <a>TEST</a> <b>TEST2</b> </object>"; var conditions = new StubConditionsModel { Xpath = new[] { new StubXpathModel { QueryString = "/object/a[text() = 'TEST']" }, new StubXpathModel { QueryString = "/object/b[text() = 'TEST2']" } } }; _httpContextServiceMock .Setup(m => m.GetBody()) .Returns(body); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Valid, result.ConditionValidation); }
public ConditionCheckResultModel Validate(string stubId, StubConditionsModel conditions) { var result = new ConditionCheckResultModel(); var fullPathCondition = conditions?.Url?.FullPath; if (string.IsNullOrEmpty(fullPathCondition)) { return(result); } var path = _httpContextService.FullPath; if (StringHelper.IsRegexMatchOrSubstring(path, fullPathCondition)) { // The path matches the provided regex. Add the stub ID to the resulting list. result.ConditionValidation = ConditionValidationType.Valid; } else { result.Log = $"Condition '{fullPathCondition}' did not pass for request."; result.ConditionValidation = ConditionValidationType.Invalid; } return(result); }
public void BasicAuthenticationConditionChecker_Validate_BasicAuthenticationIncorrect_ShouldReturnInvalid() { // arrange var conditions = new StubConditionsModel { BasicAuthentication = new StubBasicAuthenticationModel { Username = "******", Password = "******" } }; var headers = new Dictionary <string, string> { { "Authorization", "Basic dXNlcm5hbWU6cGFzc3dvcmRk" } }; _httpContextServiceMock .Setup(m => m.GetHeaders()) .Returns(headers); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Invalid, result.ConditionValidation); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { if (string.IsNullOrWhiteSpace(request.Method)) { throw new InvalidOperationException("No HTTP method set; this is unexpected."); } conditions.Method = request.Method; return(Task.FromResult(true)); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { if (!request.Url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { return(Task.FromResult(false)); } conditions.Url.IsHttps = true; return(Task.FromResult(true)); }
BasicAuthenticationConditionChecker_Validate_StubsFound_ButNoBasicAuthenticationCondition_ShouldReturnNotExecuted() { // arrange var conditions = new StubConditionsModel { BasicAuthentication = null }; // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.NotExecuted, result.ConditionValidation); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { var uri = new Uri(request.Url); var host = uri.Host; if (uri.Port != 80 && uri.Port != 443) { host += $":{uri.Port}"; } conditions.Host = host; return(Task.FromResult(true)); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { var uri = new Uri(request.Url); var query = QueryHelpers.ParseQuery(uri.Query); if (!query.Any()) { return(Task.FromResult(false)); } conditions.Url.Query = query.ToDictionary(q => q.Key, q => q.Value.ToString()); return(Task.FromResult(true)); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { if (!request.Headers.Any()) { return(Task.FromResult(false)); } // Do a Regex escape here, if we don do this it might give some strange results later on // and filter some headers out. conditions.Headers = request.Headers .Where(h => !_headersToStrip.Contains(h.Key, StringComparer.OrdinalIgnoreCase)) .ToDictionary(d => d.Key, d => Regex.Escape(d.Value)); return(Task.FromResult(true)); }
public void JsonPathConditionChecker_Validate_StubsFound_ButNoJsonPathConditions_ShouldReturnNotExecuted() { // arrange var conditions = new StubConditionsModel { JsonPath = null }; // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.NotExecuted, result.ConditionValidation); }
public void HostConditionChecker_Validate_NoConditionFound_ShouldReturnNotExecuted() { // arrange var conditions = new StubConditionsModel { Host = null }; // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.NotExecuted, result.ConditionValidation); }
public void HeaderConditionCheckerValidateAsync_StubsFound_ButNoQueryStringConditions_ShouldReturnNotExecuted() { // arrange var conditions = new StubConditionsModel { Headers = null }; // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.NotExecuted, result.ConditionValidation); }
public void XPathConditionChecker_Validate_StubsFound_OnlyOneXPathConditionCorrect_ShouldReturnInvalid() { // arrange const string body = @"<?xml version=""1.0""?> <soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:m=""http://www.example.org/stock/Reddy""> <soap:Header> </soap:Header> <soap:Body> <m:GetStockPrice> <m:StockName>Umbrella</m:StockName> <m:Description>An umbrella</m:Description> </m:GetStockPrice> </soap:Body> </soap:Envelope>"; var conditions = new StubConditionsModel { Xpath = new[] { new StubXpathModel { QueryString = "/soap:Envelope/soap:Body/m:GetStockPrice/m:StockName[text() = 'Umbrella']", Namespaces = new Dictionary <string, string> { { "soap", "http://www.w3.org/2003/05/soap-envelope" }, { "m", "http://www.example.org/stock/Reddy" } } }, new StubXpathModel { QueryString = "/soap:Envelope/soap:Body/m:GetStockPrice/m:Description[text() = 'A pair of shades']", Namespaces = new Dictionary <string, string> { { "soap", "http://www.w3.org/2003/05/soap-envelope" }, { "m", "http://www.example.org/stock/Reddy" } } } } }; _httpContextServiceMock .Setup(m => m.GetBody()) .Returns(body); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Invalid, result.ConditionValidation); }
public ConditionCheckResultModel Validate(string stubId, StubConditionsModel conditions) { var result = new ConditionCheckResultModel(); var xpathConditions = conditions?.Xpath?.ToArray() ?? new StubXpathModel[0]; if (!xpathConditions.Any()) { return(result); } var validXpaths = 0; var body = _httpContextService.GetBody(); var doc = new XmlDocument(); doc.LoadXml(body); foreach (var condition in xpathConditions) { var nsManager = new XmlNamespaceManager(doc.NameTable); var namespaces = condition.Namespaces; if (namespaces != null) { foreach (var ns in namespaces) { nsManager.AddNamespace(ns.Key, ns.Value); } } else { // If no namespaces are defined, check the XML namespaces with a regex. nsManager.ParseBodyAndAssignNamespaces(body); } var elements = doc.SelectNodes(condition.QueryString, nsManager); if (elements != null && elements.Count == 0) { // No suitable XML results found. result.Log = $"No suitable XML results found with XPath query {condition}."; break; } validXpaths++; } // If the number of succeeded conditions is equal to the actual number of conditions, // the header condition is passed and the stub ID is passed to the result. result.ConditionValidation = validXpaths == xpathConditions.Length ? ConditionValidationType.Valid : ConditionValidationType.Invalid; return(result); }
/// <inheritdoc /> public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions) { if (conditions.Json != null) { return(Task.FromResult(false)); } if (string.IsNullOrWhiteSpace(request.Body)) { return(Task.FromResult(false)); } conditions.Body = new[] { request.Body }; return(Task.FromResult(true)); }
/// <inheritdoc/> public async Task <StubConditionsModel> ConvertToConditionsAsync(HttpRequestModel request) { var conditions = new StubConditionsModel(); foreach (var handler in _handlers.OrderByDescending(w => w.Priority)) { var executed = await handler.HandleStubGenerationAsync(request, conditions); _logger.LogDebug( $"Handler '{handler.GetType().Name}' " + (executed ? "executed" : "not executed") + "."); } return(conditions); }
public void ClientIpConditionChecker_Validate_ConditionNotSet_ShouldReturnNotExecuted() { // arrange const string stubId = "stub1"; var conditions = new StubConditionsModel { ClientIp = null }; // act var result = _checker.Validate(stubId, conditions); // assert Assert.AreEqual(ConditionValidationType.NotExecuted, result.ConditionValidation); }
BasicAuthenticationConditionChecker_Validate_StubsFound_NoUsernameAndPasswordSet_ShouldReturnNotExecuted() { // arrange var conditions = new StubConditionsModel { BasicAuthentication = new StubBasicAuthenticationModel { Username = null, Password = null } }; // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.NotExecuted, result.ConditionValidation); }
public ConditionCheckResultModel Validate(string stubId, StubConditionsModel conditions) { var result = new ConditionCheckResultModel(); var hostCondition = conditions?.Host; if (hostCondition == null) { return(result); } var host = _clientDataResolver.GetHost(); result.ConditionValidation = !StringHelper.IsRegexMatchOrSubstring(host, hostCondition) ? ConditionValidationType.Invalid : ConditionValidationType.Valid; return(result); }
public void MethodConditionChecker_Validate_StubsFound_HappyFlow() { // arrange var conditions = new StubConditionsModel { Method = "GET" }; _httpContextServiceMock .Setup(m => m.Method) .Returns("GET"); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Valid, result.ConditionValidation); }
public ConditionCheckResultModel Validate(string stubId, StubConditionsModel conditions) { var result = new ConditionCheckResultModel(); var condition = conditions?.Url?.IsHttps; if (condition == null) { return(result); } var shouldBeHttps = condition.Value; var isHttps = _clientDataResolver.IsHttps(); result.ConditionValidation = isHttps == shouldBeHttps ? ConditionValidationType.Valid : ConditionValidationType.Invalid; return(result); }
public void HostConditionChecker_Validate_ConditionCorrectRegex_ShouldReturnValid() { // arrange const string host = "httplaceholder.com"; var conditions = new StubConditionsModel { Host = "http(.*)" }; _clientDataResolverMock .Setup(m => m.GetHost()) .Returns(host); // act var result = _checker.Validate("id", conditions); // assert Assert.AreEqual(ConditionValidationType.Valid, result.ConditionValidation); }