diff --git a/commons/protocol/src/main/scala/net/shrine/protocol/ResultOutputType.scala b/commons/protocol/src/main/scala/net/shrine/protocol/ResultOutputType.scala index 185ece37b..9e481c721 100644 --- a/commons/protocol/src/main/scala/net/shrine/protocol/ResultOutputType.scala +++ b/commons/protocol/src/main/scala/net/shrine/protocol/ResultOutputType.scala @@ -1,155 +1,154 @@ package net.shrine.protocol import scala.xml.NodeSeq import net.shrine.util.XmlUtil import ResultOutputType.I2b2Options import scala.util.Try import scala.{ util => su } import net.shrine.util.NodeSeqEnrichments import scala.util.Success import net.shrine.serialization.I2b2Unmarshaller import net.shrine.serialization.XmlUnmarshaller import net.shrine.util.OptionEnrichments /** * @author Bill Simons * @author clint * @since 8/30/11 * @see http://cbmi.med.harvard.edu * @see http://chip.org *

* NOTICE: This software comes with NO guarantees whatsoever and is * licensed as Lgpl Open Source * @see http://www.gnu.org/licenses/lgpl.html */ final case class ResultOutputType( name: String, isBreakdown: Boolean, i2b2Options: I2b2Options, id: Option[Int]) { override def toString: String = name def deepEquals(that: ResultOutputType): Boolean = { this.productIterator.toSeq == that.productIterator.toSeq } //Preserve old enum-like behavior override def equals(other: Any): Boolean = other match { case null => false case that: ResultOutputType => this.name == that.name case _ => false } //Preserve old enum-like behavior override def hashCode: Int = name.hashCode def isError: Boolean = this.name == ResultOutputType.ERROR.name def withId(i: Int): ResultOutputType = copy(id = Some(i)) import OptionEnrichments._ def toI2b2: NodeSeq = XmlUtil.stripWhitespace { { id.toXml() } { name } { i2b2Options.displayType } LA { i2b2Options.description } } def toI2b2NameOnly(nameToUse: String = name): NodeSeq = XmlUtil.stripWhitespace { { nameToUse } } def toXml: NodeSeq = XmlUtil.stripWhitespace { { id.toXml() } { name } { isBreakdown } { i2b2Options.description } { i2b2Options.displayType } } } object ResultOutputType extends I2b2Unmarshaller[Try[ResultOutputType]] with XmlUnmarshaller[Try[ResultOutputType]] { val defaultDisplayType = "CATNUM" final case class I2b2Options(description: String, displayType: String = defaultDisplayType) //NB: There is apparently another Patient Set output type with the description "Patient set"; //I chose this version arbitrarily -Clint Oct 6, 2014 - val PATIENTSET = ResultOutputType("PATIENTSET", isBreakdown = false, I2b2Options("Patient set", "LIST"), Some(1)) +//todo delete val PATIENTSET = ResultOutputType("PATIENTSET", isBreakdown = false, I2b2Options("Patient set", "LIST"), Some(1)) val PATIENT_COUNT_XML = ResultOutputType("PATIENT_COUNT_XML", isBreakdown = false, I2b2Options("Number of patients"), Some(4)) val ERROR = ResultOutputType("ERROR", isBreakdown = false, I2b2Options("Error"), None) lazy val values: Seq[ResultOutputType] = Seq( - PATIENTSET, PATIENT_COUNT_XML, ERROR) private[this] def toMap(resultTypes: Iterable[ResultOutputType]): Map[String, ResultOutputType] = Map.empty ++ resultTypes.map(rt => toKey(rt.name) -> rt) private[this] lazy val byName: Map[String, ResultOutputType] = toMap(values) private[this] def toKey(s: String): String = s.toUpperCase def valueOf(name: String): Option[ResultOutputType] = valueOf(Set.empty[ResultOutputType])(name) def valueOf(knownTypes: Set[ResultOutputType])(name: String): Option[ResultOutputType] = tryValueOf(knownTypes)(name).toOption implicit object ResultOutputTypeOrdering extends Ordering[ResultOutputType] { override def compare(x: ResultOutputType, y: ResultOutputType): Int = x.name.compareTo(y.name) } def tryValueOf(knownTypes: Set[ResultOutputType])(name: String): Try[ResultOutputType] = { val allTypes = byName ++ toMap(knownTypes) def failure(s: String) = su.Failure(new Exception(s)) name match { case null => failure(s"Null result output type name") case _ => allTypes.get(toKey(name)) match { case None => failure(s"Unknown result output type '$name'; known types are ${allTypes.values.toSeq.sorted}") case Some(rt) => su.Success(rt) } } } def fromI2b2(xml: NodeSeq): Try[ResultOutputType] = unmarshalXml(xml)("name", "display_type", "description", "result_type_id") def fromXml(xml: NodeSeq): Try[ResultOutputType] = unmarshalXml(xml)("name", "displayType", "description", "id") private def unmarshalXml(xml: NodeSeq)(nameTag: String, displayTypeTag: String, descriptionTag: String, idTag: String): Try[ResultOutputType] = { import NodeSeqEnrichments.Strictness._ val trim: NodeSeq => String = _.text.trim def lookup(name: String) = tryValueOf(Set.empty)(name) //If name refers to one of the ResultOutputTypes defined in this object, return that //value. Otherwise, construct a new ResultOutputType from the values in the XML. //This code assumes all non-breakdown ROTs are defined in this file. for { name <- xml.withChild(nameTag).map(trim) if !name.isEmpty displayType = xml.withChild(displayTypeTag).map(trim).getOrElse(defaultDisplayType) description = xml.withChild(descriptionTag).map(trim).getOrElse(name) id = xml.withChild(idTag).map(trim).map(_.toInt).toOption result <- lookup(name).orElse(Success(ResultOutputType(name, isBreakdown = true, I2b2Options(description, displayType), id))) } yield { result } } def nonBreakdownTypes: Seq[ResultOutputType] = values lazy val nonErrorTypes: Seq[ResultOutputType] = values.filterNot(_.isError) } diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedReadInstanceResultsResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedReadInstanceResultsResponseTest.scala index 667ba5144..8b0a833fe 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedReadInstanceResultsResponseTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedReadInstanceResultsResponseTest.scala @@ -1,146 +1,146 @@ package net.shrine.protocol import junit.framework.TestCase import net.shrine.util.XmlDateHelper import net.shrine.util.XmlUtil import org.junit.Test import scala.xml.NodeSeq /** * @author clint * @author Bill Simons * @since Dec 4, 2012 */ //noinspection EmptyParenMethodOverridenAsParameterless,UnitMethodIsParameterless final class AggregatedReadInstanceResultsResponseTest extends TestCase with ShrineResponseI2b2SerializableValidator { val shrineNetworkQueryId = 1111111L val resultId1 = 1111111L val setSize = 12 - val type1 = ResultOutputType.PATIENTSET + val type1 = ResultOutputType.PATIENT_COUNT_XML val statusType1 = QueryResult.StatusType.Finished val startDate1 = XmlDateHelper.now val endDate1 = XmlDateHelper.now val result1 = QueryResult( resultId = resultId1, instanceId = shrineNetworkQueryId, resultType = Option(type1), setSize = setSize, startDate = Option(startDate1), endDate = Option(endDate1), description = None, statusType = statusType1, statusMessage = Option(statusType1.name) ) val resultId2 = 222222L val type2 = ResultOutputType.PATIENT_COUNT_XML val statusType2 = QueryResult.StatusType.Finished val startDate2 = XmlDateHelper.now val endDate2 = XmlDateHelper.now val result2 = QueryResult(resultId2, shrineNetworkQueryId, Option(type2), setSize, Option(startDate2), Option(endDate2), None, statusType2, Option(statusType2.name)) override def messageBody: NodeSeq = { DONE { resultId1 } { shrineNetworkQueryId } { type1.toI2b2 } { setSize } { startDate1 } { endDate1 } { statusType1.name } 3 FINISHED { resultId2 } { shrineNetworkQueryId } { type2.toI2b2 } { setSize } { startDate2 } { endDate2 } { statusType2.name } 3 FINISHED } private val readInstanceResultsResponse = XmlUtil.stripWhitespace { { shrineNetworkQueryId } { resultId1 } { shrineNetworkQueryId } { type1.toXml } { setSize } { startDate1 } { endDate1 } { statusType1 } { statusType1.name } { resultId2 } { shrineNetworkQueryId } { type2.toXml } { setSize } { startDate2 } { endDate2 } { statusType2 } { statusType2.name } } import DefaultBreakdownResultOutputTypes.{values => breakdownTypes} @Test def testFromXml { val fromXml = AggregatedReadInstanceResultsResponse.fromXml(breakdownTypes.toSet)(readInstanceResultsResponse) fromXml.shrineNetworkQueryId should equal(shrineNetworkQueryId) fromXml.results should equal(Seq(result1, result2)) } @Test def testResults { AggregatedReadInstanceResultsResponse(shrineNetworkQueryId, Seq(result1, result2)).results should equal(Seq(result1, result2)) } @Test def testToXml { val xml = AggregatedReadInstanceResultsResponse(shrineNetworkQueryId, Seq(result1, result2)).toXmlString //we compare the string versions of the xml because Scala's xml equality does not always behave properly xml should equal(readInstanceResultsResponse.toString()) } @Test def testFromI2b2 { val actual = AggregatedReadInstanceResultsResponse.fromI2b2(breakdownTypes.toSet)(response) actual.shrineNetworkQueryId should equal(shrineNetworkQueryId) actual.results should equal(Seq(result1, result2)) } @Test def testToI2b2 { //we compare the string versions of the xml because Scala's xml equality does not always behave properly val actual = AggregatedReadInstanceResultsResponse(shrineNetworkQueryId, Seq(result1, result2)).toI2b2String actual should equal(response.toString()) } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala index 844dfa8a6..0abbe99ed 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/AggregatedRunQueryResponseTest.scala @@ -1,318 +1,318 @@ package net.shrine.protocol import net.shrine.problem.TestProblem import scala.xml.NodeSeq import org.junit.Test import net.shrine.protocol.query.QueryDefinition import net.shrine.protocol.query.Term import net.shrine.util.XmlDateHelper import net.shrine.util.XmlUtil /** * * * @author Justin Quan * @see http://chip.org * @since 8/12/11 */ //noinspection EmptyParenMethodOverridenAsParameterless,EmptyParenMethodAccessedAsParameterless,UnitMethodIsParameterless final class AggregatedRunQueryResponseTest extends ShrineResponseI2b2SerializableValidator { private val queryId = 1L private val queryName = "queryName" private val userId = "user" private val groupId = "group" private val createDate = XmlDateHelper.now private val requestQueryDef = QueryDefinition(queryName, Term("""\\i2b2\i2b2\Demographics\Age\0-9 years old\""")) private val queryInstanceId = 2L private val resultId = 3L private val setSize = 10L private val startDate = createDate private val endDate = createDate private val resultId2 = 4L - private val resultType1 = ResultOutputType.PATIENTSET + private val resultType1 = ResultOutputType.PATIENT_COUNT_XML private val resultType2 = ResultOutputType.PATIENT_COUNT_XML private val statusType = QueryResult.StatusType.Finished override def messageBody = { DONE { queryId } { queryName } { userId } { groupId } { createDate } { requestQueryDef.toI2b2 } { queryInstanceId } { queryId } { userId } { groupId } 6 COMPLETED COMPLETED { resultId } { queryInstanceId } - 1 + 4 { resultType1 } - LIST + CATNUM LA - Patient set + Number of patients { setSize } { startDate } { endDate } { statusType } 3 FINISHED { resultId2 } { queryInstanceId } 4 { resultType2 } CATNUM LA Number of patients { setSize } { startDate } { endDate } { statusType } 3 FINISHED } private val qr1 = QueryResult( resultId = resultId, instanceId = queryInstanceId, resultType = Option(resultType1), setSize = setSize, startDate = Option(createDate), endDate = Option(createDate), description = None, statusType = statusType, statusMessage = Some(statusType.name), problemDigest = None, breakdowns = Map.empty) private val qr2 = QueryResult( resultId = resultId2, instanceId = queryInstanceId, resultType = Option(resultType2), setSize = setSize, startDate = Option(createDate), endDate = Option(createDate), description = None, statusType = statusType, statusMessage = Some(statusType.name), problemDigest = None, breakdowns = Map.empty) private val runQueryResponse = XmlUtil.stripWhitespace { { queryId } { queryInstanceId } { userId } { groupId } { requestQueryDef.toXml } { createDate } { Seq(qr1, qr2).map(_.toXml) } } import DefaultBreakdownResultOutputTypes.{ values => breakdownTypes } @Test def testFromXml { val actual = AggregatedRunQueryResponse.fromXml(breakdownTypes.toSet)(runQueryResponse).get actual.queryId should equal(queryId) actual.createDate should equal(createDate) actual.userId should equal(userId) actual.groupId should equal(groupId) actual.requestXml should equal(requestQueryDef) actual.queryInstanceId should equal(queryInstanceId) actual.results should equal(Seq(qr1, qr2)) actual.queryName should equal(queryName) } @Test def testToXml { AggregatedRunQueryResponse(queryId, createDate, userId, groupId, requestQueryDef, queryInstanceId, Seq(qr1, qr2)).toXmlString should equal(runQueryResponse.toString) } @Test def testFromI2b2 { val translatedResponse = AggregatedRunQueryResponse.fromI2b2(breakdownTypes.toSet)(response).get translatedResponse.queryId should equal(queryId) translatedResponse.createDate should equal(createDate) translatedResponse.userId should equal(userId) translatedResponse.groupId should equal(groupId) translatedResponse.requestXml should equal(requestQueryDef) translatedResponse.queryInstanceId should equal(queryInstanceId) translatedResponse.results should equal(Seq(qr1, qr2)) translatedResponse.queryName should equal(queryName) } @Test def testFromI2b2StringRequestXml { val hackToProduceXml = new HasResponse { //Produces a message body where the tag contains escaped XML as a String, as is produced by the CRC override def messageBody: NodeSeq = { DONE { queryId } { queryName } { userId } { groupId } { createDate } { requestQueryDef.toI2b2String } { queryInstanceId } { queryId } { userId } { groupId } 6 COMPLETED COMPLETED { resultId } { queryInstanceId } { resultType1 } 1 LIST LA Patient list { setSize } { startDate } { endDate } { statusType } 3 FINISHED { resultId2 } { queryInstanceId } { resultType2 } 4 CATNUM LA Number of patients { setSize } { startDate } { endDate } { statusType } 3 FINISHED } } doTestFromI2b2(hackToProduceXml.response, requestQueryDef) } private def doTestFromI2b2(i2b2Response: NodeSeq, expectedQueryDef: AnyRef) { val translatedResponse = AggregatedRunQueryResponse.fromI2b2(breakdownTypes.toSet)(i2b2Response).get translatedResponse.queryId should equal(queryId) translatedResponse.createDate should equal(createDate) translatedResponse.userId should equal(userId) translatedResponse.groupId should equal(groupId) translatedResponse.requestXml should equal(expectedQueryDef) translatedResponse.queryInstanceId should equal(queryInstanceId) translatedResponse.results should equal(Seq(qr1, qr2)) translatedResponse.queryName should equal(queryName) } @Test def testResultsPartitioned { val actual = AggregatedRunQueryResponse.fromXml(breakdownTypes.toSet)(runQueryResponse).get { val (nonErrors, errors) = actual.resultsPartitioned nonErrors should equal(Seq(qr1, qr2)) errors.size should equal(0) } def error = QueryResult.errorResult(None, "something broke", TestProblem) { val withOnlyErrors = actual.withResults(Seq(error, error)) val (nonErrors, errors) = withOnlyErrors.resultsPartitioned nonErrors.size should equal(0) errors should equal(Seq(error, error)) } { val withErrorsAndSuccesses = actual.withResults(actual.results ++ Seq(error, error)) val (nonErrors, errors) = withErrorsAndSuccesses.resultsPartitioned nonErrors should equal(Seq(qr1, qr2)) errors should equal(Seq(error, error)) } { val withNoResults = actual.withResults(Nil) val (nonErrors, errors) = withNoResults.resultsPartitioned nonErrors.size should equal(0) errors.size should equal(0) } } @Test def testToI2b2 { AggregatedRunQueryResponse(queryId, createDate, userId, groupId, requestQueryDef, queryInstanceId, Seq(qr1, qr2)).toI2b2String should equal(response.toString) } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/OutputTypeSetTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/OutputTypeSetTest.scala index c0bf313ae..bf8012728 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/OutputTypeSetTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/OutputTypeSetTest.scala @@ -1,112 +1,111 @@ package net.shrine.protocol import junit.framework.TestCase import org.scalatest.junit.AssertionsForJUnit import net.shrine.util.ShouldMatchersForJUnit import org.junit.Test /** * * @author Clint Gilbert * @date Sep 20, 2011 * * @link http://cbmi.med.harvard.edu * * This software is licensed under the LGPL * @link http://www.gnu.org/licenses/lgpl.html * */ final class OutputTypeSetTest extends ShouldMatchersForJUnit { private val possibleOutputTypeSets = Seq(ResultOutputType.values.toSet, Set(ResultOutputType.PATIENT_COUNT_XML), - Set(ResultOutputType.PATIENTSET), Set.empty[ResultOutputType]) @Test def testConstructorAndToSet { possibleOutputTypeSets.foreach { outputTypes => val outputTypeSet = new OutputTypeSet(outputTypes) outputTypeSet.toSet should equal(outputTypes) } intercept[IllegalArgumentException] { val nullSet: Set[ResultOutputType] = null new OutputTypeSet(nullSet) } } @Test def testStringConstructorAndSerialized { possibleOutputTypeSets.foreach { outputTypes => val outputTypeSet = new OutputTypeSet(outputTypes) val serialized = outputTypeSet.serialized serialized should not be (null) val roundTripped = new OutputTypeSet(serialized) roundTripped should equal(outputTypeSet) } intercept[Exception] { val nullString: String = null new OutputTypeSet(nullString) } intercept[Exception] { new OutputTypeSet("jkasdhkjashdjks") } } @Test def testSerialized { import ResultOutputType._ new OutputTypeSet(Set.empty[ResultOutputType]).serialized should equal("") - new OutputTypeSet(Set(PATIENT_COUNT_XML, PATIENTSET)).serialized should equal("PATIENT_COUNT_XML%2CPATIENTSET") + new OutputTypeSet(Set(PATIENT_COUNT_XML)).serialized should equal("PATIENT_COUNT_XML") ResultOutputType.values.foreach { outputType => new OutputTypeSet(Set(outputType)).serialized should equal(outputType.name) } } @Test def testDeserialize { import OutputTypeSet.deserialize intercept[Exception] { deserialize(null) } deserialize("") should equal(Set.empty[ResultOutputType]) ResultOutputType.values.foreach { outputType => deserialize(outputType.name) should equal(Set(outputType)) } - val someOutputTypes = Set(ResultOutputType.PATIENTSET, ResultOutputType.PATIENT_COUNT_XML) + val someOutputTypes = Set(ResultOutputType.PATIENT_COUNT_XML) - deserialize("PATIENT_COUNT_XML%2CPATIENTSET") should equal(someOutputTypes) - deserialize("PATIENTSET%2CPATIENT_COUNT_XML") should equal(someOutputTypes) + deserialize("PATIENT_COUNT_XML") should equal(someOutputTypes) + deserialize("PATIENT_COUNT_XML") should equal(someOutputTypes) } @Test def testDeserializeAllPermutations { import OutputTypeSet.{deserialize, encode} val allResultOutputTypes = ResultOutputType.values.toSet ResultOutputType.values.permutations.foreach { resultTypes => val serialized = encode(resultTypes.map(_.name).mkString(",")) deserialize(serialized) should equal(allResultOutputTypes) } } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala index 29337bed4..1b91ae976 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/QueryResultTest.scala @@ -1,498 +1,498 @@ package net.shrine.protocol import net.shrine.problem.{TestProblem, ProblemSources, AbstractProblem} import net.shrine.util.ShouldMatchersForJUnit import org.junit.Test import net.shrine.util.XmlUtil import net.shrine.util.XmlDateHelper import net.shrine.util.XmlGcEnrichments import scala.xml.{XML, NodeSeq} /** * @author Bill Simons * @author clint * @since 8/19/11 * @see http://cbmi.med.harvard.edu * @see http://chip.org *

* NOTICE: This software comes with NO guarantees whatsoever and is * licensed as Lgpl Open Source * @see http://www.gnu.org/licenses/lgpl.html */ //noinspection EmptyParenMethodAccessedAsParameterless,NameBooleanParameters final class QueryResultTest extends ShouldMatchersForJUnit with XmlRoundTripper[QueryResult] with I2b2SerializableValidator { private val date = XmlDateHelper.now private val resultId = 1L private val instanceId = 2L - private val resultType = ResultOutputType.PATIENTSET + private val resultType = ResultOutputType.PATIENT_COUNT_XML private val setSize = 12L private val statusType = QueryResult.StatusType.Finished private val description = "description" private val statusMessage = "lakjdalsjd" private val queryResult = QueryResult(resultId, instanceId, Some(resultType), setSize, Option(date), Option(date), Option(description), statusType, Option(statusType.name)) import DefaultBreakdownResultOutputTypes.{ values => breakdownTypes, _ } private val resultWithBreakDowns = queryResult.copy( statusMessage = Some(statusMessage), breakdowns = Map(PATIENT_AGE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_AGE_COUNT_XML, Map("foo" -> 1L, "bar" -> 2L)), PATIENT_RACE_COUNT_XML -> I2b2ResultEnvelope(PATIENT_RACE_COUNT_XML, Map("nuh" -> 3L, "zuh" -> 4L)), PATIENT_VITALSTATUS_COUNT_XML -> I2b2ResultEnvelope(PATIENT_VITALSTATUS_COUNT_XML, Map("blarg" -> 5L, "glarg" -> 6L)), PATIENT_GENDER_COUNT_XML -> I2b2ResultEnvelope(PATIENT_GENDER_COUNT_XML, Map("huh" -> 7L, "yeah" -> 8)))) private val expectedWhenBreakdownsArePresent = XmlUtil.stripWhitespace { { resultId } { instanceId } { resultType.toXml } { setSize } { date } { date } { description } { statusType } { statusMessage } { PATIENT_AGE_COUNT_XML } bar 2 foo 1 { PATIENT_GENDER_COUNT_XML } huh 7 yeah 8 { PATIENT_RACE_COUNT_XML } nuh 3 zuh 4 { PATIENT_VITALSTATUS_COUNT_XML } blarg 5 glarg 6 }.toString private val expectedI2b2Xml = XmlUtil.stripWhitespace { { resultId } { instanceId } { description } - 1 + 4 { resultType } - LISTLAPatient set + CATNUMLANumber of patients { setSize } { date } { date } { statusType } 3FINISHED }.toString private val expectedI2b2XmlWithBreakdowns = XmlUtil.stripWhitespace { { resultId } { instanceId } { description } { resultType.toI2b2 } { setSize } { date } { date } { statusType } 3FINISHED { PATIENT_AGE_COUNT_XML } bar 2 foo 1 { PATIENT_GENDER_COUNT_XML } huh 7 yeah 8 { PATIENT_RACE_COUNT_XML } nuh 3 zuh 4 { PATIENT_VITALSTATUS_COUNT_XML } blarg 5 glarg 6 }.toString private val expectedI2b2ErrorXml = XmlUtil.stripWhitespace { 0 0 { description } 0 ERROR { statusMessage } }.toString //NB: See https://open.med.harvard.edu/jira/browse/SHRINE-745 private val expectedI2b2IncompleteXml = XmlUtil.stripWhitespace { 0 0 { description } 0 INCOMPLETE { statusMessage } }.toString import scala.xml.XML.loadString //NB: See https://open.med.harvard.edu/jira/browse/SHRINE-745 @Test def testParseIncomplete() { val qr = QueryResult.fromI2b2(breakdownTypes.toSet)(loadString(expectedI2b2IncompleteXml)) qr.statusType should be(QueryResult.StatusType.Incomplete) } @Test def testElapsed() { queryResult.copy(startDate = None).elapsed should be(None) queryResult.copy(endDate = None).elapsed should be(None) queryResult.copy(startDate = None, endDate = None).elapsed should be(None) { val now = XmlDateHelper.now queryResult.copy(startDate = Some(now), endDate = Some(now)).elapsed should equal(Some(0L)) } { val start = XmlDateHelper.now val delta = 123L import XmlGcEnrichments._ import scala.concurrent.duration._ val end = start + delta.milliseconds queryResult.copy(startDate = Some(start), endDate = Some(end)).elapsed should equal(Some(delta)) } } @Test def testIsError() { queryResult.isError should be(false) queryResult.copy(statusType = QueryResult.StatusType.Processing).isError should be(false) queryResult.copy(statusType = QueryResult.StatusType.Finished).isError should be(false) queryResult.copy(statusType = QueryResult.StatusType.Queued).isError should be(false) queryResult.copy(statusType = QueryResult.StatusType.Incomplete).isError should be(false) queryResult.copy(statusType = QueryResult.StatusType.Error).isError should be(true) } @Test def testToXml() { val queryResultForShrine = queryResult.copy(statusMessage = Some(statusMessage)) val expectedWhenNoBreakdowns = XmlUtil.stripWhitespace { { resultId } { instanceId } { resultType.toXml } { setSize } { date } { date } { description } { statusType } { statusMessage } }.toString queryResultForShrine.copy(statusMessage = Some(statusMessage)).toXmlString should equal(expectedWhenNoBreakdowns) val expectedWhenNoStartDate = XmlUtil.stripWhitespace { { resultId } { instanceId } { resultType.toXml } { setSize } { date } { description } { statusType } { statusMessage } }.toString queryResultForShrine.copy(startDate = None).toXmlString should equal(expectedWhenNoStartDate) val expectedWhenNoEndDate = XmlUtil.stripWhitespace { { resultId } { instanceId } { resultType.toXml } { setSize } { date } { description } { statusType } { statusMessage } }.toString queryResultForShrine.copy(endDate = None).toXmlString should equal(expectedWhenNoEndDate) val expectedWhenNoDescription = XmlUtil.stripWhitespace { { resultId } { instanceId } { resultType.toXml } { setSize } { date } { date } { statusType } { statusMessage } }.toString queryResultForShrine.copy(description = None).toXmlString should equal(expectedWhenNoDescription) val expectedWhenNoStatusMessage = XmlUtil.stripWhitespace { { resultId } { instanceId } { resultType.toXml } { setSize } { date } { date } { description } { statusType } }.toString queryResult.copy(statusMessage = None).toXmlString should equal(expectedWhenNoStatusMessage) resultWithBreakDowns.toXmlString should equal(expectedWhenBreakdownsArePresent) } @Test def testFromXml() { QueryResult.fromXml(breakdownTypes.toSet)(loadString(expectedWhenBreakdownsArePresent)) should equal(resultWithBreakDowns) } @Test def testShrineRoundTrip() = { QueryResult.fromXml(breakdownTypes.toSet)(resultWithBreakDowns.toXml) should equal(resultWithBreakDowns) } private def compareIgnoringBreakdowns(actual: QueryResult, expected: QueryResult) { //Ignore breakdowns field, since this can't be serialized to i2b2 format as part of a actual.breakdowns should equal(Map.empty) actual.description should equal(expected.description) actual.endDate should equal(expected.endDate) actual.instanceId should equal(expected.instanceId) actual.resultId should equal(expected.resultId) actual.resultType should equal(expected.resultType) actual.setSize should equal(expected.setSize) actual.startDate should equal(expected.startDate) actual.statusMessage should equal(expected.statusMessage) actual.statusType should equal(expected.statusType) } @Test def testI2b2RoundTrip() = { //NB: Needed because i2b2 handles status messages differently. In the error case, statusMessage is //descriptive; otherwise, it's the all-caps name of the status type. This is different from how //Shrine creates and parses statusMessage XML, so we need a new QueryResult here. (Previously, we //could use the same one, since we were ignoring statusMessage and description when unmarshalling //from i2b2 format.) val newStatusMessage = Some(resultWithBreakDowns.statusType.name) val resultWithBreakDownsForI2b2 = resultWithBreakDowns.copy(statusMessage = newStatusMessage) val unmarshalled = QueryResult.fromI2b2(breakdownTypes.toSet)(resultWithBreakDownsForI2b2.toI2b2) compareIgnoringBreakdowns(unmarshalled, resultWithBreakDownsForI2b2) } @Test def testFromI2b2() { compareIgnoringBreakdowns(QueryResult.fromI2b2(breakdownTypes.toSet)(loadString(expectedI2b2Xml)), queryResult) } @Test def testFromI2b2WithErrors() { val errorResult = QueryResult.errorResult(Some(description), statusMessage,TestProblem) val actual = QueryResult.fromI2b2(breakdownTypes.toSet)(loadString(expectedI2b2ErrorXml)) compareIgnoringBreakdowns(actual, errorResult) } @Test def testToI2b2() { queryResult.toI2b2String should equal(expectedI2b2Xml) } @Test def testToI2b2WithBreakdowns() { resultWithBreakDowns.toI2b2String should equal(expectedI2b2XmlWithBreakdowns) } @Test def testToI2b2AllStatusTypes(): Unit = { def doTest(statusType: QueryResult.StatusType) { val expectedI2b2Xml = XmlUtil.stripWhitespace { { resultId } { instanceId } { description } { resultType.toI2b2 } { setSize } { date } { date } { statusType } { statusType.i2b2Id.get }{ statusType } }.toString val result = queryResult.copy(statusType = statusType) result.toI2b2String should equal(expectedI2b2Xml) } import QueryResult.StatusType //NB: Error is tested by testToI2b2WithErrors() val nonErrorStatuses = StatusType.values.toSet - StatusType.Error for (statusType <- nonErrorStatuses) { doTest(statusType) } } @Test def testToI2b2WithErrors(): Unit = { QueryResult.errorResult(Some(description), statusMessage, TestProblem).toI2b2String } @Test def testWithErrorsAndProblemDigest():Unit = { case class TestProblem(override val summary: String = "test summary",override val description:String = "test description") extends AbstractProblem(ProblemSources.Unknown) val testProblem:TestProblem = new TestProblem() val expected: NodeSeq = 0 0 description 0 ERROR lakjdalsjd {testProblem.problemName} {testProblem.stamp.pretty}

{testProblem.summary} {testProblem.description} {testProblem.detailsXml} val actual = QueryResult.errorResult( Some(description), statusMessage, testProblem) val i2b2Xml: NodeSeq = actual.toI2b2 val pretty = new scala.xml.PrettyPrinter(80, 2) pretty.formatNodes(i2b2Xml) should equal(pretty.formatNodes(expected)) val fromI2b2 = QueryResult.fromI2b2(Set.empty)(i2b2Xml) fromI2b2 should equal(actual) val xml = actual.toXml val fromXml = QueryResult.fromXml(Set.empty)(xml) fromXml should equal(actual) } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ReadInstanceResultsResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ReadInstanceResultsResponseTest.scala index 17a87cf61..5543be37d 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/ReadInstanceResultsResponseTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/ReadInstanceResultsResponseTest.scala @@ -1,114 +1,114 @@ package net.shrine.protocol import org.junit.Test import junit.framework.TestCase import net.shrine.util.XmlDateHelper import net.shrine.util.XmlUtil import scala.xml.NodeSeq /** * @author Bill Simons * @date 4/14/11 * @link http://cbmi.med.harvard.edu * @link http://chip.org *

* NOTICE: This software comes with NO guarantees whatsoever and is * licensed as Lgpl Open Source * @link http://www.gnu.org/licenses/lgpl.html */ final class ReadInstanceResultsResponseTest extends TestCase with ShrineResponseI2b2SerializableValidator { val shrineNetworkQueryId = 1111111L val resultId1 = 1111111L val setSize = 12 - val type1 = ResultOutputType.PATIENTSET + val type1 = ResultOutputType.PATIENT_COUNT_XML val statusName1 = QueryResult.StatusType.Finished val startDate1 = XmlDateHelper.now val endDate1 = XmlDateHelper.now val result1 = QueryResult(resultId1, shrineNetworkQueryId, Option(type1), setSize, Option(startDate1), Option(endDate1),None, statusName1, Option(statusName1.name)) val resultId2 = 222222L val type2 = ResultOutputType.PATIENT_COUNT_XML val statusName2 = QueryResult.StatusType.Finished val startDate2 = XmlDateHelper.now val endDate2 = XmlDateHelper.now val result2 = QueryResult(resultId2, shrineNetworkQueryId, Option(type2), setSize, Option(startDate2), Option(endDate2), None, statusName2, Option(statusName2.name)) override def messageBody: NodeSeq = { DONE { resultId1 } { shrineNetworkQueryId } { type1.toI2b2 } { setSize } { startDate1 } { endDate1 } { statusName1 } 3 FINISHED } private val readInstanceResultsResponse = XmlUtil.stripWhitespace { { shrineNetworkQueryId } { resultId1 } { shrineNetworkQueryId } { type1.toXml } { setSize } { startDate1 } { endDate1 } { statusName1 } { statusName1.name } } import DefaultBreakdownResultOutputTypes.{ values => breakdownTypes } @Test def testFromXml { val actual = ReadInstanceResultsResponse.fromXml(breakdownTypes.toSet)(readInstanceResultsResponse) actual.shrineNetworkQueryId should equal(shrineNetworkQueryId) actual.singleNodeResult should equal(result1) } @Test def testToXml { //we compare the string versions of the xml because Scala's xml equality does not always behave properly new ReadInstanceResultsResponse(shrineNetworkQueryId, result1).toXmlString should equal(readInstanceResultsResponse.toString) } @Test def testFromI2b2 { val actual = ReadInstanceResultsResponse.fromI2b2(breakdownTypes.toSet)(response) actual.shrineNetworkQueryId should equal(shrineNetworkQueryId) actual.singleNodeResult should equal(result1) } @Test def testToI2b2 { //we compare the string versions of the xml because Scala's xml equality does not always behave properly val actual = new ReadInstanceResultsResponse(shrineNetworkQueryId, result1).toI2b2String actual should equal(response.toString) } @Test def testResults { ReadInstanceResultsResponse(shrineNetworkQueryId, result2).results should equal(Seq(result2)) } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ReadResultOutputTypesResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ReadResultOutputTypesResponseTest.scala index 6ae5ceab5..f74f24ba8 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/ReadResultOutputTypesResponseTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/ReadResultOutputTypesResponseTest.scala @@ -1,73 +1,66 @@ package net.shrine.protocol import net.shrine.util.ShouldMatchersForJUnit import org.junit.Test import net.shrine.util.XmlUtil /** * @author clint - * @date Oct 6, 2014 + * @since Oct 6, 2014 */ final class ReadResultOutputTypesResponseTest extends ShouldMatchersForJUnit { @Test def testToI2b2: Unit = { val expectedMessageBody = XmlUtil.stripWhitespace { DONE 1 - PATIENTSET - LIST - LA - Patient set - - - 2 PATIENT_COUNT_XML CATNUM LA Number of patients - 3 + 2 PATIENT_GENDER_COUNT_XML CATNUM LA Gender patient breakdown - 4 + 3 PATIENT_VITALSTATUS_COUNT_XML CATNUM LA Vital Status patient breakdown - 5 + 4 PATIENT_RACE_COUNT_XML CATNUM LA Race patient breakdown - 6 + 5 PATIENT_AGE_COUNT_XML CATNUM LA Age patient breakdown } import ResultOutputType._ import DefaultBreakdownResultOutputTypes._ - val resp = ReadResultOutputTypesResponse(Seq(PATIENTSET, PATIENT_COUNT_XML, PATIENT_GENDER_COUNT_XML, PATIENT_VITALSTATUS_COUNT_XML, PATIENT_RACE_COUNT_XML, PATIENT_AGE_COUNT_XML)) + val resp = ReadResultOutputTypesResponse(Seq(PATIENT_COUNT_XML, PATIENT_GENDER_COUNT_XML, PATIENT_VITALSTATUS_COUNT_XML, PATIENT_RACE_COUNT_XML, PATIENT_AGE_COUNT_XML)) val messageBody = resp.i2b2MessageBody messageBody.toString should equal(expectedMessageBody.toString) } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/ResultOutputTypeTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/ResultOutputTypeTest.scala index af3c9cc21..9c647d1a1 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/ResultOutputTypeTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/ResultOutputTypeTest.scala @@ -1,210 +1,198 @@ package net.shrine.protocol import org.junit.Test import net.shrine.util.ShouldMatchersForJUnit import net.shrine.util.XmlUtil import scala.xml.NodeSeq import scala.util.Success import net.shrine.util.OptionEnrichments /** * @author clint * @date Aug 28, 2012 */ final class ResultOutputTypeTest extends ShouldMatchersForJUnit { import ResultOutputType._ @Test def testToXml: Unit = { val breakdownTypes = DefaultBreakdownResultOutputTypes.toSet def expectedXml(rt: ResultOutputType) = { val idXml = rt.id.map(i => { i }.toString).getOrElse("") s"${idXml}${rt.name}${rt.isBreakdown}${rt.i2b2Options.description}${rt.i2b2Options.displayType}" } for { rt <- (ResultOutputType.values ++ breakdownTypes) } { rt.toXml.toString should equal(expectedXml(rt)) } } @Test def testFromI2b2: Unit = { val breakdownTypes = DefaultBreakdownResultOutputTypes.toSet fromI2b2(null).isFailure should be(true) fromI2b2().isFailure should be(true) fromI2b2("").isFailure should be(true) for { rt <- ResultOutputType.values } { fromI2b2(rt.toI2b2).get should equal(rt) (fromI2b2(rt.toI2b2).get eq rt) should be(true) } for { rt <- breakdownTypes } { fromI2b2(rt.toI2b2).get should equal(rt) } } @Test def testFromXml: Unit = { val breakdownTypes = DefaultBreakdownResultOutputTypes.toSet fromXml(null).isFailure should be(true) fromXml().isFailure should be(true) fromXml("").isFailure should be(true) for { rt <- ResultOutputType.values } { fromXml(rt.toXml).get should equal(rt) (fromXml(rt.toXml).get eq rt) should be(true) } for { rt <- breakdownTypes } { fromXml(rt.toXml).get should equal(rt) } } @Test def testToString: Unit = { for { rt <- values } { rt.toString should equal(rt.name) } } @Test def testValues: Unit = { values should equal(Seq( - PATIENTSET, PATIENT_COUNT_XML, ERROR)) } @Test def testValueOf: Unit = { valueOf(null: String) should be(None) valueOf("") should be(None) valueOf("askldjlasdj") should be(None) valueOf("ERROR") should equal(Some(ERROR)) valueOf("error") should equal(Some(ERROR)) valueOf("ErRoR") should equal(Some(ERROR)) for { rt <- values } { valueOf(rt.name) should equal(Some(rt)) valueOf(rt.name.toLowerCase) should equal(Some(rt)) } } @Test def testValueOfKnownValues: Unit = { val known = DefaultBreakdownResultOutputTypes.values.toSet valueOf(known)(null) should be(None) valueOf(known)("") should be(None) valueOf(known)("askldjlasdj") should be(None) valueOf(known)("ERROR") should equal(Some(ERROR)) valueOf(known)("error") should equal(Some(ERROR)) valueOf(known)("ErRoR") should equal(Some(ERROR)) for { rt <- known } { valueOf(known)(rt.name) should equal(Some(rt)) valueOf(known)(rt.name.toLowerCase) should equal(Some(rt)) } } @Test def testTryValueOfKnownValues: Unit = { val known = DefaultBreakdownResultOutputTypes.values.toSet tryValueOf(known)(null).isFailure should be(true) tryValueOf(known)("").isFailure should be(true) tryValueOf(known)("askldjlasdj").isFailure should be(true) tryValueOf(known)("ERROR") should equal(Success(ERROR)) tryValueOf(known)("error") should equal(Success(ERROR)) tryValueOf(known)("ErRoR") should equal(Success(ERROR)) for { rt <- known } { tryValueOf(known)(rt.name) should equal(Success(rt)) tryValueOf(known)(rt.name.toLowerCase) should equal(Success(rt)) } } @Test def testBreakdownFlag: Unit = { - PATIENTSET.isBreakdown should be(false) PATIENT_COUNT_XML.isBreakdown should be(false) ERROR.isBreakdown should be(false) } @Test def testIsError: Unit = { ERROR.isError should be(true) - PATIENTSET.isError should be(false) PATIENT_COUNT_XML.isError should be(false) } @Test def testNonBreakdownTypes: Unit = { nonBreakdownTypes.toSet should equal(Set( - PATIENTSET, PATIENT_COUNT_XML, ERROR)) } @Test def testNonErrorTypes: Unit = { nonErrorTypes.toSet should equal(Set( - PATIENTSET, PATIENT_COUNT_XML)) } @Test def testToI2b2 { import XmlUtil.{ stripWhitespace => compact } val expected: Map[ResultOutputType, NodeSeq] = Map( - PATIENTSET -> compact( - 1 - PATIENTSET - LIST - LA - Patient set - ), PATIENT_COUNT_XML -> compact( 4 PATIENT_COUNT_XML CATNUM LA Number of patients )) for { outputType <- ResultOutputType.nonErrorTypes xml = outputType.toI2b2 } { xml.toString should equal(expected(outputType).toString) } } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryRequestTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryRequestTest.scala index 2abf0a57d..a5794b4c3 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryRequestTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryRequestTest.scala @@ -1,473 +1,473 @@ package net.shrine.protocol import org.junit.Test import xml.Utility import scala.xml.XML import net.shrine.util.XmlUtil import net.shrine.protocol.query.QueryDefinition import net.shrine.protocol.query.OccuranceLimited import net.shrine.protocol.query.Term /** * @author Bill Simons * @since 3/17/11 * @see http://cbmi.med.harvard.edu * @see http://chip.org *

* NOTICE: This software comes with NO guarantees whatsoever and is * licensed as Lgpl Open Source * @see http://www.gnu.org/licenses/lgpl.html */ final class RunQueryRequestTest extends ShrineRequestValidator { private val queryId = 98765L private val topicId = "1" private val topicName = "Test Topic" private val queryDefinition = QueryDefinition("Ostium secundum@14:01:35", Term("""\\SHRINE\SHRINE\Diagnoses\Congenital anomalies\Cardiac and circulatory congenital anomalies\Atrial septal defect\Ostium secundum type atrial septal defect\""")) private val resultOutputTypes = { import ResultOutputType._ - (Seq(PATIENTSET, PATIENT_COUNT_XML) ++ DefaultBreakdownResultOutputTypes.values).sortBy(_.name).zipWithIndex.map { + (Seq(PATIENT_COUNT_XML) ++ DefaultBreakdownResultOutputTypes.values).sortBy(_.name).zipWithIndex.map { case (rot, i) => rot.withId(i + 1) } } private val nonCountResultOutputTypes = resultOutputTypes.filterNot(_ == ResultOutputType.PATIENT_COUNT_XML) //add weird casing to make sure the code isn't case senstive, the client will send all sorts of weirdness private val resultOutputTypesI2b2Xml = XmlUtil.stripWhitespace { } override def messageBody = XmlUtil.stripWhitespace { { username } 0 0 CRC_QRY_runQueryInstance_fromQueryDefinition { queryDefinition.toI2b2 } { resultOutputTypesI2b2Xml } { topicId } } private def messageBodyNoTopicId = XmlUtil.stripWhitespace { { username } 0 0 CRC_QRY_runQueryInstance_fromQueryDefinition { queryDefinition.toI2b2 } { resultOutputTypesI2b2Xml } } private def messageBodyNoOutputTypes = XmlUtil.stripWhitespace { { username } 0 0 CRC_QRY_runQueryInstance_fromQueryDefinition { queryDefinition.toI2b2 } { topicId } } private def messageBodyNoCountOutputType = XmlUtil.stripWhitespace { { username } 0 0 CRC_QRY_runQueryInstance_fromQueryDefinition { queryDefinition.toI2b2 } { topicId } } private val runQueryRequest = XmlUtil.stripWhitespace { { requestHeaderFragment } { queryId } { topicId } { topicName } { resultOutputTypes.map(_.toXml) } { queryDefinition.toXml } } private val runQueryRequestNoCountOutputType = XmlUtil.stripWhitespace { { requestHeaderFragment } { queryId } { topicId } { nonCountResultOutputTypes.map(_.toXml) } { queryDefinition.toXml } } private val runQueryRequestNoOutputTypes = XmlUtil.stripWhitespace { { requestHeaderFragment } { queryId } { topicId } { queryDefinition.toXml } } private val runQueryRequestNoTopicId = XmlUtil.stripWhitespace { { requestHeaderFragment } { queryId } { resultOutputTypes.map(_.toXml) } { queryDefinition.toXml } } @Test def testAddPatientCountXmlIfNecessary: Unit = { import scala.concurrent.duration._ import ResultOutputType._ import RunQueryRequest.addPatientCountXmlIfNecessary val breakdownOutputType = ResultOutputType("PATIENT_GENDER_COUNT_XML", true, I2b2Options("Number of patients by gender"), Some(99)) val countReq = RunQueryRequest( "project-Id", 1.minute, AuthenticationInfo("d", "u", Credential("p", false)), None, None, Set(PATIENT_COUNT_XML, breakdownOutputType), QueryDefinition("foo", Some(Term("bar")))) val nonCountReq = countReq.copy(outputTypes = countReq.outputTypes - PATIENT_COUNT_XML) val noOutputTypesReq = countReq.copy(outputTypes = Set.empty) countReq.outputTypes.contains(PATIENT_COUNT_XML) should be(true) nonCountReq.outputTypes.contains(PATIENT_COUNT_XML) should be(false) addPatientCountXmlIfNecessary(countReq) should equal(countReq) addPatientCountXmlIfNecessary(nonCountReq) should equal(countReq) addPatientCountXmlIfNecessary(noOutputTypesReq).outputTypes should equal(Set(PATIENT_COUNT_XML)) } @Test def testElideAuthenticationInfo: Unit = { val req = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request()).get req.authn.username should equal(username) req.authn.domain should equal(domain) req.authn.credential.value should equal(passwd) val elided = req.elideAuthenticationInfo elided.authn.username should equal("*******") elided.authn.domain should equal("*******") elided.authn.credential.value should equal("*******") } @Test override def testFromI2b2 { val translatedRequest = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request()).get validateRequestWith(translatedRequest) { translatedRequest.topicId should equal(Some(topicId)) translatedRequest.outputTypes should equal(ResultOutputType.nonErrorTypes.toSet ++ DefaultBreakdownResultOutputTypes.toSet) translatedRequest.queryDefinition should equal(queryDefinition) val queryDefNode = translatedRequest.queryDefinition.toI2b2 queryDefNode.head.prefix should equal(queryDefNode.head.scope.getPrefix(RunQueryRequest.neededI2b2Namespace)) } } @Test def testFromI2b2NoTopicId { val translatedRequest = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request(() => messageBodyNoTopicId)).get validateRequestWith(translatedRequest) { translatedRequest.topicId should equal(None) translatedRequest.outputTypes should equal(ResultOutputType.nonErrorTypes.toSet ++ DefaultBreakdownResultOutputTypes.toSet) translatedRequest.queryDefinition should equal(queryDefinition) val queryDefNode = translatedRequest.queryDefinition.toI2b2 queryDefNode.head.prefix should equal(queryDefNode.head.scope.getPrefix(RunQueryRequest.neededI2b2Namespace)) } } @Test def testFromI2b2NoOutputTypes { val translatedRequest = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request(() => messageBodyNoOutputTypes)).get validateRequestWith(translatedRequest) { translatedRequest.topicId should equal(Some(topicId)) translatedRequest.outputTypes should equal(Set(ResultOutputType.PATIENT_COUNT_XML)) translatedRequest.queryDefinition should equal(queryDefinition) val queryDefNode = translatedRequest.queryDefinition.toI2b2 queryDefNode.head.prefix should equal(queryDefNode.head.scope.getPrefix(RunQueryRequest.neededI2b2Namespace)) } } @Test def testFromI2b2NoCountOutputType { val translatedRequest = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request(() => messageBodyNoCountOutputType)).get validateRequestWith(translatedRequest) { translatedRequest.topicId should equal(Some(topicId)) translatedRequest.outputTypes should equal(DefaultBreakdownResultOutputTypes.toSet + ResultOutputType.PATIENT_COUNT_XML) translatedRequest.queryDefinition should equal(queryDefinition) val queryDefNode = translatedRequest.queryDefinition.toI2b2 queryDefNode.head.prefix should equal(queryDefNode.head.scope.getPrefix(RunQueryRequest.neededI2b2Namespace)) } } @Test def testMapQueryDefinition { val outputTypes = ResultOutputType.nonBreakdownTypes.toSet val req = new RunQueryRequest(projectId, waitTime, authn, queryId, Option(topicId), Option(topicName), outputTypes, queryDefinition) val bogusTerm = Term("sa;ldk;alskd") val mapped = req.mapQueryDefinition(_.transform(_ => bogusTerm)) (mapped eq req) should not be (true) mapped should not equal (req) mapped.projectId should equal(projectId) mapped.waitTime should equal(waitTime) mapped.authn should equal(authn) mapped.topicId should equal(Option(topicId)) mapped.outputTypes should equal(outputTypes) mapped.queryDefinition.name should equal(queryDefinition.name) mapped.queryDefinition.expr.get should equal(bogusTerm) } @Test override def testShrineRequestFromI2b2 { val shrineRequest = CrcRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request()).get shrineRequest.isInstanceOf[RunQueryRequest] should be(true) } @Test def testDoubleDispatchingShrineRequestFromI2b2 { val shrineRequest = HandleableShrineRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(request()).get shrineRequest.isInstanceOf[RunQueryRequest] should be(true) } @Test def testShrineXmlRoundTrip: Unit = { def doTest(outputTypes: Set[ResultOutputType]) { val req = RunQueryRequest( projectId, waitTime, authn, queryId, Option(topicId), Option(topicName), outputTypes, queryDefinition) val roundTripped = RunQueryRequest.fromXml(Set.empty)(req.toXml).get roundTripped should equal(req) } doTest(ResultOutputType.nonErrorTypes.toSet) doTest(ResultOutputType.nonErrorTypes.toSet ++ DefaultBreakdownResultOutputTypes.toSet) } @Test override def testToXml { import scala.concurrent.duration._ RunQueryRequest( projectId, waitTime, authn, queryId, Option(topicId), Option(topicName), resultOutputTypes.toSet, queryDefinition).toXml should equal(runQueryRequest) } @Test def testToXmlNoTopicId { RunQueryRequest( projectId, waitTime, authn, queryId, None, None, resultOutputTypes.toSet, queryDefinition).toXml should equal(runQueryRequestNoTopicId) } @Test override def testToI2b2 { val req = RunQueryRequest( projectId, waitTime, authn, queryId, Option(topicId), Option(topicName), resultOutputTypes.toSet, queryDefinition) val actual = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(req.toI2b2).get validateRequestWith(actual) { actual.topicId should equal(Some(topicId)) actual.outputTypes should equal(resultOutputTypes.toSet) actual.queryDefinition should equal(queryDefinition) } } @Test def testToI2b2NoTopicId { val req = RunQueryRequest( projectId, waitTime, authn, queryId, None, None, resultOutputTypes.toSet, queryDefinition) val actual = RunQueryRequest.fromI2b2(DefaultBreakdownResultOutputTypes.toSet)(req.toI2b2).get validateRequestWith(actual) { actual.topicId should equal(None) actual.outputTypes should equal(resultOutputTypes.toSet) actual.queryDefinition should equal(queryDefinition) } } @Test override def testFromXml { val actual = RunQueryRequest.fromXml(DefaultBreakdownResultOutputTypes.toSet)(runQueryRequest).get validateRequestWith(actual) { actual.networkQueryId should equal(queryId) actual.topicId should equal(Some(topicId)) actual.outputTypes should equal(resultOutputTypes.toSet) actual.queryDefinition should equal(queryDefinition) val queryDefNode = actual.queryDefinition.toXml.head queryDefNode.prefix should be(null) queryDefNode.namespace should be(null) } } @Test def testFromXmlNoTopicId { val actual = RunQueryRequest.fromXml(DefaultBreakdownResultOutputTypes.toSet)(runQueryRequestNoTopicId).get validateRequestWith(actual) { actual.networkQueryId should equal(queryId) actual.topicId should equal(None) actual.outputTypes should equal(resultOutputTypes.toSet) actual.queryDefinition should equal(queryDefinition) val queryDefNode = actual.queryDefinition.toXml.head queryDefNode.prefix should be(null) queryDefNode.namespace should be(null) } } @Test def testFromXmlNoOutputTypes { val actual = RunQueryRequest.fromXml(DefaultBreakdownResultOutputTypes.toSet)(runQueryRequestNoOutputTypes).get validateRequestWith(actual) { actual.networkQueryId should equal(queryId) actual.topicId should equal(Some(topicId)) actual.outputTypes should equal(Set(ResultOutputType.PATIENT_COUNT_XML)) actual.queryDefinition should equal(queryDefinition) val queryDefNode = actual.queryDefinition.toXml.head queryDefNode.prefix should be(null) queryDefNode.namespace should be(null) } } @Test def testFromXmlNoCountOutputType { val actual = RunQueryRequest.fromXml(DefaultBreakdownResultOutputTypes.toSet)(runQueryRequestNoCountOutputType).get validateRequestWith(actual) { actual.networkQueryId should equal(queryId) actual.topicId should equal(Some(topicId)) actual.outputTypes should equal(nonCountResultOutputTypes.toSet + ResultOutputType.PATIENT_COUNT_XML) actual.queryDefinition should equal(queryDefinition) val queryDefNode = actual.queryDefinition.toXml.head queryDefNode.prefix should be(null) queryDefNode.namespace should be(null) } } @Test def testShrineRequestFromXml { ShrineRequest.fromXml(DefaultBreakdownResultOutputTypes.toSet)(runQueryRequest).get.isInstanceOf[RunQueryRequest] should be(true) } } \ No newline at end of file diff --git a/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryResponseTest.scala b/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryResponseTest.scala index e59013f8f..8a75cbae5 100644 --- a/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryResponseTest.scala +++ b/commons/protocol/src/test/scala/net/shrine/protocol/RunQueryResponseTest.scala @@ -1,244 +1,244 @@ package net.shrine.protocol import scala.xml.NodeSeq import org.junit.Test import net.shrine.protocol.query.QueryDefinition import net.shrine.protocol.query.Term import net.shrine.util.XmlDateHelper import net.shrine.util.XmlUtil /** * * * @author Justin Quan * @see http://chip.org * Date: 8/12/11 */ //noinspection EmptyParenMethodOverridenAsParameterless,EmptyParenMethodAccessedAsParameterless,UnitMethodIsParameterless final class RunQueryResponseTest extends ShrineResponseI2b2SerializableValidator { private val queryId = 1L private val queryName = "queryName" private val userId = "user" private val groupId = "group" private val createDate = XmlDateHelper.now private val requestQueryDef = QueryDefinition(queryName, Term("""\\i2b2\i2b2\Demographics\Age\0-9 years old\""")) private val queryInstanceId = 2L private val resultId = 3L private val setSize = 10L private val startDate = createDate private val endDate = createDate private val resultId2 = 4L - private val resultType1 = ResultOutputType.PATIENTSET + private val resultType1 = ResultOutputType.PATIENT_COUNT_XML private val resultType2 = ResultOutputType.PATIENT_COUNT_XML private val statusType = QueryResult.StatusType.Finished override def messageBody: NodeSeq = { DONE { queryId } { queryName } { userId } { groupId } { createDate } { requestQueryDef.toI2b2 } { queryInstanceId } { queryId } { userId } { groupId } 6 COMPLETED COMPLETED { resultId } { queryInstanceId } - 1 + 4 { resultType1 } - LIST + CATNUM LA - Patient set + Number of patients { setSize } { startDate } { endDate } { statusType } 3 FINISHED } private val qr1 = QueryResult( resultId = resultId, instanceId = queryInstanceId, resultType = Option(resultType1), setSize = setSize, startDate = Option(createDate), endDate = Option(createDate), description = None, statusType = statusType, statusMessage = Some(statusType.name)) private val runQueryResponse = XmlUtil.stripWhitespace { { queryId } { queryInstanceId } { userId } { groupId } { requestQueryDef.toXml } { createDate } { qr1.toXml } } import DefaultBreakdownResultOutputTypes.{ values => breakdownTypes } @Test def testFromXml: Unit = { val actual = RunQueryResponse.fromXml(breakdownTypes.toSet)(runQueryResponse).get actual.queryId should equal(queryId) actual.createDate should equal(createDate) actual.userId should equal(userId) actual.groupId should equal(groupId) actual.requestXml should equal(requestQueryDef) actual.queryInstanceId should equal(queryInstanceId) actual.results should equal(Seq(qr1)) actual.queryName should equal(queryName) } @Test def testToXml: Unit = { RunQueryResponse(queryId, createDate, userId, groupId, requestQueryDef, queryInstanceId, qr1).toXmlString should equal(runQueryResponse.toString) } @Test def testFromI2b2: Unit = { val translatedResponse = RunQueryResponse.fromI2b2(breakdownTypes.toSet)(response).get translatedResponse.queryId should equal(queryId) translatedResponse.createDate should equal(createDate) translatedResponse.userId should equal(userId) translatedResponse.groupId should equal(groupId) translatedResponse.requestXml should equal(requestQueryDef) translatedResponse.queryInstanceId should equal(queryInstanceId) translatedResponse.results should equal(Seq(qr1)) translatedResponse.queryName should equal(queryName) } @Test def testFromI2b2StringRequestXml: Unit = { def hackToProduceXml(statusType: QueryResult.StatusType): HasResponse = new HasResponse { //Produces a message body where the tag contains escaped XML as a String, as is produced by the CRC override def messageBody: NodeSeq = { DONE { queryId } { queryName } { userId } { groupId } { createDate } { requestQueryDef.toI2b2String } { queryInstanceId } { queryId } { userId } { groupId } 6 COMPLETED COMPLETED { resultId } { queryInstanceId } { resultType1 } 1 LIST LA Timeline { setSize } { startDate } { endDate } { statusType } 3 FINISHED { resultId2 } { queryInstanceId } { resultType2 } 4 CATNUM LA Number of patients { setSize } { startDate } { endDate } { statusType } 3 FINISHED } } for { statusType <- QueryResult.StatusType.values } { doTestFromI2b2(hackToProduceXml(statusType).response, requestQueryDef, statusType) } } private def doTestFromI2b2(i2b2Response: NodeSeq, expectedQueryDef: AnyRef, expectedStatusType: QueryResult.StatusType) { val translatedResponse = RunQueryResponse.fromI2b2(breakdownTypes.toSet)(i2b2Response).get translatedResponse.queryId should equal(queryId) translatedResponse.createDate should equal(createDate) translatedResponse.userId should equal(userId) translatedResponse.groupId should equal(groupId) translatedResponse.requestXml should equal(expectedQueryDef) translatedResponse.queryInstanceId should equal(queryInstanceId) translatedResponse.results should equal(Seq(qr1.copy(statusType = expectedStatusType))) translatedResponse.queryName should equal(queryName) translatedResponse.singleNodeResult.statusType should be(expectedStatusType) } @Test def testToI2b2 { RunQueryResponse(queryId, createDate, userId, groupId, requestQueryDef, queryInstanceId, qr1).toI2b2String should equal(response.toString) } } \ No newline at end of file diff --git a/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/RunQueryAggregator.scala b/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/RunQueryAggregator.scala index 2331d5245..d1843f574 100644 --- a/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/RunQueryAggregator.scala +++ b/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/RunQueryAggregator.scala @@ -1,70 +1,68 @@ package net.shrine.aggregation import net.shrine.aggregation.BasicAggregator.Valid import net.shrine.protocol.AggregatedRunQueryResponse import net.shrine.protocol.QueryResult import net.shrine.protocol.ResultOutputType import net.shrine.protocol.RunQueryResponse import net.shrine.protocol.ShrineResponse import net.shrine.protocol.query.QueryDefinition import net.shrine.util.XmlDateHelper /** * * * @author Justin Quan * @author Clint Gilbert * @see http://chip.org * @since 8/11/11 */ final class RunQueryAggregator( val queryId: Long, val userId: String, val groupId: String, val requestQueryDefinition: QueryDefinition, val addAggregatedResult: Boolean) extends PackagesErrorsAggregator[RunQueryResponse](errorMessage = None, invalidMessage = Some("Unexpected response")) { def withQueryId(qId: Long) = new RunQueryAggregator(qId, userId, groupId, requestQueryDefinition, addAggregatedResult) //TODO XXX: Get description/node name some better way private def transformResult(queryResult: QueryResult, metaData: Valid[RunQueryResponse]): QueryResult = queryResult.withDescription(metaData.origin.name) import RunQueryAggregator._ private[aggregation] override def makeResponse(validResponses: Iterable[Valid[RunQueryResponse]], errorResponses: Iterable[QueryResult], invalidResponses: Iterable[QueryResult]): ShrineResponse = { val results = validResponses.flatMap { case result @ Valid(origin, elapsed, response) => response.results.map(transformResult(_, result)) } import ResultOutputType._ val counts = validResponses.map { case Valid(origin, elsapsed, response) => - val setResultOption = response.results.find(_.resultTypeIs(PATIENTSET)).map(_.setSize) - val countResultOption = response.results.find(_.resultTypeIs(PATIENT_COUNT_XML)).map(_.setSize) - (setResultOption orElse countResultOption).getOrElse(0L) + countResultOption.getOrElse(0L) } val now = XmlDateHelper.now val aggResults = { if (addAggregatedResult) { val sumResult = new QueryResult(0L, invalidInstanceId, PATIENT_COUNT_XML, counts.sum, now, now, "TOTAL COUNT", QueryResult.StatusType.Finished) results.toSeq :+ sumResult } else { results } } AggregatedRunQueryResponse(queryId, now, userId, groupId, requestQueryDefinition, invalidInstanceId, aggResults.toSeq ++ errorResponses ++ invalidResponses) } } object RunQueryAggregator { val invalidInstanceId = -1L } \ No newline at end of file diff --git a/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/StoredResultsAggregator.scala b/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/StoredResultsAggregator.scala index 612c193e7..644a4a071 100644 --- a/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/StoredResultsAggregator.scala +++ b/hub/broadcaster-aggregator/src/main/scala/net/shrine/aggregation/StoredResultsAggregator.scala @@ -1,78 +1,74 @@ package net.shrine.aggregation import net.shrine.aggregation.BasicAggregator.Valid import net.shrine.protocol.AggregatedReadInstanceResultsResponse import net.shrine.protocol.AggregatedReadQueryResultResponse import net.shrine.protocol.HasQueryResults import net.shrine.protocol.QueryResult import net.shrine.protocol.ResultOutputType import net.shrine.protocol.ShrineResponse import net.shrine.aggregation.StoredResultsAggregator.Aggregated /** * @author clint * @since Nov 9, 2012 * * NB: Aggregated trait and companion object implements the typeclass pattern: * http://www.casualmiracles.com/2012/05/03/a-small-example-of-the-typeclass-pattern-in-scala/ * A typeclass is used here in place of an abstract method with multiple concrete implementations, * or another similar strategy. -Clint */ abstract class StoredResultsAggregator[R <: ShrineResponse with HasQueryResults : Manifest, AR <: ShrineResponse : Aggregated]( shrineNetworkQueryId: Long, showAggregation: Boolean, errorMessage: Option[String] = None, invalidMessage: Option[String] = None) extends PackagesErrorsAggregator[R](errorMessage, invalidMessage) { protected def consolidateQueryResults(queryResultsFromAllValidResponses: Iterable[(BasicAggregator.Valid[R], Iterable[QueryResult])]): Iterable[QueryResult] protected def makeAggregatedResult(queryResults: Iterable[QueryResult]): Option[QueryResult] - import ResultOutputType._ - - private val setType = Some(PATIENTSET) - private val finishedStatusType = QueryResult.StatusType.Finished.name private val allowedSetTypes = ResultOutputType.values.filterNot(_.isError).toSet private val makeResponse = implicitly[Aggregated[AR]] private[aggregation] final override def makeResponse(validResponses: Iterable[Valid[R]], errorResponses: Iterable[QueryResult], invalidResponses: Iterable[QueryResult]): ShrineResponse = { def isAllowedSetType(result: QueryResult) = result.resultType.map(allowedSetTypes).getOrElse(false) val allQueryResults = for { v @ Valid(_, _, response) <- validResponses } yield (v, response.results) val queryResults = consolidateQueryResults(allQueryResults) //Append the aggregated response, if any val finalQueryResults = { if (showAggregation) queryResults ++ makeAggregatedResult(queryResults) else queryResults } makeResponse(shrineNetworkQueryId, finalQueryResults ++ errorResponses ++ invalidResponses) } } object StoredResultsAggregator { /** * @author clint * @since Nov 9, 2012 */ trait Aggregated[R] { def apply(shrineNetworkQueryId: Long, queryResults: Iterable[QueryResult]): R } object Aggregated { implicit val aggregatedReadQueryResultResponseIsAggregated: Aggregated[AggregatedReadQueryResultResponse] = new Aggregated[AggregatedReadQueryResultResponse] { override def apply(shrineNetworkQueryId: Long, queryResults: Iterable[QueryResult]) = AggregatedReadQueryResultResponse(shrineNetworkQueryId, queryResults.toSeq) } implicit val aggregatedReadInstanceResultsResponseIsAggregated: Aggregated[AggregatedReadInstanceResultsResponse] = new Aggregated[AggregatedReadInstanceResultsResponse] { override def apply(shrineNetworkQueryId: Long, queryResults: Iterable[QueryResult]) = AggregatedReadInstanceResultsResponse(shrineNetworkQueryId, queryResults.toSeq) } } } \ No newline at end of file diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala index 682273cbb..5c1faf6f3 100644 --- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala +++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/ReadInstanceResultsAggregatorTest.scala @@ -1,107 +1,107 @@ package net.shrine.aggregation import net.shrine.problem.ProblemNotYetEncoded import org.junit.Test import org.junit.Assert.assertNotNull import net.shrine.protocol.{ ErrorResponse, QueryResult, ReadInstanceResultsResponse } import net.shrine.protocol.ResultOutputType._ import net.shrine.util.XmlDateHelper import net.shrine.protocol.AggregatedReadInstanceResultsResponse import net.shrine.protocol.Result import net.shrine.protocol.NodeId import net.shrine.util.ShouldMatchersForJUnit /** * @author Bill Simons * @since 6/13/11 * @see http://cbmi.med.harvard.edu * @see http://chip.org *

* NOTICE: This software comes with NO guarantees whatsoever and is * licensed as Lgpl Open Source * @see http://www.gnu.org/licenses/lgpl.html */ //noinspection UnitMethodIsParameterless,NameBooleanParameters final class ReadInstanceResultsAggregatorTest extends ShouldMatchersForJUnit { import scala.concurrent.duration._ @Test def testAggregate { val instanceId = 123L val startDate = XmlDateHelper.now val endDate = XmlDateHelper.now val queryResult1 = new QueryResult(1L, instanceId, PATIENT_COUNT_XML, 12, startDate, endDate, QueryResult.StatusType.Finished) - val queryResult2 = new QueryResult(2L, instanceId, PATIENTSET, 14, startDate, endDate, QueryResult.StatusType.Finished) + val queryResult2 = new QueryResult(2L, instanceId, PATIENT_COUNT_XML, 14, startDate, endDate, QueryResult.StatusType.Finished) val aggregator = new ReadInstanceResultsAggregator(instanceId, true) val aggregatorNoAggregate = new ReadInstanceResultsAggregator(instanceId, false) val response1 = ReadInstanceResultsResponse(instanceId, queryResult1) val response2 = ReadInstanceResultsResponse(instanceId, queryResult2) val description1 = "NODE1" val description2 = "NODE2" val result1 = Result(NodeId(description1), 1.second, response1) val result2 = Result(NodeId(description2), 5.seconds, response2) { val actual = aggregator.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedReadInstanceResultsResponse] assertNotNull(actual) assertNotNull(actual.results) actual.results.size should equal(3) val expectedTotal = queryResult1.setSize + queryResult2.setSize actual.results.contains(queryResult1.withDescription(description1)) should be(true) actual.results.contains(queryResult2.withDescription(description2).withResultType(PATIENT_COUNT_XML)) should be(true) actual.results.exists(qr => qr.setSize == expectedTotal && qr.resultTypeIs(PATIENT_COUNT_XML) && qr.description.contains("Aggregated Count")) should be(true) } { val actual = aggregatorNoAggregate.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedReadInstanceResultsResponse] assertNotNull(actual) assertNotNull(actual.results) actual.results.size should equal(2) actual.results.contains(queryResult1.withDescription(description1)) should be(true) actual.results.contains(queryResult2.withDescription(description2).withResultType(PATIENT_COUNT_XML)) should be(true) } } @Test def testAggregateWithError { val instanceId = 123L val startDate = XmlDateHelper.now val endDate = XmlDateHelper.now val queryResult = new QueryResult(1L, instanceId, PATIENT_COUNT_XML, 12, startDate, endDate, QueryResult.StatusType.Finished) val aggregator = new ReadInstanceResultsAggregator(instanceId, true) val errorMessage = "you are an error" val patientCountResponse = ReadInstanceResultsResponse(instanceId, queryResult) val errorResponse = ErrorResponse(errorMessage) val patientCountNodeDescription = "NODE1" val errorNodeDescription = "NODE2" val result1 = Result(NodeId(patientCountNodeDescription), 1.minute, patientCountResponse) val result2 = Result(NodeId(errorNodeDescription), 1.hour, errorResponse) val actual = aggregator.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedReadInstanceResultsResponse] assertNotNull(actual) assertNotNull(actual.results) actual.results.size should equal(3) actual.results.contains(queryResult.withDescription(patientCountNodeDescription)) should be(true) actual.results.exists(qr => qr.problemDigest.exists(pd => pd.codec == classOf[ProblemNotYetEncoded].getName)) should be (true) } } \ No newline at end of file diff --git a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala index 93f13f256..859fc729a 100644 --- a/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala +++ b/hub/broadcaster-aggregator/src/test/scala/net/shrine/aggregation/RunQueryAggregatorTest.scala @@ -1,154 +1,148 @@ package net.shrine.aggregation import scala.concurrent.duration.DurationInt import org.junit.Test import net.shrine.util.ShouldMatchersForJUnit import net.shrine.protocol.AggregatedRunQueryResponse import net.shrine.protocol.ErrorResponse import net.shrine.protocol.I2b2ResultEnvelope import net.shrine.protocol.NodeId import net.shrine.protocol.QueryResult import net.shrine.protocol.Result -import net.shrine.protocol.ResultOutputType -import net.shrine.protocol.ResultOutputType.PATIENTSET import net.shrine.protocol.ResultOutputType.PATIENT_COUNT_XML import net.shrine.protocol.RunQueryResponse import net.shrine.protocol.query.QueryDefinition import net.shrine.protocol.query.Term import net.shrine.util.XmlDateHelper import net.shrine.protocol.DefaultBreakdownResultOutputTypes /** * * * @author Justin Quan * @see http://chip.org * Date: 8/12/11 */ final class RunQueryAggregatorTest extends ShouldMatchersForJUnit { private val queryId = 1234L private val queryName = "someQueryName" private val now = XmlDateHelper.now private val userId = "user" private val groupId = "group" private val requestQueryDef = QueryDefinition(queryName, Term("""\\i2b2\i2b2\Demographics\Age\0-9 years old\""")) private val requestQueryDefString = requestQueryDef.toI2b2String private val queryInstanceId = 9999L import scala.concurrent.duration._ @Test def testAggregate { val qrCount = new QueryResult(1L, queryInstanceId, PATIENT_COUNT_XML, 10L, now, now, "Desc", QueryResult.StatusType.Finished) - val qrSet = new QueryResult(2L, queryInstanceId, PATIENTSET, 10L, now, now, "Desc", QueryResult.StatusType.Finished) val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrCount) - val rqr2 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrSet) - val result2 = Result(NodeId("description1"), 1.second, rqr2) val result1 = Result(NodeId("description2"), 1.second, rqr1) val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true) - val actual = aggregator.aggregate(Vector(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse] + val actual = aggregator.aggregate(Vector(result1), Nil).asInstanceOf[AggregatedRunQueryResponse] actual.queryId should equal(queryId) actual.queryInstanceId should equal(-1L) - actual.results.size should equal(3) + actual.results.size should equal(2) actual.results.filter(_.resultTypeIs(PATIENT_COUNT_XML)).size should equal(2) //1 for the actual count result, 1 for the aggregated total count - actual.results.filter(_.resultTypeIs(PATIENTSET)).size should equal(1) actual.results.filter(hasTotalCount).size should equal(1) - actual.results.filter(hasTotalCount).head.setSize should equal(20) + actual.results.filter(hasTotalCount).head.setSize should equal(10) actual.queryName should equal(queryName) } @Test def testAggCount { - val qrSet = new QueryResult(2L, queryInstanceId, PATIENTSET, 10L, now, now, "Desc", QueryResult.StatusType.Finished) + val qrSet = new QueryResult(2L, queryInstanceId, PATIENT_COUNT_XML, 10L, now, now, "Desc", QueryResult.StatusType.Finished) val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrSet) val rqr2 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrSet) val result1 = Result(NodeId("description1"), 1.second, rqr1) val result2 = Result(NodeId("description2"), 1.second, rqr2) val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true) //TODO: test handling error responses val actual = aggregator.aggregate(Vector(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse] actual.results.filter(_.description.getOrElse("").equalsIgnoreCase("TOTAL COUNT")).head.setSize should equal(20) } @Test def testHandleErrorResponse { val qrCount = new QueryResult(1L, queryInstanceId, PATIENT_COUNT_XML, 10L, now, now, "Desc", QueryResult.StatusType.Finished) val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qrCount) val errorMessage = "error message" val errorResponse = ErrorResponse(errorMessage) val result1 = Result(NodeId("description1"), 1.second, rqr1) val result2 = Result(NodeId("description2"), 1.second, errorResponse) val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true) val actual = aggregator.aggregate(Vector(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse] actual.results.size should equal(3) actual.results.filter(_.resultTypeIs(PATIENT_COUNT_XML)).head.setSize should equal(10) actual.results.filter(_.statusType == QueryResult.StatusType.Error).head.statusMessage should equal(Some(errorMessage)) actual.results.filter(hasTotalCount).head.setSize should equal(10) } @Test def testAggregateResponsesWithBreakdowns { def toColumnTuple(i: Int) = ("x" + i, i.toLong) val breakdowns1 = Map.empty ++ DefaultBreakdownResultOutputTypes.values.map { resultType => resultType -> I2b2ResultEnvelope(resultType, (1 to 10).map(toColumnTuple).toMap) } val breakdowns2 = Map.empty ++ DefaultBreakdownResultOutputTypes.values.map { resultType => resultType -> I2b2ResultEnvelope(resultType, (11 to 20).map(toColumnTuple).toMap) } val qr1 = new QueryResult(1L, queryInstanceId, Some(PATIENT_COUNT_XML), 10L, Some(now), Some(now), Some("Desc"), QueryResult.StatusType.Finished, None, breakdowns = breakdowns1) val qr2 = new QueryResult(2L, queryInstanceId, Some(PATIENT_COUNT_XML), 20L, Some(now), Some(now), Some("Desc"), QueryResult.StatusType.Finished, None, breakdowns = breakdowns2) val rqr1 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qr1) val rqr2 = RunQueryResponse(queryId, now, userId, groupId, requestQueryDef, queryInstanceId, qr2) val result1 = Result(NodeId("description2"), 1.second, rqr1) val result2 = Result(NodeId("description1"), 1.second, rqr2) val aggregator = new RunQueryAggregator(queryId, userId, groupId, requestQueryDef, true) val actual = aggregator.aggregate(Seq(result1, result2), Nil).asInstanceOf[AggregatedRunQueryResponse] actual.results.size should equal(3) actual.results.filter(hasTotalCount).size should equal(1) val Seq(actualQr1, actualQr2, actualQr3) = actual.results.filter(_.resultTypeIs(PATIENT_COUNT_XML)) actualQr1.setSize should equal(10) actualQr2.setSize should equal(20) actualQr3.setSize should equal(30) actualQr1.breakdowns should equal(breakdowns1) actualQr2.breakdowns should equal(breakdowns2) actualQr3.breakdowns.isEmpty should be(true) } private def hasTotalCount(result: QueryResult) = result.description.getOrElse("").equalsIgnoreCase("TOTAL COUNT") private def toQueryResultMap(results: QueryResult*) = Map.empty ++ (for { result <- results resultType <- result.resultType } yield (resultType, result)) } diff --git a/qep/service/src/test/scala/net/shrine/qep/ShrineResourceJaxrsTest.scala b/qep/service/src/test/scala/net/shrine/qep/ShrineResourceJaxrsTest.scala index fe69f94f1..21dca9c52 100644 --- a/qep/service/src/test/scala/net/shrine/qep/ShrineResourceJaxrsTest.scala +++ b/qep/service/src/test/scala/net/shrine/qep/ShrineResourceJaxrsTest.scala @@ -1,535 +1,534 @@ package net.shrine.qep import com.sun.jersey.api.client.UniformInterfaceException import net.shrine.client.JerseyShrineClient import net.shrine.crypto.TrustParam.AcceptAllCerts import net.shrine.protocol.{AggregatedReadInstanceResultsResponse, AggregatedReadQueryResultResponse, AggregatedReadTranslatedQueryDefinitionResponse, AggregatedRunQueryResponse, ApprovedTopic, AuthenticationInfo, BaseShrineResponse, Credential, DefaultBreakdownResultOutputTypes, DeleteQueryRequest, DeleteQueryResponse, FlagQueryRequest, FlagQueryResponse, QueryResult, ReadApprovedQueryTopicsRequest, ReadApprovedQueryTopicsResponse, ReadInstanceResultsRequest, ReadPreviousQueriesRequest, ReadPreviousQueriesResponse, ReadQueryDefinitionRequest, ReadQueryDefinitionResponse, ReadQueryInstancesRequest, ReadQueryInstancesResponse, ReadQueryResultRequest, ReadTranslatedQueryDefinitionRequest, RenameQueryRequest, RenameQueryResponse, RequestType, ResultOutputType, RunQueryRequest, ShrineRequest, ShrineRequestHandler, UnFlagQueryRequest, UnFlagQueryResponse} import net.shrine.protocol.query.{QueryDefinition, Term} import net.shrine.util.{AbstractPortSearchingJerseyTest, JerseyAppDescriptor, ShouldMatchersForJUnit, XmlDateHelper} import org.junit.{After, Before, Test} /** * * @author Clint Gilbert * @since Sep 14, 2011 * * @see http://cbmi.med.harvard.edu * * This software is licensed under the LGPL * @see http://www.gnu.org/licenses/lgpl.html * * Starts a ShrineResource in an embedded HTTP server, sends requests to it, then verifies that the requests don't fail, * and that the parameters made it from the client to the ShrineResource successfully. Uses a mock ShrineRequestHandler, so * it doesn't test that correct values are returned by the ShrineResource. */ final class ShrineResourceJaxrsTest extends AbstractPortSearchingJerseyTest with ShouldMatchersForJUnit { private val projectId = "some-project-id" private val topicId = "some-topic-id" private val userId = "some-user-id" private val authenticationInfo = AuthenticationInfo("some-domain", userId, new Credential("some-val", false)) private val shrineClient = new JerseyShrineClient(resource.getURI.toString, projectId, authenticationInfo, DefaultBreakdownResultOutputTypes.toSet, AcceptAllCerts) /** * We invoked the no-arg superclass constructor, so we must override configure() to provide an AppDescriptor * That tells Jersey to instantiate and expose ShrineResource */ override def configure = JerseyAppDescriptor.thatCreates(ShrineResource).using(MockShrineRequestHandler) @Before override def setUp(): Unit = super.setUp() @After override def tearDown(): Unit = super.tearDown() @Test def testReadApprovedQueryTopics { val response = shrineClient.readApprovedQueryTopics(userId) response should not(be(null)) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.readApprovedQueryTopicsParam validateCachedParam(param, RequestType.SheriffRequest) param.userId should equal(userId) } @Test def testReadPreviousQueries = resetMockThen { val fetchSize = 123 val response = shrineClient.readPreviousQueries(userId, fetchSize) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.readPreviousQueriesParam validateCachedParam(param, RequestType.UserRequest) param.fetchSize should equal(fetchSize) param.userId should equal(userId) } @Test def testReadPreviousQueriesUsernameMismatch = resetMockThen { intercept[UniformInterfaceException] { shrineClient.readPreviousQueries("foo", 123) } MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) } @Test def testRunQuery = resetMockThen { val queryDef = QueryDefinition("foo", Term("nuh")) def doTestRunQueryResponse(response: AggregatedRunQueryResponse, expectedOutputTypes: Set[ResultOutputType]) { response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.runQueryParam validateCachedParam(param, RequestType.QueryDefinitionRequest) param.outputTypes should equal(expectedOutputTypes) param.queryDefinition should equal(queryDef) param.topicId should equal(Some(topicId)) } def doTestRunQuery(outputTypes: Set[ResultOutputType]) { val responseScalaSet = shrineClient.runQuery(topicId, outputTypes, queryDef) doTestRunQueryResponse(responseScalaSet, outputTypes) val responseJavaSet = shrineClient.runQuery(topicId, outputTypes, queryDef) doTestRunQueryResponse(responseJavaSet, outputTypes) } Seq(ResultOutputType.values.toSet, Set(ResultOutputType.PATIENT_COUNT_XML), - Set(ResultOutputType.PATIENTSET), Set.empty[ResultOutputType]).foreach(doTestRunQuery) } @Test def testReadQueryInstances = resetMockThen { val queryId = 123L val response = shrineClient.readQueryInstances(queryId) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.readQueryInstancesParam validateCachedParam(param, RequestType.MasterRequest) param.networkQueryId should equal(queryId) } @Test def testReadInstanceResults = resetMockThen { val shrineNetworkQueryId = 98765L val response = shrineClient.readInstanceResults(shrineNetworkQueryId) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.readInstanceResultsParam validateCachedParam(param, RequestType.InstanceRequest) param.shrineNetworkQueryId should equal(shrineNetworkQueryId) } @Test def testReadQueryDefinition = resetMockThen { val queryId = 3789894L val response = shrineClient.readQueryDefinition(queryId) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.readQueryDefinitionParam validateCachedParam(param, RequestType.GetRequestXml) param.queryId should equal(queryId) } @Test def testDeleteQuery = resetMockThen { val queryId = 3789894L val response = shrineClient.deleteQuery(queryId) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.deleteQueryParam validateCachedParam(param, RequestType.MasterDeleteRequest) param.networkQueryId should equal(queryId) } @Test def testRenameQuery = resetMockThen { val queryId = 3789894L val queryName = "aslkfhkasfh" val response = shrineClient.renameQuery(queryId, queryName) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.renameQueryParam validateCachedParam(param, RequestType.MasterRenameRequest) param.networkQueryId should equal(queryId) param.queryName should equal(queryName) } @Test def testReadQueryResult = resetMockThen { val queryId = 3789894L val response = shrineClient.readQueryResult(queryId) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) val param = MockShrineRequestHandler.readQueryResultParam MockShrineRequestHandler.shouldBroadcastParam should be(true) param should not(be(null)) param.projectId should equal(projectId) param.authn should equal(authenticationInfo) param.requestType should equal(RequestType.GetQueryResult) param.waitTime should equal(ShrineResource.waitTime) param.queryId should equal(queryId) } @Test def testReadTranslatedQueryDefinition = resetMockThen { val queryDef = QueryDefinition("foo", Term("network")) val response = shrineClient.readTranslatedQueryDefinition(queryDef) response should not(be(null)) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) val param = MockShrineRequestHandler.readTranslatedQueryDefinitionParam MockShrineRequestHandler.shouldBroadcastParam should be(true) param should not(be(null)) param.authn should equal(authenticationInfo) param.requestType should equal(RequestType.ReadTranslatedQueryDefinitionRequest) param.queryDef should equal(queryDef) } @Test def testFlagQuery: Unit = resetMockThen { val queryId = 12345L val message = "laskfhdklsjfhksdf" val response = shrineClient.flagQuery(queryId, Some(message), true) response should equal(FlagQueryResponse) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) MockShrineRequestHandler.readTranslatedQueryDefinitionParam should be(null) val param = MockShrineRequestHandler.flagQueryRequestParam MockShrineRequestHandler.shouldBroadcastParam should be(true) param should not(be(null)) param.authn should equal(authenticationInfo) param.requestType should equal(RequestType.FlagQueryRequest) param.networkQueryId should equal(queryId) param.message should equal(Some(message)) } @Test def testUnFlagQuery: Unit = resetMockThen { val queryId = 12345L val response = shrineClient.unFlagQuery(queryId, true) response should equal(UnFlagQueryResponse) MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) MockShrineRequestHandler.readTranslatedQueryDefinitionParam should be(null) MockShrineRequestHandler.flagQueryRequestParam should be(null) val param = MockShrineRequestHandler.unFlagQueryRequestParam MockShrineRequestHandler.shouldBroadcastParam should be(true) param should not(be(null)) param.authn should equal(authenticationInfo) param.requestType should equal(RequestType.UnFlagQueryRequest) param.networkQueryId should equal(queryId) } private def validateCachedParam(param: ShrineRequest, expectedRequestType: RequestType) { MockShrineRequestHandler.shouldBroadcastParam should be(true) param should not(be(null)) param.projectId should equal(projectId) param.authn should equal(authenticationInfo) param.requestType should equal(expectedRequestType) param.waitTime should equal(ShrineResource.waitTime) } private def resetMockThen(body: => Any) { MockShrineRequestHandler.reset() //(Healthy?) paranoia MockShrineRequestHandler.readApprovedQueryTopicsParam should be(null) MockShrineRequestHandler.readPreviousQueriesParam should be(null) MockShrineRequestHandler.runQueryParam should be(null) MockShrineRequestHandler.readQueryInstancesParam should be(null) MockShrineRequestHandler.readInstanceResultsParam should be(null) MockShrineRequestHandler.readQueryDefinitionParam should be(null) MockShrineRequestHandler.deleteQueryParam should be(null) MockShrineRequestHandler.renameQueryParam should be(null) MockShrineRequestHandler.readQueryResultParam should be(null) MockShrineRequestHandler.flagQueryRequestParam should be(null) MockShrineRequestHandler.unFlagQueryRequestParam should be(null) MockShrineRequestHandler.readTranslatedQueryDefinitionParam should be(null) body } /** * Mock ShrineRequestHandler; stores passed parameters for later inspection. * Private, since this is (basically) the enclosing test class's state */ private object MockShrineRequestHandler extends ShrineRequestHandler { var shouldBroadcastParam = false var readApprovedQueryTopicsParam: ReadApprovedQueryTopicsRequest = _ var readPreviousQueriesParam: ReadPreviousQueriesRequest = _ var runQueryParam: RunQueryRequest = _ var readQueryInstancesParam: ReadQueryInstancesRequest = _ var readInstanceResultsParam: ReadInstanceResultsRequest = _ var readQueryDefinitionParam: ReadQueryDefinitionRequest = _ var deleteQueryParam: DeleteQueryRequest = _ var renameQueryParam: RenameQueryRequest = _ var readQueryResultParam: ReadQueryResultRequest = _ var readTranslatedQueryDefinitionParam: ReadTranslatedQueryDefinitionRequest = _ var flagQueryRequestParam: FlagQueryRequest = _ var unFlagQueryRequestParam: UnFlagQueryRequest = _ def reset() { shouldBroadcastParam = false readApprovedQueryTopicsParam = null readPreviousQueriesParam = null runQueryParam = null readQueryInstancesParam = null readInstanceResultsParam = null readQueryDefinitionParam = null deleteQueryParam = null renameQueryParam = null readQueryResultParam = null readTranslatedQueryDefinitionParam = null flagQueryRequestParam = null unFlagQueryRequestParam = null } import XmlDateHelper.now private def setShouldBroadcastAndThen(shouldBroadcast: Boolean)(f: => BaseShrineResponse): BaseShrineResponse = { try { f } finally { shouldBroadcastParam = shouldBroadcast } } override def readApprovedQueryTopics(request: ReadApprovedQueryTopicsRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readApprovedQueryTopicsParam = request ReadApprovedQueryTopicsResponse(Seq(new ApprovedTopic(123L, "some topic"))) } override def readPreviousQueries(request: ReadPreviousQueriesRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readPreviousQueriesParam = request ReadPreviousQueriesResponse(Seq.empty) } override def readQueryInstances(request: ReadQueryInstancesRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readQueryInstancesParam = request ReadQueryInstancesResponse(999L, "userId", "groupId", Seq.empty) } override def readInstanceResults(request: ReadInstanceResultsRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readInstanceResultsParam = request AggregatedReadInstanceResultsResponse(1337L, Seq(new QueryResult(123L, 1337L, Some(ResultOutputType.PATIENT_COUNT_XML), 789L, None, None, Some("description"), QueryResult.StatusType.Finished, Some("statusMessage")))) } override def readQueryDefinition(request: ReadQueryDefinitionRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readQueryDefinitionParam = request ReadQueryDefinitionResponse(87456L, "name", "userId", now, "") } override def runQuery(request: RunQueryRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { runQueryParam = request AggregatedRunQueryResponse(123L, now, "userId", "groupId", request.queryDefinition, 456L, Seq.empty) } override def deleteQuery(request: DeleteQueryRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { deleteQueryParam = request DeleteQueryResponse(56834756L) } override def renameQuery(request: RenameQueryRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { renameQueryParam = request RenameQueryResponse(873468L, "some-name") } override def readQueryResult(request: ReadQueryResultRequest, shouldBroadcast: Boolean): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readQueryResultParam = request AggregatedReadQueryResultResponse(1234567890L, Seq.empty) } override def readTranslatedQueryDefinition(request: ReadTranslatedQueryDefinitionRequest, shouldBroadcast: Boolean = true): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { readTranslatedQueryDefinitionParam = request AggregatedReadTranslatedQueryDefinitionResponse(Seq.empty) } override def flagQuery(request: FlagQueryRequest, shouldBroadcast: Boolean = true): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { flagQueryRequestParam = request FlagQueryResponse } override def unFlagQuery(request: UnFlagQueryRequest, shouldBroadcast: Boolean = true): BaseShrineResponse = setShouldBroadcastAndThen(shouldBroadcast) { unFlagQueryRequestParam = request UnFlagQueryResponse } } } \ No newline at end of file