public void GivenAChainedParameterPointingToMultipleResourceTypesAndWithResourceTypeSpecified_WhenParsed_ThenOnlyExpressionForTheSpecifiedResourceTypeShouldBeCreated()
        {
            ResourceType sourceResourceType = ResourceType.Patient;

            // The reference will support both Organization and Practitioner,
            // but we will limit the search to Organization only in the key below.
            ResourceType[] targetResourceTypes = new[] { ResourceType.Organization, ResourceType.Practitioner };

            string param1 = "ref";
            string param2 = "param";

            string key   = $"{param1}:Organization.{param2}";
            string value = "Seattle";

            // Setup the search parameters.
            SearchParameterInfo referenceSearchParameter = SetupReferenceSearchParameter(sourceResourceType, param1, targetResourceTypes);

            Expression[] expectedExpressions = targetResourceTypes.Select(targetResourceType =>
            {
                SearchParameterInfo searchParameter = SetupSearchParameter(targetResourceType, param2);

                return(SetupExpression(searchParameter, value));
            })
                                               .ToArray();

            // Parse the expression.
            Expression expression = _expressionParser.Parse(sourceResourceType.ToString(), key, value);

            ValidateChainedExpression(
                expression,
                sourceResourceType,
                referenceSearchParameter,
                ResourceType.Organization.ToString(),
                actualSearchExpression => Assert.Equal(expectedExpressions[0], actualSearchExpression));
        }
        public void GivenAChainedParameterPointingToASingleResourceType_WhenParsed_ThenCorrectExpressionShouldBeCreated()
        {
            ResourceType sourceResourceType = ResourceType.Patient;
            ResourceType targetResourceType = ResourceType.Organization;

            string param1 = "ref";
            string param2 = "param";

            string key   = $"{param1}.{param2}";
            string value = "Seattle";

            // Setup the search parameters.
            SearchParameterInfo referenceSearchParameter = SetupReferenceSearchParameter(
                sourceResourceType,
                param1,
                targetResourceType);

            SearchParameterInfo searchParameter = SetupSearchParameter(targetResourceType, param2);

            Expression expectedExpression = SetupExpression(searchParameter, value);

            // Parse the expression.
            Expression expression = _expressionParser.Parse(sourceResourceType.ToString(), key, value);

            ValidateChainedExpression(
                expression,
                sourceResourceType,
                referenceSearchParameter,
                targetResourceType.ToString(),
                actualSearchExpression => Assert.Equal(expectedExpression, actualSearchExpression));
        }
        private Expression SetupExpression(SearchParameterInfo searchParameter, string value)
        {
            Expression expectedExpression = Substitute.For <Expression>();

            _searchParameterExpressionParser.Parse(searchParameter, null, value).Returns(expectedExpression);

            return(expectedExpression);
        }
        public void GivenAModifier_WhenParsed_ThenExceptionShouldBeThrown()
        {
            ResourceType resourceType = ResourceType.Patient;

            string param1   = "ref";
            string modifier = "missing";

            // Practitioner is a valid resource type but is not supported by the search parameter.
            string key   = $"{param1}:{modifier}";
            string value = "Seattle";

            SearchParameterInfo searchParameter = SetupSearchParameter(resourceType, param1);

            Expression expression = Substitute.For <Expression>();

            _searchParameterExpressionParser.Parse(searchParameter, SearchParameter.SearchModifierCode.Missing, value).Returns(expression);

            // Parse the expression.
            Expression actualExpression = _expressionParser.Parse(resourceType.ToString(), key, value);

            // The mock requires the modifier to match so if we get the same expression instance
            // then it means we got the modifier correctly.
            Assert.Equal(expression, actualExpression);
        }
        public void GivenANestedChainedParameter_WhenParsed_ThenCorrectExpressionShouldBeCreated()
        {
            ResourceType sourceResourceType       = ResourceType.Patient;
            ResourceType firstTargetResourceType  = ResourceType.Organization;
            ResourceType secondTargetResourceType = ResourceType.Practitioner;

            string param1 = "ref1";
            string param2 = "ref2";
            string param3 = "param";

            string key   = $"{param1}.{param2}.{param3}";
            string value = "Microsoft";

            // Setup the search parameters.
            SearchParameterInfo referenceSearchParameter1 = SetupReferenceSearchParameter(sourceResourceType, param1, firstTargetResourceType);
            SearchParameterInfo referenceSearchParameter2 = SetupReferenceSearchParameter(firstTargetResourceType, param2, secondTargetResourceType);

            SearchParameterInfo searchParameter = SetupSearchParameter(secondTargetResourceType, param3);

            Expression expectedExpression = SetupExpression(searchParameter, value);

            // Parse the expression.
            Expression expression = _expressionParser.Parse(sourceResourceType.ToString(), key, value);

            ValidateChainedExpression(
                expression,
                sourceResourceType,
                referenceSearchParameter1,
                firstTargetResourceType.ToString(),
                nestedExpression => ValidateChainedExpression(
                    nestedExpression,
                    firstTargetResourceType,
                    referenceSearchParameter2,
                    secondTargetResourceType.ToString(),
                    actualSearchExpression => Assert.Equal(expectedExpression, actualSearchExpression)));
        }
        public void GivenAChainedParameterPointingToMultipleResourceTypesAndSearchParamIsNotSupportedByAllTargetResourceTypes_WhenParsed_ThenOnlyExpressionsForResourceTypeThatSupportsSearchParamShouldBeCreated()
        {
            ResourceType sourceResourceType = ResourceType.Patient;

            // The reference will support both Organization and Practitioner,
            // but the search value will only be supported by Practitioner.
            ResourceType[] targetResourceTypes = new[] { ResourceType.Organization, ResourceType.Practitioner };

            string param1 = "ref";
            string param2 = "param";

            string key   = $"{param1}.{param2}";
            string value = "Lewis";

            // Setup the search parameters.
            SearchParameterInfo referenceSearchParameter = SetupReferenceSearchParameter(sourceResourceType, param1, targetResourceTypes);

            // Setup the Organization to not support this search param.
            _searchParameterDefinitionManager.GetSearchParameter(ResourceType.Organization.ToString(), param2)
            .Returns(x => throw new SearchParameterNotSupportedException(x.ArgAt <string>(0), x.ArgAt <string>(1)));

            // Setup the Practitioner to support this search param.
            SearchParameterInfo searchParameter = SetupSearchParameter(ResourceType.Practitioner, param2);

            Expression expectedExpression = SetupExpression(searchParameter, value);

            // Parse the expression.
            Expression expression = _expressionParser.Parse(sourceResourceType.ToString(), key, value);

            ValidateChainedExpression(
                expression,
                sourceResourceType,
                referenceSearchParameter,
                ResourceType.Practitioner.ToString(),
                actualSearchExpression => Assert.Equal(expectedExpression, actualSearchExpression));
        }