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

Add helper function to ignore hidden questions #325

Merged
merged 6 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 4 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 @@ -83,6 +83,12 @@ public class QuestionnaireResponseGeneratorCommand implements Runnable {
defaultValue = ".")
private String outputFilePath;

@CommandLine.Option(
names = {"-ih", "--ignore-hidden"},
description = "Ignore hidden questions when generating responses",
defaultValue = "true")
private boolean ignoreHiddenQuestions;

private static final Random random = new Random();
private static final Faker faker = new Faker();

Expand All @@ -99,7 +105,8 @@ public void run() {
fhir_base_url,
apiKey,
aiModel,
maxTokens);
maxTokens,
ignoreHiddenQuestions);
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down Expand Up @@ -127,7 +134,8 @@ public static void generateResponse(
String fhir_base_url,
String apiKey,
String aiModel,
String maxTokens)
String maxTokens,
boolean ignoreHiddenQuestions)
throws IOException {
long start = System.currentTimeMillis();

Expand All @@ -141,7 +149,7 @@ public static void generateResponse(

String questionnaireResponseString =
(Objects.equals(mode, "populate"))
? populateMode(questionnaireData, fhir_base_url, extrasPath)
? populateMode(questionnaireData, fhir_base_url, extrasPath, ignoreHiddenQuestions)
: aiMode(questionnaireData, apiKey, aiModel, maxTokens);

// Write response to file
Expand Down Expand Up @@ -321,9 +329,15 @@ static JSONObject generateAnswer(
}
}

static JSONArray getAnswers(JSONArray questions, JSONArray responses, JSONObject extras) {
static JSONArray getAnswers(
JSONArray questions, JSONArray responses, JSONObject extras, boolean ignoreHiddenQuestions) {
for (int i = 0; i < questions.length(); i++) {
JSONObject current_question = questions.getJSONObject(i);

if (ignoreHiddenQuestions && isHiddenQuestion(current_question)) {
continue;
}

String question_type = current_question.getString("type");
String link_id = current_question.getString("linkId");

Expand All @@ -335,15 +349,38 @@ static JSONArray getAnswers(JSONArray questions, JSONArray responses, JSONObject
if (current_question.has("item")) {
JSONArray group_questions = current_question.getJSONArray("item");
JSONArray group_responses = responses.getJSONObject(i).getJSONArray("item");
getAnswers(group_questions, group_responses, extras);
getAnswers(group_questions, group_responses, extras, ignoreHiddenQuestions);
}
}
responses.getJSONObject(i).put("answer", answer_arr);
}
return responses;
}

static String populateMode(String questionnaireData, String fhir_base_url, String extrasPath)
static boolean isHiddenQuestion(JSONObject question) {
boolean isHidden = false;

if (question.has("extension")) {
JSONArray extensions = question.getJSONArray("extension");
for (int i = 0; i < extensions.length(); i++) {
JSONObject extension = extensions.getJSONObject(i);
if (extension
.getString("url")
.equals("http://hl7.org/fhir/StructureDefinition/questionnaire-hidden")) {
isHidden = extension.optBoolean("valueBoolean", true);
break;
}
}
}

return isHidden;
}

static String populateMode(
String questionnaireData,
String fhir_base_url,
String extrasPath,
boolean ignoreHiddenQuestions)
throws IOException {
JSONObject resource = new JSONObject(questionnaireData);
String questionnaire_id = resource.getString("id");
Expand Down Expand Up @@ -377,7 +414,7 @@ static String populateMode(String questionnaireData, String fhir_base_url, Strin
String populate_endpoint =
String.join("/", fhir_base_url, resourceType, questionnaire_id, "$populate");
List<String> result = HttpClient.postRequest(params.toString(), populate_endpoint, null);

System.out.println("Hidden questions" + ignoreHiddenQuestions);
sharon2719 marked this conversation as resolved.
Show resolved Hide resolved
JSONObject questionnaire_response = new JSONObject(result.get(1));
FctUtils.printError("Debug: response from questionnaireResponse: " + questionnaire_response);

Expand All @@ -387,7 +424,8 @@ static String populateMode(String questionnaireData, String fhir_base_url, Strin
if (questionnaire_response.has("item")) {
JSONArray response = (JSONArray) questionnaire_response.get("item");
JSONArray questions = resource.getJSONArray("item");
JSONArray response_with_answers = getAnswers(questions, response, extras);
JSONArray response_with_answers =
getAnswers(questions, response, extras, ignoreHiddenQuestions);
questionnaire_response.put("item", response_with_answers);
}
return String.valueOf(questionnaire_response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ void validateStructureMap(String inputFilePath, String structureMapFilePath, boo
"http://localhost:8080/fhir",
"",
"",
"");
"",
true);

// Extract Resources using the StructureMap and the generated QuestionnaireResponse
String generatedQuestionnaireResponsePath =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -299,4 +300,232 @@ void testGenerateDefaultAnswer() {
assertNotNull(answer);
assertTrue(answer.isEmpty());
}

@Test
void testIsHiddenQuestion_hiddenExtensionTrue() {
JSONObject question = new JSONObject();
JSONArray extensions = new JSONArray();
JSONObject hiddenExtension = new JSONObject();
hiddenExtension.put("url", "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden");
hiddenExtension.put("valueBoolean", true);
extensions.put(hiddenExtension);
question.put("extension", extensions);

assertTrue(QuestionnaireResponseGeneratorCommand.isHiddenQuestion(question));
}

@Test
void testIsHiddenQuestion_hiddenExtensionFalse() {
JSONObject question = new JSONObject();
JSONArray extensions = new JSONArray();
JSONObject hiddenExtension = new JSONObject();
hiddenExtension.put("url", "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden");
hiddenExtension.put("valueBoolean", false);
extensions.put(hiddenExtension);
question.put("extension", extensions);

assertFalse(QuestionnaireResponseGeneratorCommand.isHiddenQuestion(question));
}

@Test
void testIsHiddenQuestion_noHiddenExtension() {
JSONObject question = new JSONObject();
JSONArray extensions = new JSONArray();
JSONObject otherExtension = new JSONObject();
otherExtension.put("url", "http://example.com/other-extension");
otherExtension.put("valueBoolean", true);
extensions.put(otherExtension);
question.put("extension", extensions);

assertFalse(QuestionnaireResponseGeneratorCommand.isHiddenQuestion(question));
}

@Test
void testIsHiddenQuestion_noExtensions() {
JSONObject question = new JSONObject();
assertFalse(QuestionnaireResponseGeneratorCommand.isHiddenQuestion(question));
}

@Test
void testIsHiddenQuestion_hiddenExtensionNoValueBoolean() {
JSONObject question = new JSONObject();
JSONArray extensions = new JSONArray();
JSONObject hiddenExtension = new JSONObject();
hiddenExtension.put("url", "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden");
extensions.put(hiddenExtension);
question.put("extension", extensions);

assertTrue(QuestionnaireResponseGeneratorCommand.isHiddenQuestion(question));
}

@Test
void testGetAnswers_simpleQuestion() {
JSONArray questions = new JSONArray();
JSONObject question = new JSONObject();
question.put("type", "string");
question.put("linkId", "exampleLinkId");
questions.put(question);

JSONArray responses = new JSONArray();
JSONObject response = new JSONObject();
responses.put(response);

JSONObject extras = new JSONObject();

JSONArray updatedResponses =
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, extras, false);

assertNotNull(updatedResponses);
assertTrue(updatedResponses.getJSONObject(0).has("answer"));
assertTrue(
updatedResponses
.getJSONObject(0)
.getJSONArray("answer")
.getJSONObject(0)
.has("valueString"));
}

@Test
void testGetAnswers_groupQuestion() {
JSONArray questions = new JSONArray();
JSONObject groupQuestion = new JSONObject();
groupQuestion.put("type", "group");
groupQuestion.put("linkId", "group1");
JSONArray nestedQuestions = new JSONArray();
JSONObject nestedQuestion = new JSONObject();
nestedQuestion.put("type", "integer");
nestedQuestion.put("linkId", "nested1");
nestedQuestions.put(nestedQuestion);
groupQuestion.put("item", nestedQuestions);
questions.put(groupQuestion);

JSONArray responses = new JSONArray();
JSONObject groupResponse = new JSONObject();
groupResponse.put("item", new JSONArray().put(new JSONObject()));
responses.put(groupResponse);

JSONObject extras = new JSONObject();

JSONArray updatedResponses =
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, extras, false);

assertNotNull(updatedResponses);
JSONObject nestedResponse =
updatedResponses.getJSONObject(0).getJSONArray("item").getJSONObject(0);
assertTrue(nestedResponse.has("answer"));
assertTrue(nestedResponse.getJSONArray("answer").getJSONObject(0).has("valueInteger"));
}

@Test
void testGetAnswers_ignoreHiddenQuestions() {
JSONArray questions = new JSONArray();
JSONObject hiddenQuestion = new JSONObject();
hiddenQuestion.put("type", "boolean");
hiddenQuestion.put("linkId", "hidden1");
JSONArray extensions = new JSONArray();
JSONObject hiddenExtension = new JSONObject();
hiddenExtension.put("url", "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden");
hiddenExtension.put("valueBoolean", true);
extensions.put(hiddenExtension);
hiddenQuestion.put("extension", extensions);
questions.put(hiddenQuestion);

JSONArray responses = new JSONArray();
responses.put(new JSONObject());

JSONObject extras = new JSONObject();

JSONArray updatedResponses =
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, extras, true);

assertNotNull(updatedResponses);
assertFalse(updatedResponses.getJSONObject(0).has("answer"));
}

@Test
void testGetAnswers_includeHiddenQuestions() {
JSONArray questions = new JSONArray();
JSONObject hiddenQuestion = new JSONObject();
hiddenQuestion.put("type", "boolean");
hiddenQuestion.put("linkId", "hidden1");
JSONArray extensions = new JSONArray();
JSONObject hiddenExtension = new JSONObject();
hiddenExtension.put("url", "http://hl7.org/fhir/StructureDefinition/questionnaire-hidden");
hiddenExtension.put("valueBoolean", true);
extensions.put(hiddenExtension);
hiddenQuestion.put("extension", extensions);
questions.put(hiddenQuestion);

JSONArray responses = new JSONArray();
responses.put(new JSONObject());

JSONObject extras = new JSONObject();

JSONArray updatedResponses =
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, extras, false);

assertNotNull(updatedResponses);
assertTrue(updatedResponses.getJSONObject(0).has("answer"));
assertTrue(
updatedResponses
.getJSONObject(0)
.getJSONArray("answer")
.getJSONObject(0)
.has("valueBoolean"));
}

@Test
void testGetAnswers_noExtras() {
JSONArray questions = new JSONArray();
JSONObject question = new JSONObject();
question.put("type", "decimal");
question.put("linkId", "decimal1");
questions.put(question);

JSONArray responses = new JSONArray();
responses.put(new JSONObject());

JSONArray updatedResponses =
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, null, false);

assertNotNull(updatedResponses);
assertTrue(updatedResponses.getJSONObject(0).has("answer"));
assertTrue(
updatedResponses
.getJSONObject(0)
.getJSONArray("answer")
.getJSONObject(0)
.has("valueDecimal"));
}

@Test
void testGetAnswers_emptyQuestionnaire() {
JSONArray questions = new JSONArray();
JSONArray responses = new JSONArray();
JSONObject extras = new JSONObject();

JSONArray updatedResponses =
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, extras, false);

assertNotNull(updatedResponses);
assertEquals(0, updatedResponses.length());
}

@Test
void testGetAnswers_mismatchedQuestionsAndResponses() {
JSONArray questions = new JSONArray();
JSONObject question = new JSONObject();
question.put("type", "text");
question.put("linkId", "text1");
questions.put(question);

JSONArray responses = new JSONArray();

JSONObject extras = new JSONObject();

assertThrows(
JSONException.class,
() ->
QuestionnaireResponseGeneratorCommand.getAnswers(questions, responses, extras, false));
}
}
Loading