Skip to content

Commit

Permalink
Merge pull request #83 from c3g/develop
Browse files Browse the repository at this point in the history
Release v0.5.1
  • Loading branch information
zxenia authored Feb 26, 2020
2 parents 21b565a + 23ea08e commit 0317219
Show file tree
Hide file tree
Showing 13 changed files with 440 additions and 136 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ addons:
- postgresql-11
- postgresql-contrib-11
before_install:
- sudo -u postgres psql -U postgres -p 5433 -d postgres -c "alter user postgres with password 'hj38f3Ntr';"
- sudo -u postgres psql -U postgres -p 5432 -d postgres -c "alter user postgres with password 'hj38f3Ntr';"
install:
- pip install -r requirements.txt
- pip install .
script:
- export POSTGRES_USER="postgres" && export POSTGRES_PASSWORD="hj38f3Ntr" && export POSTGRES_PORT=5433
- export POSTGRES_USER="postgres" && export POSTGRES_PASSWORD="hj38f3Ntr" && export POSTGRES_PORT=5432
- python3 -m coverage run ./manage.py test
- codecov
- rm -rf chord_metadata_service
Expand Down
11 changes: 8 additions & 3 deletions chord_metadata_service/chord/tests/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ def dats_dataset(project_id, creators):
}
],
"title": "1000 Genomes Project",
"description": "The 1000 Genomes Project provides a comprehensive description of common human variation by applying a combination of whole-genome sequencing, deep exome sequencing and dense microarray genotyping to a diverse set of 2504 individuals from 26 populations. Over 88 million variants are characterised, including >99% of SNP variants with a frequency of >1% for a variety of ancestries.",
"description": "The 1000 Genomes Project provides a comprehensive description of common human variation by "
"applying a combination of whole-genome sequencing, deep exome sequencing and dense microarray "
"genotyping to a diverse set of 2504 individuals from 26 populations. Over 88 million variants "
"are characterised, including >99% of SNP variants with a frequency of >1% for a variety of "
"ancestries.",
"storedIn": {
"name": "European Bioinformatics Institute"
},
Expand Down Expand Up @@ -140,13 +144,14 @@ def dats_dataset(project_id, creators):
"category": "contact",
"values": [
{
"value": "Jennifer Tremblay-Mercier, Research Co-ordinator, [email protected], 514-761-6131 #3329"
"value": "Jennifer Tremblay-Mercier, Research Co-ordinator, "
"[email protected], 514-761-6131 #3329"
}
]
}
],
"data_use": VALID_DATA_USE_1
}
}


TEST_SEARCH_QUERY_1 = ["#eq", ["#resolve", "subject", "sex"], "FEMALE"]
Expand Down
234 changes: 234 additions & 0 deletions chord_metadata_service/chord/tests/example_ingest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
EXAMPLE_INGEST = {
"subject": {
"id": "patient1",
"date_of_birth": "1964-03-15T00:00:00Z",
"sex": "MALE",
"karyotypic_sex": "UNKNOWN_KARYOTYPE"
},
"phenotypic_features": [
{
"description": "",
"type": {
"id": "HP:0000790",
"label": "Hematuria"
},
"negated": False,
"modifier": [],
"evidence": []
},
{
"description": "",
"type": {
"id": "HP:0100518",
"label": "Dysuria"
},
"negated": False,
"severity": {
"id": "HP:0012828",
"label": "Severe"
},
"modifier": [],
"evidence": []
}
],
"diseases": [
{
"term": {
"id": "NCIT:C39853",
"label": "Infiltrating Urothelial Carcinoma"
},
"disease_stage": [
{
"id": "NCIT:C48766",
"label": "pT2b Stage Finding"
},
{
"id": "NCIT:C48750",
"label": "pN2 Stage Finding"
}
]
}
],
"meta_data": {
"created": "2019-04-03T15:31:40.765Z",
"created_by": "Peter R",
"submitted_by": "Peter R",
"resources": [
{
"id": "hp",
"name": "human phenotype ontology",
"namespace_prefix": "HP",
"url": "http://purl.obolibrary.org/obo/hp.owl",
"version": "2019-04-08",
"iri_prefix": "http://purl.obolibrary.org/obo/HP_"
},
{
"id": "uberon",
"name": "uber anatomy ontology",
"namespace_prefix": "UBERON",
"url": "http://purl.obolibrary.org/obo/uberon.owl",
"version": "2019-03-08",
"iri_prefix": "http://purl.obolibrary.org/obo/UBERON_"
},
{
"id": "ncit",
"name": "NCI Thesaurus OBO Edition",
"namespace_prefix": "NCIT",
"url": "http://purl.obolibrary.org/obo/ncit.owl",
"version": "18.05d",
"iri_prefix": "http://purl.obolibrary.org/obo/NCIT_"
}
],
"updated": [],
"external_references": [
{
"id": "PMID:29221636",
"description": "Urothelial neoplasms in pediatric and young adult patients: A large single-center "
"series"
}
]
},
"biosamples": [
{
"id": "sample1",
"individual_id": "patient1",
"description": "",
"sampled_tissue": {
"id": "UBERON_0001256",
"label": "wall of urinary bladder"
},
"phenotypic_features": [],
"individual_age_at_collection": {
"age": "P52Y2M"
},
"histological_diagnosis": {
"id": "NCIT:C39853",
"label": "Infiltrating Urothelial Carcinoma"
},
"tumor_progression": {
"id": "NCIT:C84509",
"label": "Primary Malignant Neoplasm"
},
"diagnostic_markers": [],
"procedure": {
"code": {
"id": "NCIT:C5189",
"label": "Radical Cystoprostatectomy"
}
},
"is_control_sample": False
},
{
"id": "sample2",
"individual_id": "patient1",
"description": "",
"sampled_tissue": {
"id": "UBERON:0002367",
"label": "prostate gland"
},
"phenotypic_features": [],
"individual_age_at_collection": {
"age": "P52Y2M"
},
"histological_diagnosis": {
"id": "NCIT:C5596",
"label": "Prostate Acinar Adenocarcinoma"
},
"tumor_progression": {
"id": "NCIT:C95606",
"label": "Second Primary Malignant Neoplasm"
},
"tumor_grade": {
"id": "NCIT:C28091",
"label": "Gleason Score 7"
},
"disease_stage": [],
"diagnostic_markers": [],
"procedure": {
"code": {
"id": "NCIT:C15189",
"label": "Biopsy"
}
},
"is_control_sample": False
},
{
"id": "sample3",
"individual_id": "patient1",
"description": "",
"sampled_tissue": {
"id": "UBERON:0001223",
"label": "left ureter"
},
"phenotypic_features": [],
"individual_age_at_collection": {
"age": "P52Y2M"
},
"histological_diagnosis": {
"id": "NCIT:C38757",
"label": "Negative Finding"
},
"disease_stage": [],
"diagnostic_markers": [],
"procedure": {
"code": {
"id": "NCIT:C15189",
"label": "Biopsy"
}
},
"is_control_sample": False
},
{
"id": "sample4",
"individual_id": "patient1",
"description": "",
"sampled_tissue": {
"id": "UBERON:0001222",
"label": "right ureter"
},
"phenotypic_features": [],
"individual_age_at_collection": {
"age": "P52Y2M"
},
"histological_diagnosis": {
"id": "NCIT:C38757",
"label": "Negative Finding"
},
"disease_stage": [],
"diagnostic_markers": [],
"procedure": {
"code": {
"id": "NCIT:C15189",
"label": "Biopsy"
}
},
"is_control_sample": False
},
{
"id": "sample5",
"individual_id": "patient1",
"description": "",
"sampled_tissue": {
"id": "UBERON:0015876",
"label": "pelvic lymph node"
},
"phenotypic_features": [],
"individual_age_at_collection": {
"age": "P52Y2M"
},
"tumor_progression": {
"id": "NCIT:C3261",
"label": "Metastatic Neoplasm"
},
"disease_stage": [],
"diagnostic_markers": [],
"procedure": {
"code": {
"id": "NCIT:C15189",
"label": "Biopsy"
}
},
"is_control_sample": False
}
]
}
89 changes: 89 additions & 0 deletions chord_metadata_service/chord/tests/test_api_ingest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import json

from django.test import override_settings
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from uuid import uuid4

from .constants import *
from ..views_ingest import METADATA_WORKFLOWS


def generate_ingest(table_id):
return {
"table_id": table_id,
"workflow_id": "phenopackets_json",
"workflow_metadata": METADATA_WORKFLOWS["ingestion"]["phenopackets_json"],
"workflow_outputs": {
"json_document": "" # TODO
},
"workflow_params": {
"json_document": "" # TODO
}
}


class WorkflowTest(APITestCase):
def test_workflows(self):
r = self.client.get(reverse("workflows"), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_200_OK)
self.assertDictEqual(r.json(), METADATA_WORKFLOWS)

# Non-existent workflow
r = self.client.get(reverse("workflow-detail", args=("invalid_workflow",)), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_404_NOT_FOUND)

# Valid workflow
r = self.client.get(reverse("workflow-detail", args=("phenopackets_json",)), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_200_OK)
self.assertDictEqual(r.json(), METADATA_WORKFLOWS["ingestion"]["phenopackets_json"])

# Non-existent workflow file
r = self.client.get(reverse("workflow-file", args=("invalid_workflow",)), content_type="text/plain")
self.assertEqual(r.status_code, status.HTTP_404_NOT_FOUND)

# Valid workflow file
r = self.client.get(reverse("workflow-file", args=("phenopackets_json",)), content_type="text/plain")
self.assertEqual(r.status_code, status.HTTP_200_OK)
# TODO: Check file contents


class IngestTest(APITestCase):
@override_settings(AUTH_OVERRIDE=True) # For permissions
def setUp(self) -> None:
r = self.client.post(reverse("project-list"), data=json.dumps(VALID_PROJECT_1), content_type="application/json")
self.project = r.json()

r = self.client.post(reverse("dataset-list"), data=json.dumps(valid_dataset_1(self.project["identifier"])),
content_type="application/json")
self.dataset = r.json()

@override_settings(AUTH_OVERRIDE=True) # For permissions
def test_ingest(self):
# No ingestion body
r = self.client.post(reverse("ingest"), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_400_BAD_REQUEST)

# Invalid ingestion request
r = self.client.post(reverse("ingest"), data=json.dumps({}), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_400_BAD_REQUEST)

# Non-existent dataset ID
r = self.client.post(reverse("ingest"), data=json.dumps(generate_ingest(str(uuid4()))),
content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_400_BAD_REQUEST)

# Non-existent workflow ID
bad_wf = generate_ingest(self.dataset["identifier"])
bad_wf["workflow_id"] += "_invalid"
r = self.client.post(reverse("ingest"), data=json.dumps(bad_wf), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_400_BAD_REQUEST)

# json_document not in output
bad_wf = generate_ingest(self.dataset["identifier"])
bad_wf["workflow_outputs"] = {}
r = self.client.post(reverse("ingest"), data=json.dumps(bad_wf), content_type="application/json")
self.assertEqual(r.status_code, status.HTTP_400_BAD_REQUEST)

# TODO: More
Loading

0 comments on commit 0317219

Please sign in to comment.