forked from hapifhir/org.hl7.fhir.core
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request hapifhir#1578 from hapifhir/do-20240319-tx-test-reuse
Refactor terminology service tests for reuse outside core
- Loading branch information
Showing
4 changed files
with
314 additions
and
229 deletions.
There are no files selected for viewing
215 changes: 215 additions & 0 deletions
215
...l7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxServiceTestHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
package org.hl7.fhir.validation.special; | ||
|
||
import com.google.gson.JsonSyntaxException; | ||
import org.hl7.fhir.r5.formats.JsonParser; | ||
import org.hl7.fhir.r5.context.IWorkerContext; | ||
import org.hl7.fhir.r5.formats.IParser; | ||
import org.hl7.fhir.r5.model.*; | ||
import org.hl7.fhir.r5.terminologies.utilities.TerminologyServiceErrorClass; | ||
import org.hl7.fhir.r5.terminologies.utilities.ValidationResult; | ||
import org.hl7.fhir.r5.test.utils.CompareUtilities; | ||
import org.hl7.fhir.utilities.FhirPublication; | ||
import org.hl7.fhir.utilities.TextFile; | ||
import org.hl7.fhir.utilities.Utilities; | ||
import org.hl7.fhir.utilities.i18n.I18nConstants; | ||
import org.hl7.fhir.utilities.json.model.JsonObject; | ||
import org.hl7.fhir.utilities.validation.ValidationOptions; | ||
|
||
import java.io.File; | ||
import java.io.FileNotFoundException; | ||
import java.io.IOException; | ||
|
||
public class TxServiceTestHelper { | ||
|
||
|
||
public static String getDiffForValidation(String id, IWorkerContext context, String name, Resource requestParameters, String expectedResponse, String lang, String fp, JsonObject externals, boolean isCodeSystem) throws JsonSyntaxException, FileNotFoundException, IOException { | ||
org.hl7.fhir.r5.model.Parameters p = (org.hl7.fhir.r5.model.Parameters) requestParameters; | ||
ValueSet valueSet = null; | ||
String valueSetUrl = null; | ||
if (!isCodeSystem) { | ||
if (p.hasParameter("valueSetVersion")) { | ||
valueSetUrl = p.getParameterValue("url").primitiveValue()+"|"+p.getParameterValue("valueSetVersion").primitiveValue(); | ||
valueSet = context.fetchResource(ValueSet.class, p.getParameterValue("url").primitiveValue(), p.getParameterValue("valueSetVersion").primitiveValue()); | ||
} else { | ||
valueSetUrl = p.getParameterValue("url").primitiveValue(); | ||
valueSet = context.fetchResource(ValueSet.class, p.getParameterValue("url").primitiveValue()); | ||
} | ||
} | ||
ValidationResult validationResult = null; | ||
String code = null; | ||
String system = null; | ||
String version = null; | ||
String display = null; | ||
CodeableConcept codeableConcept = null; | ||
org.hl7.fhir.r5.model.Parameters parameters = null; | ||
OperationOutcome operationOutcome = null; | ||
|
||
if (valueSet == null && valueSetUrl != null) { | ||
String msg = context.formatMessage(I18nConstants.UNABLE_TO_RESOLVE_VALUE_SET_, valueSetUrl); | ||
operationOutcome = new OperationOutcome(); | ||
CodeableConcept codeableConceptWhenNullValueSet = operationOutcome.addIssue().setSeverity(OperationOutcome.IssueSeverity.ERROR).setCode(OperationOutcome.IssueType.NOTFOUND).getDetails(); | ||
codeableConceptWhenNullValueSet.addCoding("http://hl7.org/fhir/tools/CodeSystem/tx-issue-type", "not-found", null); | ||
codeableConceptWhenNullValueSet.setText(msg); | ||
} else { | ||
ValidationOptions options = new ValidationOptions(FhirPublication.R5); | ||
if (p.hasParameter("displayLanguage")) { | ||
options = options.withLanguage(p.getParameterString("displayLanguage")); | ||
} else if (lang != null ) { | ||
options = options.withLanguage(lang); | ||
} | ||
if (p.hasParameter("valueset-membership-only") && "true".equals(p.getParameterString("valueset-membership-only"))) { | ||
options = options.withCheckValueSetOnly(); | ||
} | ||
if (p.hasParameter("lenient-display-validation") && "true".equals(p.getParameterString("lenient-display-validation"))) { | ||
options = options.setDisplayWarningMode(true); | ||
} | ||
if (p.hasParameter("activeOnly") && "true".equals(p.getParameterString("activeOnly"))) { | ||
options = options.setActiveOnly(true); | ||
} | ||
context.getExpansionParameters().clearParameters("includeAlternateCodes"); | ||
for (Parameters.ParametersParameterComponent pp : p.getParameter()) { | ||
if ("includeAlternateCodes".equals(pp.getName())) { | ||
context.getExpansionParameters().addParameter(pp.copy()); | ||
} | ||
} | ||
if (p.hasParameter("code")) { | ||
code = p.getParameterString("code"); | ||
system = p.getParameterString(isCodeSystem ? "url" : "system"); | ||
version = p.getParameterString(isCodeSystem ? "version" : "systemVersion"); | ||
display = p.getParameterString("display"); | ||
validationResult = context.validateCode(options.withGuessSystem(), | ||
p.getParameterString(isCodeSystem ? "url" : "system"), p.getParameterString(isCodeSystem ? "version" : "systemVersion"), | ||
p.getParameterString("code"), p.getParameterString("display"), valueSet); | ||
} else if (p.hasParameter("coding")) { | ||
Coding coding = (Coding) p.getParameterValue("coding"); | ||
code = coding.getCode(); | ||
system = coding.getSystem(); | ||
version = coding.getVersion(); | ||
display = coding.getDisplay(); | ||
validationResult = context.validateCode(options, coding, valueSet); | ||
} else if (p.hasParameter("codeableConcept")) { | ||
codeableConcept = (CodeableConcept) p.getParameterValue("codeableConcept"); | ||
validationResult = context.validateCode(options, codeableConcept, valueSet); | ||
} else { | ||
throw new Error("validate not done yet for this steup"); | ||
} | ||
} | ||
if (operationOutcome == null && validationResult != null && validationResult.getSeverity() == org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity.FATAL) { | ||
operationOutcome = new OperationOutcome(); | ||
operationOutcome.getIssue().addAll(validationResult.getIssues()); | ||
} | ||
if (operationOutcome != null) { | ||
TxTesterSorters.sortOperationOutcome(operationOutcome); | ||
TxTesterScrubbers.scrubOO(operationOutcome, false); | ||
|
||
String actualResponse = new JsonParser().setOutputStyle(IParser.OutputStyle.PRETTY).composeString(operationOutcome); | ||
|
||
|
||
|
||
writeDiffToFileSystem( name, expectedResponse, actualResponse); | ||
|
||
String diff = CompareUtilities.checkJsonSrcIsSame(id, expectedResponse, actualResponse, externals); | ||
if (diff != null) { | ||
Utilities.createDirectory(Utilities.getDirectoryForFile(fp)); | ||
TextFile.stringToFile(actualResponse, fp); | ||
System.out.println("Test "+name+"failed: "+diff); | ||
} | ||
return diff; | ||
} else { | ||
if (parameters == null) { | ||
parameters = new org.hl7.fhir.r5.model.Parameters(); | ||
if (validationResult.getSystem() != null) { | ||
parameters.addParameter("system", new UriType(validationResult.getSystem())); | ||
} else if (system != null) { | ||
parameters.addParameter("system", new UriType(system)); | ||
} | ||
if (validationResult.getCode() != null) { | ||
if (code != null && !code.equals(validationResult.getCode())) { | ||
parameters.addParameter("code", new CodeType(code)); | ||
parameters.addParameter("normalized-code", new CodeType(validationResult.getCode())); | ||
} else { | ||
parameters.addParameter("code", new CodeType(validationResult.getCode())); | ||
} | ||
} else if (code != null) { | ||
parameters.addParameter("code", new CodeType(code)); | ||
} | ||
if (validationResult.getSeverity() == org.hl7.fhir.utilities.validation.ValidationMessage.IssueSeverity.ERROR) { | ||
parameters.addParameter("result", false); | ||
} else { | ||
parameters.addParameter("result", true); | ||
} | ||
if (validationResult.getMessage() != null) { | ||
parameters.addParameter("message", validationResult.getMessage()); | ||
} | ||
if (validationResult.getVersion() != null) { | ||
parameters.addParameter("version", validationResult.getVersion()); | ||
} else if (version != null) { | ||
parameters.addParameter("version", new StringType(version)); | ||
} | ||
if (validationResult.getDisplay() != null) { | ||
parameters.addParameter("display", validationResult.getDisplay()); | ||
} else if (display != null) { | ||
parameters.addParameter("display", new StringType(display)); | ||
} | ||
// if (vm.getCodeableConcept() != null) { | ||
// res.addParameter("codeableConcept", vm.getCodeableConcept()); | ||
// } else | ||
if (codeableConcept != null) { | ||
parameters.addParameter("codeableConcept", codeableConcept); | ||
} | ||
if (validationResult.isInactive()) { | ||
parameters.addParameter("inactive", true); | ||
} | ||
if (validationResult.getStatus() != null) { | ||
parameters.addParameter("status", validationResult.getStatus()); | ||
} | ||
if (validationResult.getUnknownSystems() != null) { | ||
for (String s : validationResult.getUnknownSystems()) { | ||
parameters.addParameter(validationResult.getErrorClass() == TerminologyServiceErrorClass.CODESYSTEM_UNSUPPORTED ? "x-caused-by-unknown-system" : "x-unknown-system", new CanonicalType(s)); | ||
} | ||
} | ||
if (validationResult.getIssues().size() > 0) { | ||
operationOutcome = new OperationOutcome(); | ||
operationOutcome.getIssue().addAll(validationResult.getIssues()); | ||
parameters.addParameter().setName("issues").setResource(operationOutcome); | ||
} | ||
} | ||
|
||
TxTesterSorters.sortParameters(parameters); | ||
TxTesterScrubbers.scrubParams(parameters); | ||
|
||
String actualResponse = new JsonParser().setOutputStyle(IParser.OutputStyle.PRETTY).composeString(parameters); | ||
|
||
writeDiffToFileSystem(name, expectedResponse, actualResponse); | ||
|
||
String diff = CompareUtilities.checkJsonSrcIsSame(id, expectedResponse, actualResponse, externals); | ||
if (diff != null) { | ||
Utilities.createDirectory(Utilities.getDirectoryForFile(fp)); | ||
TextFile.stringToFile(actualResponse, fp); | ||
System.out.println("Test "+name+"failed: "+diff); | ||
} | ||
return diff; | ||
} | ||
} | ||
|
||
public static void writeDiffToFileSystem(String testName, String expected, String actual) throws IOException { | ||
String rootDirectory = System.getenv("TX_SERVICE_TEST_DIFF_TARGET"); | ||
if (rootDirectory == null || rootDirectory.isEmpty()) { | ||
return; | ||
} | ||
String fullExpected = rootDirectory + "/expected/"; | ||
String fullActual = rootDirectory + "/actual/"; | ||
File expectedDirectory = new File(fullExpected); | ||
if (!expectedDirectory.exists()) { | ||
expectedDirectory.mkdirs(); | ||
} | ||
|
||
File actualDirectory = new File(fullActual); | ||
if (!actualDirectory.exists()) { | ||
actualDirectory.mkdirs(); | ||
} | ||
TextFile.stringToFile(expected, fullExpected + testName + ".json"); | ||
TextFile.stringToFile(actual, fullActual + testName + ".json"); | ||
|
||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxTestData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package org.hl7.fhir.validation.special; | ||
|
||
import lombok.Getter; | ||
import org.hl7.fhir.r5.test.utils.TestingUtilities; | ||
import org.hl7.fhir.utilities.json.model.JsonObject; | ||
|
||
import java.io.IOException; | ||
import java.util.*; | ||
|
||
public class TxTestData { | ||
|
||
@Getter | ||
private final JsonObject manifest; | ||
|
||
@Getter | ||
private final JsonObject externals; | ||
|
||
@Getter | ||
private final List<Object[]> testData; | ||
|
||
private TxTestData(List<Object[]> testData, JsonObject manifest, JsonObject externals) throws IOException { | ||
this.testData = testData; | ||
this.manifest = manifest; | ||
this.externals = externals; | ||
} | ||
|
||
public static TxTestData loadTestDataFromDefaultClassPath() throws IOException { | ||
String contents = TestingUtilities.loadTestResource("tx", "test-cases.json"); | ||
String externalSource = TestingUtilities.loadTestResource("tx", "messages-tx.fhir.org.json"); | ||
JsonObject externals = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(externalSource); | ||
|
||
Map<String, TxTestSetup> examples = new HashMap<String, TxTestSetup>(); | ||
JsonObject manifest = org.hl7.fhir.utilities.json.parser.JsonParser.parseObject(contents); | ||
for (JsonObject suite : manifest.getJsonObjects("suites")) { | ||
if (!"tx.fhir.org".equals(suite.asString("mode"))) { | ||
String sn = suite.asString("name"); | ||
for (JsonObject test : suite.getJsonObjects("tests")) { | ||
String tn = test.asString("name"); | ||
examples.put(sn + "." + tn, new TxTestSetup(suite, test)); | ||
} | ||
} | ||
} | ||
|
||
List<String> names = new ArrayList<String>(examples.size()); | ||
names.addAll(examples.keySet()); | ||
Collections.sort(names); | ||
|
||
List<Object[]> testData = new ArrayList<Object[]>(examples.size()); | ||
for (String id : names) { | ||
testData.add(new Object[]{id, examples.get(id)}); | ||
} | ||
|
||
return new TxTestData(testData, manifest, externals); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/TxTestSetup.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.hl7.fhir.validation.special; | ||
|
||
import lombok.Getter; | ||
import org.hl7.fhir.utilities.json.model.JsonObject; | ||
|
||
public class TxTestSetup { | ||
public TxTestSetup(JsonObject suite, JsonObject test) { | ||
this.suite = suite; | ||
this.test = test; | ||
} | ||
|
||
@Getter | ||
private JsonObject suite; | ||
@Getter | ||
private JsonObject test; | ||
|
||
} |
Oops, something went wrong.