Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom FHIR-resources in SearchOptionsFactory #3882

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,70 @@
Assert.Empty(options.UnsupportedSearchParams);
}

[Fact]
public void GivenSearchParamFromCustomFhirResource_WhenCustomTypeIsUnknown_ThenResourceNotSupportedExceptionShouldBeThrown()
{
const string resourceType = "Formulary";
const string paramName1 = KnownQueryParameterNames.Text;
const string value1 = "123";

var oldModelInfoProvider = ModelInfoProvider.Instance;
try
{
IModelInfoProvider modelInfoProvider = Substitute.For<IModelInfoProvider>();
modelInfoProvider.IsKnownResource(resourceType).Returns(false);
ModelInfoProvider.SetProvider(modelInfoProvider);

var queryParameters = new[]
{
Tuple.Create(paramName1, value1),
};

Assert.Throws<ResourceNotSupportedException>(() =>
{
SearchOptions options = CreateSearchOptions(
resourceType: resourceType,
queryParameters: queryParameters);
Fixed Show fixed Hide fixed
});
}
finally
{
ModelInfoProvider.SetProvider(oldModelInfoProvider);
}
}

[Fact]
public void GivenSearchParamFromCustomFhirResource_WhenCustomTypeIsKnown_ThenCorrectExpressionShouldBeGenerated()
{
const string resourceType = "Formulary";
const string paramName1 = KnownQueryParameterNames.Text;
const string value1 = "123";

var oldModelInfoProvider = ModelInfoProvider.Instance;
try
{
IModelInfoProvider modelInfoProvider = Substitute.For<IModelInfoProvider>();
modelInfoProvider.IsKnownResource(resourceType).Returns(true);
ModelInfoProvider.SetProvider(modelInfoProvider);

var queryParameters = new[]
{
Tuple.Create(paramName1, value1),
};

SearchOptions options = CreateSearchOptions(
resourceType: resourceType,
queryParameters: queryParameters);

Assert.NotNull(options);
ValidateResourceTypeSearchParameterExpression(options.Expression, resourceType);
}
finally
{
ModelInfoProvider.SetProvider(oldModelInfoProvider);
}
}

private SearchOptions CreateSearchOptions(
string resourceType = DefaultResourceType,
IReadOnlyList<Tuple<string, string>> queryParameters = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ public SearchOptions Create(

// If the resource type is not specified, then the common
// search parameters should be used.
ResourceType[] parsedResourceTypes = new[] { ResourceType.DomainResource };
string[] resourceTypesString = new[] { nameof(ResourceType.DomainResource) };

var searchExpressions = new List<Expression>();
if (string.IsNullOrWhiteSpace(resourceType))
Expand All @@ -300,37 +300,26 @@ public SearchOptions Create(
.Where(q => q.Item1 == KnownQueryParameterNames.Type) // <-- Equality comparison to avoid modifiers
.SelectMany(q => q.Item2.SplitByOrSeparator())
.Where(type => ModelInfoProvider.IsKnownResource(type))
.Select(x =>
{
if (!Enum.TryParse(x, out ResourceType parsedType))
{
// Should never get here
throw new ResourceNotSupportedException(x);
}

return parsedType;
})
.Distinct().ToList();

if (resourceTypes.Any())
{
parsedResourceTypes = resourceTypes.ToArray();
resourceTypesString = resourceTypes.ToArray();
}
}
else
{
if (!Enum.TryParse(resourceType, out parsedResourceTypes[0]))
if (!ModelInfoProvider.IsKnownResource(resourceType))
{
throw new ResourceNotSupportedException(resourceType);
}

resourceTypesString = new[] { resourceType };
searchExpressions.Add(Expression.SearchParameter(ResourceTypeSearchParameter, Expression.StringEquals(FieldName.TokenCode, null, resourceType, false)));
}

CheckFineGrainedAccessControl(searchExpressions);

var resourceTypesString = parsedResourceTypes.Select(x => x.ToString()).ToArray();

searchExpressions.AddRange(searchParams.Parameters.Select(
q =>
{
Expand Down
Loading