Skip to content

Commit

Permalink
✅ Add tests for GenomicFile
Browse files Browse the repository at this point in the history
Create mocks for indexd
  • Loading branch information
dankolbman committed Apr 16, 2018
1 parent a80113e commit 2433bb4
Show file tree
Hide file tree
Showing 13 changed files with 193 additions and 147 deletions.
2 changes: 2 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ class TestingConfig(Config):
SQLALCHEMY_DATABASE_URI = 'postgres://postgres@localhost:5432/test'
SQLALCHEMY_TRACK_MODIFICATIONS = True

INDEXD_URL = os.environ.get('INDEXD_URL', '')


class ProductionConfig(Config):
@staticmethod
Expand Down
3 changes: 2 additions & 1 deletion dataservice/api/genomic_file/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ def merge_indexd(self):
"""
Gets additional fields from indexd
"""
if current_app.config['DEBUG']:
if current_app.config['INDEXD_URL'] == None:
return

indexd_url = current_app.config['INDEXD_URL']
resp = requests.get(indexd_url + self.uuid)
for prop, v in resp.json().items():
Expand Down
14 changes: 9 additions & 5 deletions dataservice/api/genomic_file/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from marshmallow import ValidationError

from dataservice.extensions import db
from dataservice.api.common.pagination import paginated, Pagination
from dataservice.api.genomic_file.models import GenomicFile
from dataservice.api.genomic_file.schemas import GenomicFileSchema
from dataservice.api.common.views import CRUDView
Expand All @@ -16,9 +17,13 @@ class GenomicFileListAPI(CRUDView):
rule = '/genomic-files'
schemas = {'GenomicFile': GenomicFileSchema}

def get(self):
@paginated
def get(self, after, limit):
"""
Get a paginated genomic_files
Get paginated genomic_files
Retrieves the genomic files stored in the datamodel, then fetch
additional properties that are stored in indexd under the same uuid.
---
template:
path:
Expand Down Expand Up @@ -103,9 +108,8 @@ def put(self, kf_id):
GenomicFile
"""
body = request.json or {}
try:
gf = GenomicFile.query.get(kf_id)
except NoResultFound:
gf = GenomicFile.query.get(kf_id)
if gf is None:
abort(404, 'could not find {} `{}`'
.format('GenomicFile', kf_id))

Expand Down
1 change: 0 additions & 1 deletion dataservice/api/genomic_file/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


class GenomicFileSchema(BaseSchema):
__endpoint__ = 'api.genomic_files'
class Meta(BaseSchema.Meta):
model = GenomicFile
resource_url = 'api.genomic_files'
Expand Down
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pytest==3.3.1
pytest-cache==1.0
pytest-cov==2.5.1
pytest-pep8==1.0.6
pytest-mock==1.7.0
27 changes: 9 additions & 18 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from dataservice.api.sequencing_experiment.models import SequencingExperiment
from dataservice.api.study_file.models import StudyFile

from tests.mocks import MockIndexd


@pytest.yield_fixture(scope='session')
def app():
Expand All @@ -36,13 +38,17 @@ def client(app):
db.drop_all()


@pytest.yield_fixture(scope='module')
@pytest.yield_fixture(scope='function')
def swagger(client):
yield json.loads(client.get('/swagger').data.decode('utf-8'))


@pytest.fixture
def entities(client):
def entities(client, mocker):
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
indexd = MockIndexd()
mock.get = indexd.get
mock.post = indexd.post
"""
Create mock entities
"""
Expand All @@ -55,6 +61,7 @@ def entities(client):
'data_type': 'reads',
'file_format': 'fastq',
'file_url': 's3://bucket/key',
'urls': ['s3://bucket/key'],
'md5sum': str(uuid.uuid4()),
'controlled_access': False
},
Expand Down Expand Up @@ -91,16 +98,10 @@ def entities(client):
'shipment_origin': 'CORIELL',
'shipment_destination': 'Baylor',
'analyte_type': 'DNA',
<<<<<<< HEAD
'concentration_mg_per_ml': 200.0,
'volume_ml': 13.99,
'shipment_date': str(datetime.utcnow()),
'uberon_id': 'test'
=======
'concentration': 200,
'volume': 13.99,
'shipment_date': str(datetime.utcnow()),
>>>>>>> :sparkles: Add genomic file resource
},
'/sequencing-experiments': {
'external_id': 'se1',
Expand Down Expand Up @@ -178,19 +179,9 @@ def entities(client):
biospecimen_id=biospecimen.kf_id,
sequencing_experiment_id=seq_exp.kf_id)

<<<<<<< HEAD
biospecimen.genomic_files = [gen_file]
seq_exp.genomic_files = [gen_file]
p.biospecimens = [biospecimen]
=======
aliquot.sequencing_experiments = [seq_exp]
sample.aliquots = [aliquot]
genomic_file = GenomicFile(**inputs['/genomic-files'])
sample.aliquots = [aliquot]
p.samples = [sample]
sample.aliquots = [aliquot]
aliquot.sequencing_experiments = [seq_exp]
>>>>>>> :sparkles: Add genomic file resource
p.diagnoses = [diagnosis]
p.outcomes = [outcome]
p.phenotypes = [phenotype]
Expand Down
27 changes: 23 additions & 4 deletions tests/genomic_file/test_genomic_file_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
import random

from sqlalchemy.exc import IntegrityError
from unittest.mock import patch

from dataservice.extensions import db
from dataservice.api.study.models import Study
from dataservice.api.participant.models import Participant
from dataservice.api.biospecimen.models import Biospecimen
from dataservice.api.sequencing_experiment.models import SequencingExperiment
from dataservice.api.genomic_file.models import GenomicFile

from tests.utils import FlaskTestCase
from tests.mocks import MockIndexd


MAX_SIZE_MB = 5000
MIN_SIZE_MB = 1000
Expand All @@ -21,10 +25,13 @@ class ModelTest(FlaskTestCase):
Test GenomicFile database model
"""

def test_create_and_find(self):
@patch('dataservice.api.genomic_file.models.requests')
def test_create_and_find(self, mock):
"""
Test create genomic file
"""
indexd = MockIndexd()
mock.post = indexd.post
# Create genomic file dependent entities
self._create_save_dependents()

Expand All @@ -42,7 +49,7 @@ def test_create_and_find(self):
'data_type': 'submitted aligned read',
'file_format': '.cram',
'file_url': 's3://file_{}'.format(i),
'md5sum': str(uuid.uuid4()),
'md5sum': uuid.uuid4(),
'controlled_access': True,
'is_harmonized': True,
'reference_genome': 'Test01',
Expand All @@ -66,10 +73,13 @@ def test_create_and_find(self):
for k, v in kwargs.items():
self.assertEqual(getattr(gf, k), v)

@patch('dataservice.api.genomic_file.models.requests')
def test_create_via_biospecimen(self):
"""
Test create genomic file
"""
indexd = MockIndexd()
mock.post = indexd.post
# Create and save genomic files and dependent entities
biospecimen_id, kwargs_dict = self._create_save_genomic_files()

Expand All @@ -87,10 +97,13 @@ def test_create_via_biospecimen(self):
for k, v in kwargs.items():
self.assertEqual(getattr(gf, k), v)

def test_update(self):
@patch('dataservice.api.genomic_file.models.requests')
def test_update(self, mock):
"""
Test update genomic file
"""
indexd = MockIndexd()
mock.post = indexd.post
# Create and save genomic files and dependent entities
biospecimen_id, kwargs_dict = self._create_save_genomic_files()

Expand All @@ -108,10 +121,13 @@ def test_update(self):
[self.assertEqual(getattr(gf, k), v)
for k, v in kwargs.items()]

def test_delete(self):
@patch('dataservice.api.genomic_file.models.requests')
def test_delete(self, mock):
"""
Test delete existing genomic file
"""
indexd = MockIndexd()
mock.post = indexd.post
# Create and save genomic files and dependent entities
biospecimen_id, kwargs_dict = self._create_save_genomic_files()

Expand All @@ -129,12 +145,15 @@ def test_delete(self):
kf_id=biospecimen_id).one()
self.assertEqual(len(biospecimen.genomic_files), 0)

@patch('dataservice.api.genomic_file.models.requests')
def test_delete_via_biospecimen(self):
"""
Test delete existing genomic file
Delete biospecimen to which genomic file belongs
"""
indexd = MockIndexd()
mock.post = indexd.post
# Create and save genomic files and dependent entities
biospecimen_id, kwargs_dict = self._create_save_genomic_files()

Expand Down
45 changes: 29 additions & 16 deletions tests/genomic_file/test_genomic_file_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,28 @@
from dataservice.extensions import db
from dataservice.api.genomic_file.models import GenomicFile

from tests.mocks import mock_indexd_post, mock_indexd_get, mock_indexd_put
from tests.mocks import MockIndexd


GENOMICFILE_URL = 'api.genomic_files'
GENOMICFILE_LIST_URL = 'api.genomic_files_list'


@pytest.fixture
def genomic_files(client):
def genomic_files(client, mocker):
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
indexd = MockIndexd()
mock.get = indexd.get
mock.post = indexd.post

props = {
'file_name': 'hg38.bam',
'data_type': 'aligned reads',
'file_format': 'bam'
}
db.session.add(participant)
gfs = [GenomicFile(**props) for _ in range(102)]
db.session.add_all(gfs)
db.session.commit()


def test_new(client, mocker):
Expand All @@ -35,12 +40,12 @@ def test_new(client, mocker):
"""
# Mock data returned from gen3
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.post = mock_indexd_post()
mock.post = MockIndexd().post

resp = _new_genomic_file(client)
assert 'genomic_file' in resp['_status']['message']
assert 'created' in resp['_status']['message']
assert GenomicFile.query.first().uuid == mock_indexd_post()().json()['did']
assert resp['results']['file_name'] == 'hg38.bam'

gf = GenomicFile.query.first()
genomic_file = resp['results']
Expand All @@ -53,7 +58,7 @@ def test_new_indexd_error(client, mocker):
"""
# Mock data returned from gen3
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.post = mock_indexd_post(status_code=500)
mock.post = MockIndexd(status_code=500).post

body = {
'file_name': 'hg38.bam',
Expand Down Expand Up @@ -81,14 +86,17 @@ def test_get_list(client, genomic_files, mocker):
"""
# Mock data returned from gen3
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.get = mock_indexd_get
indexd = MockIndexd()
mock.get = indexd.get
mock.post = indexd.post

resp = client.get(url_for(GENOMICFILE_LIST_URL))
resp = json.loads(resp.data.decode('utf-8'))

assert resp['_status']['code'] == 200
assert resp['total'] == 102
assert len(resp['results']) == 10
# Check that each entry has both the model's and indexd's fields
for r in resp['results']:
assert r['hashes'] == {'md5': 'dcff06ebb19bc9aa8f1aae1288d10dc2'}
assert r['metadata'] == {'acls': 'INTERNAL'}
Expand All @@ -106,7 +114,8 @@ def test_get_one(client, genomic_files, mocker):
"""
# Mock data returned from gen3
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.get = mock_indexd_get
indexd = MockIndexd()
mock.get = indexd.get

gf = GenomicFile.query.first()

Expand All @@ -125,14 +134,16 @@ def test_get_one(client, genomic_files, mocker):
assert resp['data_type'] == 'aligned reads'
assert resp['file_format'] == 'bam'


def test_update(client, mocker):
"""
Test updating an existing genomic file
"""
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.get = mock_indexd_get
mock.post = mock_indexd_post()
mock.put = mock_indexd_put()
indexd = MockIndexd()
mock.post = indexd.post
mock.get = indexd.get
mock.put = indexd.put

resp = _new_genomic_file(client)
participant = resp['results']
Expand All @@ -147,7 +158,7 @@ def test_update(client, mocker):
data=json.dumps(body),
headers={'Content-Type': 'application/json'})

assert response.status_code == 201
assert response.status_code == 200

resp = json.loads(response.data.decode("utf-8"))
assert 'genomic_file' in resp['_status']['message']
Expand All @@ -166,8 +177,9 @@ def test_delete(client, mocker):
Test deleting a participant by id
"""
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.post = mock_indexd_get()
mock.post = mock_indexd_post()
indexd = MockIndexd()
mock.get = indexd.get
mock.post = indexd.post

init = GenomicFile.query.count()

Expand All @@ -191,8 +203,9 @@ def test_delete_error(client, mocker):
Test handling of indexd error
"""
mock = mocker.patch('dataservice.api.genomic_file.models.requests')
mock.post = mock_indexd_get()
mock.post = mock_indexd_post()
indexd = MockIndexd()
mock.get = indexd.get
mock.post = indexd.post

response_mock = MagicMock()
response_mock.status_code = 500
Expand Down
Loading

0 comments on commit 2433bb4

Please sign in to comment.