Пример #1
0
        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);
        }
Пример #2
0
    /// <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);
        }
Пример #6
0
        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);
        }
Пример #7
0
    /// <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));
    }
Пример #8
0
    /// <inheritdoc />
    public Task <bool> HandleStubGenerationAsync(HttpRequestModel request, StubConditionsModel conditions)
    {
        var uri = new Uri(request.Url);

        conditions.Url.Path = uri.LocalPath;
        return(Task.FromResult(true));
    }
Пример #9
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
    /// <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));
    }
Пример #13
0
    /// <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));
    }
Пример #14
0
        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);
        }
Пример #15
0
    /// <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));
    }
Пример #17
0
    /// <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);
        }
Пример #21
0
        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);
        }
Пример #22
0
        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);
        }
Пример #23
0
    /// <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));
    }
Пример #24
0
    /// <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);
    }
Пример #25
0
        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);
        }
Пример #26
0
        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);
        }
Пример #27
0
        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);
        }