Skip to content

Commit

Permalink
Merge f2da5fa into 6c48fcc
Browse files Browse the repository at this point in the history
  • Loading branch information
davidangb committed Oct 2, 2020
2 parents 6c48fcc + f2da5fa commit f4e30e7
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ object TSVFormatter {
private def makeRow(entity: Entity, headerValues: IndexedSeq[String]): IndexedSeq[String] = {
val rowMap: Map[Int, String] = entity.attributes map {
case (attributeName, attribute) =>
val columnPosition = headerValues.indexOf(attributeName.name)
val columnPosition = headerValues.indexOf(AttributeName.toDelimitedName(attributeName))
val cellValue = AttributeStringifier(attribute)
columnPosition -> cellValue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ object MockRawlsDAO {
Entity("PB&J", "pair", Map(AttributeName.withDefaultNS("names") -> AttributeValueList(Seq(AttributeString("PeanutButter"), AttributeString("Jelly")))))
)

val namespacedEntities = List(
Entity("first", "study", Map(
AttributeName.withDefaultNS("foo") -> AttributeString("default-foovalue"),
AttributeName.fromDelimitedName("tag:study_id") -> AttributeString("first-id"),
AttributeName.fromDelimitedName("tag:foo") -> AttributeString("namespaced-foovalue")
)),
Entity("second", "study", Map(
AttributeName.withDefaultNS("foo") -> AttributeString("default-bar"),
AttributeName.fromDelimitedName("tag:study_id") -> AttributeString("second-id"),
AttributeName.fromDelimitedName("tag:foo") -> AttributeString("namespaced-bar")
))
)

val nonModelBigQueryMetadata = Map(
"bigQuery" -> EntityTypeMetadata(
count = 2,
Expand All @@ -124,6 +137,12 @@ object MockRawlsDAO {
idName = "pair_id",
attributeNames = Seq("names")))

val namespacedMetadata = Map(
"study" -> EntityTypeMetadata(
count = 2,
idName = "study_id",
attributeNames = Seq("foo", "tag:foo", "tag:study_id")))

}


Expand Down Expand Up @@ -344,6 +363,13 @@ class MockRawlsDAO extends RawlsDAO {
results = nonModelPairEntities
)
Future.successful(queryResponse)
} else if (workspaceName == "namespacedEntities") {
val queryResponse: EntityQueryResponse = EntityQueryResponse(
parameters = query,
resultMetadata = EntityQueryResultMetadata(unfilteredCount = 2, filteredCount = 2, filteredPageCount = 1),
results = namespacedEntities
)
Future.successful(queryResponse)
} else {
val queryResponse: EntityQueryResponse = EntityQueryResponse(
parameters = query,
Expand All @@ -369,6 +395,8 @@ class MockRawlsDAO extends RawlsDAO {
Future.successful(nonModelBigQuerySetMetadata)
} else if (workspaceName == "nonModelPair") {
Future.successful(nonModelPairMetadata)
} else if (workspaceName == "namespacedEntities") {
Future.successful(namespacedMetadata)
} else {
Future.successful(validEntitiesMetadata)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,12 @@ object MockTSVStrings {
List("baz".quoted, List("this", "has", "tabs").tabbed.quoted).tabbed
).newlineSeparated

val namespacedAttributes = List(
List("foo", "tag:foo", "bar", "tag:bar").tabbed,
List("1", "2", "3", "4").tabbed,
List("5", "6", "7", "8").tabbed
).newlineSeparated

val windowsNewline = List(
List("foo", "bar").tabbed,
List("baz", "biz").tabbed
Expand Down Expand Up @@ -301,6 +307,7 @@ object MockTSVLoadFiles {
val validRemoveAddAttribute = TSVLoadFile("workspace", Seq("a1", "a2"), Seq(Seq("__DELETE__", "v2")))
val validQuotedValues = TSVLoadFile("foo", Seq("foo", "bar"), Seq(Seq("baz", "biz")))
val validQuotedValuesWithTabs = TSVLoadFile("foo", Seq("foo", "bar"), Seq(Seq("baz", "this\thas\ttabs")))
val validNamespacedAttributes = TSVLoadFile("foo", Seq("foo", "tag:foo", "bar", "tag:bar"), Seq(Seq("1","2","3","4"), Seq("5","6","7","8")))
val missingFields1 = TSVLoadFile("foo", Seq("foo", "bar", "baz"), Seq(Seq("biz", "", "buz")))
val missingFields2 = TSVLoadFile("foo", Seq("foo", "bar", "baz"), Seq(Seq("", "", "buz"), Seq("abc", "123", "")))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import akka.stream.ActorMaterializer
import org.broadinstitute.dsde.firecloud.dataaccess.MockRawlsDAO
import org.broadinstitute.dsde.firecloud.model._
import org.broadinstitute.dsde.firecloud.webservice.{CookieAuthedApiService, ExportEntitiesApiService}
import org.broadinstitute.dsde.rawls.model.{AttributeName, AttributeString, Entity}
import spray.http._
import spray.http.StatusCodes._

Expand Down Expand Up @@ -35,6 +36,7 @@ class ExportEntitiesByTypeServiceSpec extends BaseServiceSpec with ExportEntitie
val nonModelEntitiesBigQueryTSVPath = "/api/workspaces/broad-dsde-dev/nonModel/entities/bigQuery/tsv"
val nonModelEntitiesBigQuerySetTSVPath = "/api/workspaces/broad-dsde-dev/nonModelSet/entities/bigQuery_set/tsv"
val nonModelEntitiesPairTSVPath = "/api/workspaces/broad-dsde-dev/nonModelPair/entities/pair/tsv"
val namespacedEntitiesTSVPath = "/api/workspaces/broad-dsde-dev/namespacedEntities/entities/study/tsv"

// Pick the first few headers from the list of available sample headers:
val filterProps: Seq[String] = MockRawlsDAO.largeSampleHeaders.take(5).map(_.name)
Expand Down Expand Up @@ -121,6 +123,45 @@ class ExportEntitiesByTypeServiceSpec extends BaseServiceSpec with ExportEntitie
}
}

"when calling GET on exporting a non-FC model entity type with namespaced attributes" - {
"OK response is returned and file is entity type when model is flexible" in {
Get(namespacedEntitiesTSVPath + "?model=flexible") ~> dummyUserIdHeaders("1234") ~> sealRoute(exportEntitiesRoutes) ~> check {
handled should be(true)
status should be(OK)
entity shouldNot be(empty) // Entity is the first line of content as output by StreamingActor
chunks shouldNot be(empty) // Chunks has all of the rest of the content, as output by StreamingActor
headers.contains(HttpHeaders.Connection("Keep-Alive")) should be(true)
headers should contain(HttpHeaders.`Content-Disposition`.apply("attachment", Map("filename" -> "study.tsv")))
contentType shouldEqual ContentType(MediaTypes.`text/tab-separated-values`, HttpCharsets.`UTF-8`)
validateLineCount(chunks, MockRawlsDAO.namespacedEntities.length)

// confirm headers
val colheaders = entity.asString.trim.split('\t')
colheaders should contain theSameElementsAs(List("entity:study_id") ++ MockRawlsDAO.namespacedMetadata("study").attributeNames)

val bodyLines = asStringBody(chunks)
bodyLines.length shouldBe MockRawlsDAO.namespacedEntities.length // effectively the same assertion as validateLineCount

// reconstitute entities so we can assert equality.
// loop through the (non-header) lines of the TSV
val reconstitutedEntities = bodyLines.map { line =>
// split on tabs to get each cell
val cellValues = line.split("\t")
cellValues.length shouldBe colheaders.length
// loop through cells to build the name-value attributes. The order of cells matches the order of the headers.
// the first column is always the id, so skip the first column.
// note the use of idx+1 below to seek into the colheaders, since we use cellValues.tail but don't use colheaders.tail
val attrs = cellValues.tail.zipWithIndex.map {
case (cellValue, idx) => AttributeName.fromDelimitedName(colheaders(idx+1)) -> AttributeString(cellValue)
}
Entity(cellValues.head, "study", attrs.toMap)
}

reconstitutedEntities shouldBe MockRawlsDAO.namespacedEntities
}
}
}

"when calling GET on exporting a non-FC model entity set type with all attributes" - {
"400 response is returned when model defaults to firecloud" in {
Get(nonModelEntitiesBigQuerySetTSVPath) ~> dummyUserIdHeaders("1234") ~> sealRoute(exportEntitiesRoutes) ~> check {
Expand Down Expand Up @@ -341,6 +382,10 @@ class ExportEntitiesByTypeServiceSpec extends BaseServiceSpec with ExportEntitie
}
}

private def asStringBody(chunks: List[MessageChunk]): List[String] = {
chunks.flatMap(c => scala.io.Source.fromString(c.data.asString).getLines())
}

private def validateLineCount(chunks: List[MessageChunk], count: Int): Unit = {
val lineCount = chunks.map(c => scala.io.Source.fromString(c.data.asString).getLines().size).sum
lineCount should equal(count)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ class TSVParserSpec extends FlatSpec {
}
}

it should "handle attributes in namespaces" in {
val expected = MockTSVLoadFiles.validNamespacedAttributes
assertResult(expected) {
TSVParser.parse(MockTSVStrings.namespacedAttributes)
}
}

it should "handle windows newline separators" in {
val expected = MockTSVLoadFiles.validQuotedValues
assertResult(expected) {
Expand Down

0 comments on commit f4e30e7

Please sign in to comment.