public async Task GivenNewSearchParamCreatedBeforeResourcesToBeIndexed_WhenReindexJobCompleted_ThenResourcesAreIndexedAndParamIsSearchable() { const string searchParamName = "foo"; const string searchParamCode = "fooCode"; SearchParameter searchParam = await CreateSearchParam(searchParamName, searchParamCode); const string sampleName1 = "searchIndicesPatient1"; const string sampleName2 = "searchIndicesPatient2"; // Set up the values that the search index extraction should return on resource creation MockSearchIndexExtraction(sampleName1, sampleName2, searchParam); UpsertOutcome sample1 = await CreatePatientResource(sampleName1); UpsertOutcome sample2 = await CreatePatientResource(sampleName2); // Create the query <fhirserver>/Patient?foo=searchIndicesPatient1 var queryParams = new List <Tuple <string, string> >() { new Tuple <string, string>(searchParamCode, sampleName1) }; SearchResult searchResults = await _searchService.Value.SearchAsync("Patient", queryParams, CancellationToken.None); // Confirm that the search parameter "foo" is marked as unsupported Assert.Equal(searchParamCode, searchResults.UnsupportedSearchParameters.FirstOrDefault()?.Item1); // When search parameters aren't recognized, they are ignored // Confirm that "foo" is dropped from the query string and all patients are returned Assert.Equal(2, searchResults.Results.Count()); CreateReindexResponse response = await SetUpForReindexing(); var cancellationTokenSource = new CancellationTokenSource(); try { await PerformReindexingOperation(response, OperationStatus.Completed, cancellationTokenSource); // Rerun the same search as above searchResults = await _searchService.Value.SearchAsync("Patient", queryParams, CancellationToken.None); // This time, foo should not be dropped from the query string Assert.Single(searchResults.Results); // The foo search parameter can be used to filter for the first test patient ResourceWrapper patient = searchResults.Results.FirstOrDefault().Resource; Assert.Contains(sampleName1, patient.RawResource.Data); } finally { cancellationTokenSource.Cancel(); _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement()); await _testHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None); await _fixture.DataStore.HardDeleteAsync(sample1.Wrapper.ToResourceKey(), CancellationToken.None); await _fixture.DataStore.HardDeleteAsync(sample2.Wrapper.ToResourceKey(), CancellationToken.None); } }
public async Task GivenAnUpdatedResource_WhenUpdatingSearchParameterIndexAsync_ThenResourceMetadataIsUnchanged() { ResourceElement patientResource = CreatePatientResourceElement("Patient", Guid.NewGuid().ToString()); SaveOutcome upsertResult = await Mediator.UpsertResourceAsync(patientResource); SearchParameter searchParam = null; const string searchParamName = "newSearchParam"; try { searchParam = await CreatePatientSearchParam(searchParamName, SearchParamType.String, "Patient.name"); ISearchValue searchValue = new StringSearchValue(searchParamName); (ResourceWrapper original, ResourceWrapper updated) = await CreateUpdatedWrapperFromExistingPatient(upsertResult, searchParam, searchValue); await _dataStore.UpdateSearchParameterIndicesAsync(updated, WeakETag.FromVersionId(original.Version), CancellationToken.None); // Get the reindexed resource from the database var resourceKey1 = new ResourceKey(upsertResult.RawResourceElement.InstanceType, upsertResult.RawResourceElement.Id, upsertResult.RawResourceElement.VersionId); ResourceWrapper reindexed = await _dataStore.GetAsync(resourceKey1, CancellationToken.None); VerifyReindexedResource(original, reindexed); } finally { if (searchParam != null) { _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement()); await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None); } } }
public async Task GivenNewSearchParamCreatedBeforeResourcesToBeIndexed_WhenReindexJobCompleted_ThenResourcesAreIndexedAndParamIsSearchable() { var randomName = Guid.NewGuid().ToString().ComputeHash().Substring(0, 14).ToLower(); string searchParamName = randomName; string searchParamCode = randomName + "Code"; SearchParameter searchParam = await CreateSearchParam(searchParamName, SearchParamType.String, ResourceType.Patient, "Patient.name", searchParamCode); string sampleName1 = randomName + "searchIndicesPatient1"; string sampleName2 = randomName + "searchIndicesPatient2"; string sampleId1 = Guid.NewGuid().ToString(); string sampleId2 = Guid.NewGuid().ToString(); // Set up the values that the search index extraction should return during reindexing var searchValues = new List <(string, ISearchValue)> { (sampleId1, new StringSearchValue(sampleName1)), (sampleId2, new StringSearchValue(sampleName2)) }; MockSearchIndexExtraction(searchValues, searchParam); UpsertOutcome sample1 = await CreatePatientResource(sampleName1, sampleId1); UpsertOutcome sample2 = await CreatePatientResource(sampleName2, sampleId2); // Create the query <fhirserver>/Patient?foo=searchIndicesPatient1 var queryParams = new List <Tuple <string, string> > { new(searchParamCode, sampleName1) }; SearchResult searchResults = await _searchService.Value.SearchAsync("Patient", queryParams, CancellationToken.None); // Confirm that the search parameter "foo" is marked as unsupported Assert.Equal(searchParamCode, searchResults.UnsupportedSearchParameters.FirstOrDefault()?.Item1); // When search parameters aren't recognized, they are ignored // Confirm that "foo" is dropped from the query string and all patients are returned Assert.Equal(2, searchResults.Results.Count()); CreateReindexResponse response = await SetUpForReindexing(); var cancellationTokenSource = new CancellationTokenSource(); try { await PerformReindexingOperation(response, OperationStatus.Completed, cancellationTokenSource); // Rerun the same search as above searchResults = await _searchService.Value.SearchAsync("Patient", queryParams, CancellationToken.None); // This time, foo should not be dropped from the query string Assert.Single(searchResults.Results); // The foo search parameter can be used to filter for the first test patient ResourceWrapper patient = searchResults.Results.FirstOrDefault().Resource; Assert.Contains(sampleName1, patient.RawResource.Data); // Confirm that the reindexing operation did not create a new version of the resource Assert.Equal("1", searchResults.Results.FirstOrDefault().Resource.Version); } finally { cancellationTokenSource.Cancel(); _searchParameterDefinitionManager.DeleteSearchParameter(searchParam.ToTypedElement()); await _testHelper.DeleteSearchParameterStatusAsync(searchParam.Url, CancellationToken.None); await _fixture.DataStore.HardDeleteAsync(sample1.Wrapper.ToResourceKey(), false, CancellationToken.None); await _fixture.DataStore.HardDeleteAsync(sample2.Wrapper.ToResourceKey(), false, CancellationToken.None); } }