public async Task GivenUpdatedResourcesWithWrongWeakETag_WhenBulkUpdatingSearchParameterIndicesAsync_ThenExceptionIsThrown() { ResourceElement patientResource1 = CreatePatientResourceElement("Patient1", Guid.NewGuid().ToString()); SaveOutcome upsertResult1 = await Mediator.UpsertResourceAsync(patientResource1); ResourceElement patientResource2 = CreatePatientResourceElement("Patient2", Guid.NewGuid().ToString()); SaveOutcome upsertResult2 = await Mediator.UpsertResourceAsync(patientResource2); SearchParameter searchParam1 = null; const string searchParamName1 = "newSearchParam1"; SearchParameter searchParam2 = null; const string searchParamName2 = "newSearchParam2"; try { searchParam1 = await CreatePatientSearchParam(searchParamName1, SearchParamType.String, "Patient.name"); ISearchValue searchValue1 = new StringSearchValue(searchParamName1); (ResourceWrapper original1, ResourceWrapper updated1) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam1, searchValue1); (ResourceWrapper original2, ResourceWrapper updated2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam1, searchValue1); await _dataStore.UpsertAsync(updated1, WeakETag.FromVersionId(original1.Version), allowCreate : false, keepHistory : false, CancellationToken.None); await _dataStore.UpsertAsync(updated2, WeakETag.FromVersionId(original2.Version), allowCreate : false, keepHistory : false, CancellationToken.None); // Let's update the resources again with new information searchParam2 = await CreatePatientSearchParam(searchParamName2, SearchParamType.Token, "Patient.gender"); ISearchValue searchValue2 = new TokenSearchValue("system", "code", "text"); // Create the updated wrappers using the original resource and its outdated version (_, ResourceWrapper updated1WithSearchParam2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult1, searchParam2, searchValue2, original1); (_, ResourceWrapper updated2WithSearchParam2) = await CreateUpdatedWrapperFromExistingPatient(upsertResult2, searchParam2, searchValue2, original2); var resources = new List <ResourceWrapper> { updated1WithSearchParam2, updated2WithSearchParam2 }; // Attempt to reindex resources with the old versions await Assert.ThrowsAsync <PreconditionFailedException>(() => _dataStore.BulkUpdateSearchParameterIndicesAsync(resources, CancellationToken.None)); } finally { if (searchParam1 != null) { _searchParameterDefinitionManager.DeleteSearchParameter(searchParam1.ToTypedElement()); await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam1.Url, CancellationToken.None); } if (searchParam2 != null) { _searchParameterDefinitionManager.DeleteSearchParameter(searchParam2.ToTypedElement()); await _fixture.TestHelper.DeleteSearchParameterStatusAsync(searchParam2.Url, CancellationToken.None); } } }
protected override IEnumerable <ISearchValue> ConvertTo(CodeableConcept value) { // Based on spec: http://hl7.org/fhir/STU3/search.html#token, // CodeableConcept.text is searchable. if (!string.IsNullOrWhiteSpace(value.Text)) { yield return(new TokenSearchValue(null, null, value.Text)); } if (value.Coding?.Count == 0) { yield break; } foreach (Coding coding in value.Coding) { if (coding == null) { continue; } TokenSearchValue searchValue = coding.ToTokenSearchValue(); if (searchValue != null) { yield return(searchValue); } } }
public void GivenASearchValue_WhenToStringIsCalled_ThenCorrectStringShouldBeReturned(string system, string code, string expected) { _builder.System = system; _builder.Code = code; TokenSearchValue value = _builder.ToTokenSearchValue(); Assert.Equal(expected, value.ToString()); }
public void GivenAValidString_WhenParsed_ThenCorrectSearchValueShouldBeReturned(string s, string expectedSystem, string expectedCode) { TokenSearchValue value = TokenSearchValue.Parse(s); Assert.NotNull(value); Assert.Equal(expectedSystem, value.System); Assert.Equal(expectedCode, value.Code); Assert.Null(value.Text); }
protected override IEnumerable <ISearchValue> ConvertTo(Coding value) { TokenSearchValue searchValue = value.ToTokenSearchValue(); if (searchValue != null) { yield return(searchValue); } }
void ISearchValueVisitor.Visit(TokenSearchValue token) { EnsureArg.IsNotNull(token, nameof(token)); EnsureOnlyEqualComparatorIsSupported(); if (_modifier == null) { _outputExpression = BuildEqualityExpression(); } else if (_modifier == SearchModifierCode.Not) { _outputExpression = Expression.Not(BuildEqualityExpression()); } else if (_modifier == SearchModifierCode.Above || _modifier == SearchModifierCode.Below || _modifier == SearchModifierCode.In || _modifier == SearchModifierCode.NotIn) { // These modifiers are not supported yet but will be supported eventually. ThrowModifierNotSupported(); } else { ThrowModifierNotSupported(); } Expression BuildEqualityExpression() { // Based on spec http://hl7.org/fhir/search.html#token, // we need to make sure to test if system is missing or not based on how it is supplied. if (token.System == null) { // If the system is not supplied, then the token code is matched irrespective of the value of system. return(Expression.StringEquals(FieldName.TokenCode, _componentIndex, token.Code, false)); } else if (token.System.Length == 0) { // If the system is empty, then the token is matched if there is no system property. return(Expression.And( Expression.Missing(FieldName.TokenSystem, _componentIndex), Expression.StringEquals(FieldName.TokenCode, _componentIndex, token.Code, false))); } else if (string.IsNullOrWhiteSpace(token.Code)) { // If the code is empty, then the token is matched if system is matched. return(Expression.StringEquals(FieldName.TokenSystem, _componentIndex, token.System, false)); } else { return(Expression.And( Expression.StringEquals(FieldName.TokenSystem, _componentIndex, token.System, false), Expression.StringEquals(FieldName.TokenCode, _componentIndex, token.Code, false))); } } }
public void GivenOneNonEmptyField_WhenInitialized_ThenTokenSearchValueShouldBeCreated(string system, string code, string text) { _builder.System = system; _builder.Code = code; _builder.Text = text; TokenSearchValue value = _builder.ToTokenSearchValue(); Assert.Equal(text, value.Text); }
void ISearchValueVisitor.Visit(TokenSearchValue token) { AddPropertyIfNotNull(SearchValueConstants.SystemName, token.System); AddPropertyIfNotNull(SearchValueConstants.CodeName, token.Code); if (!IsCompositeComponent) { // Since text is case-insensitive search, it will always be normalized. AddPropertyIfNotNull(SearchValueConstants.NormalizedTextName, token.Text?.ToUpperInvariant()); } }
public void GivenATokenSearchValueWithNullText_WhenGenerated_ThenCorrectJObjectShouldBeCreated() { const string system = "system"; const string code = "code"; var value = new TokenSearchValue(system, code, null); var expectedValues = new[] { CreateTuple(SystemName, system), CreateTuple(CodeName, code), }; TestAndValidateOutput( "token", value, expectedValues); }
public void GivenATokenSearchValueWithNullCode_WhenGenerated_ThenCorrectJObjectShouldBeCreated() { const string system = "system"; const string text = "TEXT"; var value = new TokenSearchValue(system, null, text); var expectedValues = new[] { CreateTuple(SystemName, system), CreateTuple(TextName, text), }; TestAndValidateOutput( "token", value, expectedValues); }
public void GivenATokenSearchValueWithNullSystem_WhenGenerated_ThenCorrectJObjectShouldBeCreated() { const string code = "code"; const string text = "TEXT"; var value = new TokenSearchValue(null, code, text); var expectedValues = new[] { CreateTuple(CodeName, code), CreateTuple(TextName, text), }; TestAndValidateOutput( "token", value, expectedValues); }
public void GivenATokenSearchValue_WhenGenerated_ThenCorrectJObjectShouldBeCreated() { const string system = "system"; const string code = "code"; const string text = "MixedCaseText"; var value = new TokenSearchValue(system, code, text); var expectedValues = new[] { CreateTuple(SystemName, system), CreateTuple(CodeName, code), CreateTuple(TextName, text.ToUpperInvariant()), }; TestAndValidateOutput( "token", value, expectedValues); }
protected override IEnumerable <ISearchValue> ConvertTo(CodeableConcept value) { // Based on spec: http://hl7.org/fhir/STU3/search.html#token, // CodeableConcept.text is searchable, but we will only create a dedicated entry for it // if it is different from the display text of one of its codings bool conceptTextNeedsToBeAdded = !string.IsNullOrWhiteSpace(value.Text); if (value.Coding != null) { foreach (Coding coding in value.Coding) { if (coding == null) { continue; } TokenSearchValue searchValue = coding.ToTokenSearchValue(); if (searchValue != null) { if (conceptTextNeedsToBeAdded) { conceptTextNeedsToBeAdded = !value.Text.Equals(searchValue.Text, StringComparison.OrdinalIgnoreCase); } yield return(searchValue); } } } if (conceptTextNeedsToBeAdded) { yield return(new TokenSearchValue(null, null, value.Text)); } }
public void GivenAnInvalidString_WhenParsing_ThenExceptionShouldBeThrown(string s) { Assert.Throws <ArgumentException>(ParamNameS, () => TokenSearchValue.Parse(s)); }
public void GivenANullString_WhenParsing_ThenExceptionShouldBeThrown() { Assert.Throws <ArgumentNullException>(ParamNameS, () => TokenSearchValue.Parse(null)); }
public void GivenAStringContainingMoreThanOneTokenSeparator_WhenParsing_ThenExceptionShouldBeThrown() { Assert.Throws <FormatException>(() => TokenSearchValue.Parse(@"s12\|s12|c12\|c12|c12")); }
public void Visit(TokenSearchValue token) { }
public void GivenASearchValue_WhenIsValidCompositeComponentIsCalled_ThenCorrectValueShouldBeReturned(string system, string code, bool expected) { var value = new TokenSearchValue(system, code, "test"); Assert.Equal(expected, value.IsValidAsCompositeComponent); }