예제 #1
0
    def test_update_compound_hets_variant_tags(self):
        variant_tags = VariantTag.objects.filter(saved_variants__guid__in=[COMPOUND_HET_1_GUID, COMPOUND_HET_2_GUID])
        self.assertEqual(len(variant_tags), 0)

        update_variant_tags_url = reverse(
            update_variant_tags_handler, args=[','.join([COMPOUND_HET_1_GUID, COMPOUND_HET_2_GUID])])
        _check_login(self, update_variant_tags_url)

        response = self.client.post(update_variant_tags_url, content_type='application/json', data=json.dumps({
            'tags': [{'name': 'Review'}, {'name': 'Excluded'}],
            'familyGuid': 'F000001_1'
        }))
        self.assertEqual(response.status_code, 200)

        response_json = response.json()
        compound_het_1_tag_guids = response_json['savedVariantsByGuid'][COMPOUND_HET_1_GUID]['tagGuids']
        compound_het_2_tag_guids = response_json['savedVariantsByGuid'][COMPOUND_HET_2_GUID]['tagGuids']
        self.assertEqual(len(compound_het_1_tag_guids), 2)
        self.assertEqual(len(compound_het_2_tag_guids), 2)
        self.assertSetEqual({"Review", "Excluded"}, {
            vt['name'] for vt in response_json['variantTagsByGuid'].values()
            if vt['tagGuid'] in compound_het_1_tag_guids
        })
        self.assertSetEqual({"Review", "Excluded"}, {
            vt['name'] for vt in response_json['variantTagsByGuid'].values()
            if vt['tagGuid'] in compound_het_2_tag_guids
        })
        self.assertSetEqual(
            {"Review", "Excluded"},
            {vt.variant_tag_type.name for vt in VariantTag.objects.filter(
                saved_variants__guid__in=[COMPOUND_HET_1_GUID, COMPOUND_HET_2_GUID])})
예제 #2
0
    def test_saved_variant_data(self, mock_reference):
        mock_reference.return_value.get_genes.side_effect = lambda gene_ids: {gene_id: {'geneId': gene_id} for gene_id in gene_ids}

        url = reverse(saved_variant_data, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        variants = response.json()['savedVariants']
        self.assertSetEqual(set(variants.keys()), {'SV0000002_1248367227_r0390_100', 'SV0000001_2103343353_r0390_100'})

        variant = variants['SV0000001_2103343353_r0390_100']
        self.assertSetEqual(
            set(variant.keys()),
            {'variantId', 'xpos', 'ref', 'alt', 'chrom', 'pos', 'genomeVersion', 'liftedOverGenomeVersion',
             'liftedOverChrom', 'liftedOverPos', 'familyGuid', 'tags', 'functionalData', 'notes', 'clinvar',
             'origAltAlleles', 'geneIds', 'genotypes', 'hgmd', 'annotation', 'transcripts', 'locusLists'}
        )

        # filter by family
        response = self.client.get('{}?family=F000002_2'.format(url))
        self.assertEqual(response.status_code, 200)

        self.assertSetEqual(set(response.json()['savedVariants'].keys()), {'SV0000002_1248367227_r0390_100'})

        # filter by variant guid
        response = self.client.get('{}{}'.format(url, VARIANT_GUID))
        self.assertEqual(response.status_code, 200)

        self.assertSetEqual(set(response.json()['savedVariants'].keys()), {VARIANT_GUID})

        # filter by invalid variant guid
        response = self.client.get('{}foo'.format(url))
        self.assertEqual(response.status_code, 404)
예제 #3
0
    def test_gene_info(self, mock_reference):
        mock_reference.return_value.get_gene.return_value = deepcopy(MOCK_GENE)
        mock_reference.return_value.get_tissue_expression_display_values.return_value = []

        url = reverse(gene_info, args=[GENE_ID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        gene = response.json()[GENE_ID]
        self.assertDictEqual(
            gene, {
                'geneId': GENE_ID,
                'geneName': 'TTN',
                'phenotypeInfo': {},
                'expression': [],
                'notes': [],
                'constraints': {
                    'lof': {
                        'constraint': None,
                        'rank': None,
                        'totalGenes': None
                    },
                    'missense': {
                        'constraint': None,
                        'rank': None,
                        'totalGenes': None
                    },
                }
            })
예제 #4
0
    def test_add_and_remove_project_locus_lists(self):
        project = Project.objects.get(guid=PROJECT_GUID)
        self.assertListEqual(list(get_project_locus_list_models(project)), [])

        # add a locus list
        url = reverse(add_project_locus_lists, args=[PROJECT_GUID])
        _check_login(self, url)

        response = self.client.post(url,
                                    content_type='application/json',
                                    data=json.dumps(
                                        {'locusListGuids': [LOCUS_LIST_GUID]}))
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(response.json()['locusListGuids'],
                             [LOCUS_LIST_GUID])
        self.assertListEqual(list(get_project_locus_list_models(project)),
                             [LocusList.objects.get(guid=LOCUS_LIST_GUID)])

        # remove a locus list
        url = reverse(delete_project_locus_lists, args=[PROJECT_GUID])
        response = self.client.post(url,
                                    content_type='application/json',
                                    data=json.dumps(
                                        {'locusListGuids': [LOCUS_LIST_GUID]}))
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(response.json()['locusListGuids'], [])
        self.assertListEqual(list(get_project_locus_list_models(project)), [])
예제 #5
0
    def test_update_mme_result_status(self):
        url = reverse(update_mme_result_status, args=[RESULT_STATUS_GUID])
        _check_login(self, url)

        response = self.client.post(url, content_type='application/json', data=json.dumps({
            'matchmakerResultGuid': RESULT_STATUS_GUID,
            'comments': 'test comment',
            'deemedIrrelevant': False,
            'flagForAnalysis': True,
        }))

        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertDictEqual(response_json, {'mmeResultsByGuid': {RESULT_STATUS_GUID: {
            'matchStatus': {
                'matchmakerResultGuid': RESULT_STATUS_GUID,
                'comments': 'test comment',
                'weContacted': False,
                'hostContacted': True,
                'deemedIrrelevant': False,
                'flagForAnalysis': True,
                'createdDate': '2019-02-12T18:43:56.358Z',
            },
        }}})

        result_model = MatchmakerResult.objects.get(guid=RESULT_STATUS_GUID)
        self.assertEqual(result_model.comments, 'test comment')
예제 #6
0
    def test_create_update_and_delete_project(self):
        create_project_url = reverse(create_project_handler)
        _check_login(self, create_project_url)

        # check validation of bad requests
        response = self.client.post(create_project_url, content_type='application/json', data=json.dumps({'bad_json': None}))
        self.assertEqual(response.status_code, 400)

        response = self.client.post(create_project_url, content_type='application/json', data=json.dumps({'form': {'missing_name': True}}))
        self.assertEqual(response.status_code, 400)

        # send valid request to create project
        response = self.client.post(create_project_url, content_type='application/json', data=json.dumps(
            {'name': 'new_project', 'description': 'new project description'}
        ))

        self.assertEqual(response.status_code, 200)

        # check that project was created
        new_project = Project.objects.filter(name='new_project')
        self.assertEqual(len(new_project), 1)
        self.assertEqual(new_project[0].description, 'new project description')

        # delete the project
        delete_project_url = reverse(delete_project_handler, args=[new_project[0].guid])
        response = self.client.post(delete_project_url, content_type='application/json')

        self.assertEqual(response.status_code, 200)

        # check that project was deleted
        new_project = Project.objects.filter(name='new_project')
        self.assertEqual(len(new_project), 0)
예제 #7
0
    def test_update_variant_functional_data(self):
        variant_functional_data = VariantFunctionalData.objects.filter(saved_variants__guid__contains=VARIANT_GUID)
        self.assertSetEqual(
            {"Biochemical Function", "Genome-wide Linkage"}, {vt.functional_data_tag for vt in variant_functional_data})
        self.assertSetEqual({"A note", "2"}, {vt.metadata for vt in variant_functional_data})

        update_variant_tags_url = reverse(update_variant_functional_data_handler, args=[VARIANT_GUID])
        _check_login(self, update_variant_tags_url)

        response = self.client.post(update_variant_tags_url, content_type='application/json', data=json.dumps({
            'functionalData': [
                {'tagGuid': 'VFD0000023_1248367227_r0390_10', 'name': 'Biochemical Function',
                 'metadata': 'An updated note'},
                {'name': 'Bonferroni corrected p-value', 'metadata': 0.05}
            ],
            'familyGuid': 'F000001_1'
        }))
        self.assertEqual(response.status_code, 200)

        functional_data_guids = response.json()['savedVariantsByGuid'][VARIANT_GUID]['functionalDataGuids']
        self.assertEqual(len(functional_data_guids), 2)
        new_guid = next(guid for guid in functional_data_guids if guid != 'VFD0000023_1248367227_r0390_10')

        functional_data = response.json()['variantFunctionalDataByGuid']
        self.assertIsNone(functional_data['VFD0000024_1248367227_r0390_10'])
        self.assertEqual(functional_data['VFD0000023_1248367227_r0390_10']['name'], 'Biochemical Function')
        self.assertEqual(functional_data['VFD0000023_1248367227_r0390_10']['metadata'], 'An updated note')
        self.assertEqual(functional_data[new_guid]['name'], 'Bonferroni corrected p-value')
        self.assertEqual(functional_data[new_guid]['metadata'], 0.05)

        variant_functional_data = VariantFunctionalData.objects.filter(saved_variants__guid__contains=VARIANT_GUID)
        self.assertSetEqual(
            {"Biochemical Function", "Bonferroni corrected p-value"},
            {vt.functional_data_tag for vt in variant_functional_data})
        self.assertSetEqual({"An updated note", "0.05"}, {vt.metadata for vt in variant_functional_data})
예제 #8
0
    def test_search_context(self):
        search_context_url = reverse(search_context_handler)
        _check_login(self, search_context_url)

        response = self.client.get('{}?foo=bar'.format(search_context_url))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'Invalid query params: {"foo": "bar"}')

        response = self.client.get('{}?projectGuid={}'.format(search_context_url, PROJECT_GUID))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', }
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])

        response = self.client.get('{}?familyGuid=F000001_1'.format(search_context_url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', }
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])

        response = self.client.get('{}?analysisGroupGuid=AG0000183_test_group'.format(search_context_url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', }
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])

        response = self.client.get('{}?projectCategoryGuid=PC000003_test_category_name'.format(search_context_url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', 'projectCategoriesByGuid'}
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])
        self.assertListEqual(response_json['projectCategoriesByGuid'].keys(), ['PC000003_test_category_name'])
예제 #9
0
    def test_update_mme_contact_note(self):
        url = reverse(update_mme_contact_note, args=['GeneDx'])
        _check_login(self, url)

        # Test create
        response = self.client.post(url, content_type='application/json', data=json.dumps({
            'institution': 'GeneDx',
            'comments': 'test comment',
        }))

        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {'mmeContactNotes': {'genedx': {
            'institution': 'genedx',
            'comments': 'test comment',
        }}})

        models = MatchmakerContactNotes.objects.filter(institution='genedx')
        self.assertEqual(models.count(), 1)
        self.assertEqual(models.first().comments, 'test comment')

        # Test update
        response = self.client.post(url, content_type='application/json', data=json.dumps({
            'institution': 'GeneDx',
            'comments': 'test comment update',
        }))

        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {'mmeContactNotes': {'genedx': {
            'institution': 'genedx',
            'comments': 'test comment update',
        }}})

        models = MatchmakerContactNotes.objects.filter(institution='genedx')
        self.assertEqual(models.count(), 1)
        self.assertEqual(models.first().comments, 'test comment update')
예제 #10
0
    def test_update_variant_tags(self):
        variant_tags = VariantTag.objects.filter(saved_variant__guid=VARIANT_GUID)
        self.assertSetEqual({"Review", "Tier 1 - Novel gene and phenotype"}, {vt.variant_tag_type.name for vt in variant_tags})
        variant_functional_data = VariantFunctionalData.objects.filter(saved_variant__guid=VARIANT_GUID)
        self.assertSetEqual({"Biochemical Function", "Genome-wide Linkage"}, {vt.functional_data_tag for vt in variant_functional_data})
        self.assertSetEqual({"A note", "2"}, {vt.metadata for vt in variant_functional_data})

        update_variant_tags_url = reverse(update_variant_tags_handler, args=[VARIANT_GUID])
        _check_login(self, update_variant_tags_url)

        response = self.client.post(update_variant_tags_url, content_type='application/json', data=json.dumps({
            'tags': [{'tagGuid': 'VT1708633_2103343353_r0390_100', 'name': 'Review'}, {'name': 'Excluded'}],
            'functionalData': [
                {'tagGuid': 'VFD0000023_1248367227_r0390_10', 'name': 'Biochemical Function', 'metadata': 'An updated note'},
                {'name': 'Bonferroni corrected p-value', 'metadata': 0.05}
            ]
        }))
        self.assertEqual(response.status_code, 200)

        tags = response.json()['savedVariantsByGuid'][VARIANT_GUID]['tags']
        self.assertEqual(len(tags), 2)
        self.assertSetEqual({"Review", "Excluded"}, {vt['name'] for vt in tags})
        self.assertSetEqual({"Review", "Excluded"}, {vt.variant_tag_type.name for vt in VariantTag.objects.filter(saved_variant__guid=VARIANT_GUID)})

        functionalData = response.json()['savedVariantsByGuid'][VARIANT_GUID]['functionalData']
        self.assertEqual(len(functionalData), 2)
        self.assertSetEqual({"Biochemical Function", "Bonferroni corrected p-value"}, {vt['name'] for vt in functionalData})
        self.assertSetEqual({"An updated note", "0.05"}, {vt['metadata'] for vt in functionalData})
        variant_functional_data = VariantFunctionalData.objects.filter(saved_variant__guid=VARIANT_GUID)
        self.assertSetEqual({"Biochemical Function", "Bonferroni corrected p-value"}, {vt.functional_data_tag for vt in variant_functional_data})
        self.assertSetEqual({"An updated note", "0.05"}, {vt.metadata for vt in variant_functional_data})
예제 #11
0
    def test_add_and_remove_project_locus_lists(self):
        existing_guid = 'LL00005_retina_proteome'

        # add a locus list
        url = reverse(add_project_locus_lists, args=[PROJECT_GUID])
        _check_login(self, url)

        response = self.client.post(url,
                                    content_type='application/json',
                                    data=json.dumps(
                                        {'locusListGuids': [LOCUS_LIST_GUID]}))
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(response.json()['locusListGuids'],
                             [LOCUS_LIST_GUID, existing_guid])
        ll_projects = LocusList.objects.get(
            guid=LOCUS_LIST_GUID).projects.all()
        self.assertEqual(ll_projects.count(), 2)
        self.assertTrue(PROJECT_GUID in {p.guid for p in ll_projects})

        # remove a locus list
        url = reverse(delete_project_locus_lists, args=[PROJECT_GUID])
        response = self.client.post(url,
                                    content_type='application/json',
                                    data=json.dumps(
                                        {'locusListGuids': [LOCUS_LIST_GUID]}))
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(response.json()['locusListGuids'],
                             [existing_guid])
        ll_projects = LocusList.objects.get(
            guid=LOCUS_LIST_GUID).projects.all()
        self.assertEqual(ll_projects.count(), 1)
        self.assertFalse(PROJECT_GUID in {p.guid for p in ll_projects})
예제 #12
0
    def test_individuals_table_handler(self):
        individuals_url = reverse(receive_individuals_table_handler,
                                  args=[PROJECT_GUID])
        _check_login(self, individuals_url)

        data = 'Family ID	Individual ID	Paternal ID	Maternal ID	Sex	Affected Status	Notes\n\
"1"	"NA19675"	"NA19678"	"NA19679"	"Female"	"Affected"	"A affected individual, test1-zsf"\n\
"1"	"NA19678"	""	""	"Male"	"Unaffected"	"a individual note"\n\
"2"	"HG00733"	""	""	"Female"	"Unaffected"	""'

        f = SimpleUploadedFile("1000_genomes demo_individuals.tsv", data)

        response = self.client.post(individuals_url, {'f': f})
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertListEqual(response_json.keys(),
                             ['info', 'errors', 'warnings', 'uploadedFileId'])

        url = reverse(save_individuals_table_handler,
                      args=[PROJECT_GUID, response_json['uploadedFileId']])

        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertListEqual(response_json.keys(),
                             ['individualsByGuid', 'familiesByGuid'])
예제 #13
0
    def test_saved_variant_data(self):
        url = reverse(saved_variant_data, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        variants = response.json()['savedVariantsByGuid']
        self.assertSetEqual(set(variants.keys()), {'SV0000002_1248367227_r0390_100', 'SV0000001_2103343353_r0390_100'})

        variant = variants['SV0000001_2103343353_r0390_100']
        self.assertSetEqual(
            set(variant.keys()),
            {'variantId', 'variantGuid', 'xpos', 'ref', 'alt', 'chrom', 'pos', 'genomeVersion', 'liftedOverGenomeVersion',
             'liftedOverChrom', 'liftedOverPos', 'familyGuids', 'tags', 'functionalData', 'notes', 'clinvar',
             'originalAltAlleles', 'mainTranscript', 'genotypes', 'hgmd', 'transcripts', 'locusListGuids', 'populations',
             'predictions', 'rsid', 'genotypeFilters'}
        )
        self.assertSetEqual(set(variant['genotypes'].keys()), {'I000003_na19679', 'I000001_na19675', 'I000002_na19678'})

        # filter by family
        response = self.client.get('{}?families=F000002_2'.format(url))
        self.assertEqual(response.status_code, 200)

        self.assertSetEqual(set(response.json()['savedVariantsByGuid'].keys()), {'SV0000002_1248367227_r0390_100'})

        # filter by variant guid
        response = self.client.get('{}{}'.format(url, VARIANT_GUID))
        self.assertEqual(response.status_code, 200)

        self.assertSetEqual(set(response.json()['savedVariantsByGuid'].keys()), {VARIANT_GUID})

        # filter by invalid variant guid
        response = self.client.get('{}foo'.format(url))
        self.assertEqual(response.status_code, 404)
예제 #14
0
    def test_get_hpo_terms(self):
        url = reverse(get_hpo_terms, args=['HP:0011458'])
        _check_login(self, url)

        response = self.client.get(url, content_type='application/json')
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(
            response.json(), {
                'HP:0011458': {
                    'HP:0002017': {
                        'id': 'HP:0002017',
                        'category': 'HP:0025031',
                        'label': 'Nausea and vomiting'
                    },
                    'HP:0001252': {
                        'id': 'HP:0001252',
                        'category': 'HP:0025031',
                        'label': 'Muscular hypotonia'
                    },
                }
            })

        url = reverse(get_hpo_terms, args=['HP:0002017'])
        response = self.client.get(url, content_type='application/json')
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.json(), {'HP:0002017': {}})
예제 #15
0
    def test_update_mme_result_status(self):
        url = reverse(update_mme_result_status, args=[RESULT_STATUS_GUID])
        _check_login(self, url)

        response = self.client.post(url, content_type='application/json', data=json.dumps({
            'matchmakerResultGuid': RESULT_STATUS_GUID,
            'comments': 'test comment',
            'deemedIrrelevant': False,
            'flagForAnalysis': True,
        }))

        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertDictEqual(response_json, {'mmeResultsByGuid': {RESULT_STATUS_GUID: {
            'matchStatus': {
                'matchmakerResultGuid': RESULT_STATUS_GUID,
                'comments': 'test comment',
                'weContacted': False,
                'hostContacted': True,
                'deemedIrrelevant': False,
                'flagForAnalysis': True,
                'matchRemoved': False,
                'createdDate': '2019-02-12T18:43:56.358Z',
            },
        }}})

        result_model = MatchmakerResult.objects.get(guid=RESULT_STATUS_GUID)
        self.assertEqual(result_model.comments, 'test comment')
예제 #16
0
    def test_receive_alignment_table_handler(self):
        url = reverse(receive_alignment_table_handler, args=[PROJECT_GUID])
        _check_login(self, url)

        # Send invalid requests
        f = SimpleUploadedFile('samples.csv', b"NA19675\nNA19679,gs://readviz/NA19679.bam")
        response = self.client.post(url, data={'f': f})
        self.assertEqual(response.status_code, 400)
        self.assertDictEqual(response.json(), {'errors': ['Must contain 2 columns: NA19675']})

        f = SimpleUploadedFile('samples.csv', b"NA19675, /readviz/NA19675.cram\nNA19679,gs://readviz/NA19679.bam")
        response = self.client.post(url, data={'f': f})
        self.assertEqual(response.status_code, 400)
        self.assertDictEqual(response.json(), {'errors': ['The following Individual IDs do not exist: NA19675']})

        # Send valid request
        f = SimpleUploadedFile('samples.csv', b"NA19675_1,/readviz/NA19675.cram\nNA19679,gs://readviz/NA19679.bam")
        response = self.client.post(url, data={'f': f})
        self.assertEqual(response.status_code, 200)

        self.assertDictEqual(response.json(), {
            'uploadedFileId': mock.ANY,
            'errors': [],
            'info': ['Parsed 2 rows from samples.csv', 'No change detected for 1 individuals'],
            'updatesByIndividualGuid': {'I000003_na19679': 'gs://readviz/NA19679.bam'},
        })
예제 #17
0
    def test_delete_mme_submission(self):
        url = reverse(delete_mme_submission, args=[INDIVIDUAL_GUID])
        _check_login(self, url)

        responses.add(responses.DELETE, 'http://localhost:9020/patient/delete', body='Failed request', status=400)
        responses.add(responses.DELETE, 'http://localhost:9020/patient/delete', status=200)

        response = self.client.post(url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'Failed request')

        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertEqual(
            response_json['individualsByGuid'][INDIVIDUAL_GUID]['mmeDeletedDate'][:10],
            datetime.today().strftime('%Y-%m-%d')
        )

        # Test proxy calls
        self.assertEqual(len(responses.calls), 2)
        self.assertEqual(responses.calls[1].request.url, 'http://localhost:9020/patient/delete')
        self.assertEqual(responses.calls[1].request.headers['X-Auth-Token'], 'abcd')
        self.assertEqual(responses.calls[1].request.headers['Accept'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[1].request.headers['Content-Type'],
                         'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[1].request.body, json.dumps({'id': 'NA19675_1_01'}))

        # Test do not delete if already deleted
        response = self.client.post(url)
        self.assertEqual(response.status_code, 402)
        self.assertEqual(response.reason_phrase, 'Matchmaker submission has already been deleted for NA19675_1')
예제 #18
0
    def test_gene_info(self):
        url = reverse(gene_info, args=[GENE_ID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        gene = response.json()[GENE_ID]
        self.assertSetEqual(
            set(gene.keys()), {
                'chromGrch37',
                'chromGrch38',
                'codingRegionSizeGrch37',
                'codingRegionSizeGrch38',
                'constraints',
                'diseaseDesc',
                'endGrch37',
                'endGrch38',
                'functionDesc',
                'gencodeGeneType',
                'geneId',
                'geneSymbol',
                'omimPhenotypes',
                'startGrch37',
                'startGrch38',
                'notes',
                'expression',
            })
예제 #19
0
    def test_update_family_pedigree_image(self):
        url = reverse(update_family_pedigree_image, args=[FAMILY_GUID])
        _check_login(self, url)

        f = SimpleUploadedFile("new_ped_image_123.png", b"file_content")

        # send invalid request
        response = self.client.post(url, {'f1': f, 'f2': f})
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'Received 2 files')

        # send valid add/update request
        response = self.client.post(url, {'f': f})
        self.assertEqual(response.status_code, 200)
        response_json = response.json()

        self.assertListEqual(response_json.keys(), ['F000001_1'])
        self.assertRegex(response_json['F000001_1']['pedigreeImage'],
                         '/media/pedigree_images/new_ped_image_.+\.png')

        # send valid delete request
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        response_json = response.json()

        self.assertListEqual(response_json.keys(), ['F000001_1'])
        self.assertIsNone(response_json['F000001_1']['pedigreeImage'])
예제 #20
0
    def test_update_family_assigned_analyst(self):
        url = reverse(update_family_assigned_analyst, args=[FAMILY_GUID])
        _check_login(self, url)

        # send invalid username (without permission)
        response = self.client.post(url, content_type='application/json',
                                    data=json.dumps({'assigned_analyst_username': '******'}))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'specified user does not exist')

        # send valid request
        response = self.client.post(url, content_type='application/json',
                                    data=json.dumps({'assigned_analyst_username': '******'}))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()

        self.assertListEqual(response_json.keys(), [FAMILY_GUID])
        self.assertEqual(response_json[FAMILY_GUID]['assignedAnalyst']['email'], '*****@*****.**')
        self.assertEqual(response_json[FAMILY_GUID]['assignedAnalyst']['fullName'], 'Test User')

        # unassign analyst
        response = self.client.post(url, content_type='application/json', data=json.dumps({}))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertListEqual(response_json.keys(), [FAMILY_GUID])
        self.assertIsNone(response_json[FAMILY_GUID]['assignedAnalyst'])
예제 #21
0
    def test_saved_search(self):
        get_saved_search_url = reverse(get_saved_search_handler)
        _check_login(self, get_saved_search_url)

        response = self.client.get(get_saved_search_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.json()['savedSearchesByGuid']), 3)

        create_saved_search_url = reverse(create_saved_search_handler)

        response = self.client.post(create_saved_search_url,
                                    content_type='application/json',
                                    data='{}')
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, '"Name" is required')

        body = {'name': 'Test Search'}
        body.update(SEARCH)
        response = self.client.post(create_saved_search_url,
                                    content_type='application/json',
                                    data=json.dumps(body))
        self.assertEqual(response.status_code, 200)
        saved_searches = response.json()['savedSearchesByGuid']
        self.assertEqual(len(saved_searches), 1)
        search_guid = saved_searches.keys()[0]
        self.assertDictEqual(
            saved_searches[search_guid], {
                'savedSearchGuid': search_guid,
                'name': 'Test Search',
                'search': SEARCH,
            })

        response = self.client.get(get_saved_search_url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.json()['savedSearchesByGuid']), 4)
예제 #22
0
    def test_receive_families_table_handler(self):
        url = reverse(receive_families_table_handler, args=[PROJECT_GUID])
        _check_login(self, url)

        # send request with a "families" attribute
        data = b'Family ID	Display Name	Description	Coded Phenotype\n\
"1"	"1"	"family one description"	""\n\
"2"	"2"	"family two description"	""'

        f = SimpleUploadedFile("1000_genomes demo_families.tsv", data)

        response = self.client.post(url, {'f': f})
        self.assertEqual(response.status_code, 200)
        response_json = response.json()

        self.assertListEqual(response_json.keys(), ['info', 'errors', 'warnings', 'uploadedFileId'])

        url = reverse(edit_families_handler, args=[PROJECT_GUID])

        response = self.client.post(url, content_type='application/json',
                data=json.dumps({'uploadedFileId': response_json['uploadedFileId']}))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()

        self.assertListEqual(response_json.keys(), ['familiesByGuid'])
        self.assertListEqual(response_json['familiesByGuid'].keys(), [FAMILY_GUID2, FAMILY_GUID])
        self.assertEqual(response_json['familiesByGuid'][FAMILY_GUID]['description'], 'family one description')
        self.assertEqual(response_json['familiesByGuid'][FAMILY_GUID2]['description'], 'family two description')
예제 #23
0
    def test_delete_mme_submission(self):
        url = reverse(delete_mme_submission, args=[INDIVIDUAL_GUID])
        _check_login(self, url)

        responses.add(responses.DELETE, 'http://localhost:9020/patient/delete', body='Failed request', status=400)
        responses.add(responses.DELETE, 'http://localhost:9020/patient/delete', status=200)

        response = self.client.post(url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'Failed request')

        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertEqual(
            response_json['individualsByGuid'][INDIVIDUAL_GUID]['mmeDeletedDate'][:10],
            datetime.today().strftime('%Y-%m-%d')
        )

        self.assertEqual(MatchmakerResult.objects.filter(individual__guid=INDIVIDUAL_GUID).count(), 2)

        # Test proxy calls
        self.assertEqual(len(responses.calls), 2)
        self.assertEqual(responses.calls[1].request.url, 'http://localhost:9020/patient/delete')
        self.assertEqual(responses.calls[1].request.headers['X-Auth-Token'], 'abcd')
        self.assertEqual(responses.calls[1].request.headers['Accept'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[1].request.headers['Content-Type'],
                         'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[1].request.body, json.dumps({'id': 'NA19675_1_01'}))

        # Test do not delete if already deleted
        response = self.client.post(url)
        self.assertEqual(response.status_code, 402)
        self.assertEqual(response.reason_phrase, 'Matchmaker submission has already been deleted for NA19675_1')
예제 #24
0
    def test_query_single_variant(self, mock_get_variant):
        mock_get_variant.return_value = VARIANTS[0]

        url = reverse(query_single_variant_handler, args=['21-3343353-GAGA-G'])
        _check_login(self, url)

        response = self.client.get('{}?familyGuid=F000001_1'.format(url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json.keys()), {
                'searchedVariants', 'savedVariantsByGuid', 'genesById',
                'projectsByGuid', 'familiesByGuid', 'individualsByGuid',
                'samplesByGuid', 'locusListsByGuid', 'analysisGroupsByGuid',
                'variantTagsByGuid', 'variantNotesByGuid',
                'variantFunctionalDataByGuid'
            })

        self.assertListEqual(response_json['searchedVariants'],
                             EXPECTED_VARIANTS[:1])
        self.assertSetEqual(set(response_json['savedVariantsByGuid'].keys()),
                            {'SV0000001_2103343353_r0390_100'})
        self.assertSetEqual(set(response_json['genesById'].keys()),
                            {'ENSG00000227232', 'ENSG00000268903'})
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
예제 #25
0
    def test_phenotips_edit_patient(self):
        url = reverse(phenotips_edit_patient, args=['R0001_1kg', 'P0000001'])
        _check_login(self, url)

        response = self.client.post(url,
                                    content_type='application/json',
                                    data=json.dumps({'some_json': 'test'}))
        self.assertEqual(response.status_code, 200)
예제 #26
0
    def test_project_categories_api(self):
        url = reverse(update_project_categories_handler, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.post(url, content_type='application/json', data=json.dumps({
            'categories': []
        }))
        self.assertEqual(response.status_code, 200)
예제 #27
0
    def test_create_partially_saved_compound_het_variant_note(self):
        # compound het 5 is not saved, whereas compound het 1 is saved
        create_saved_variant_url = reverse(create_saved_variant_handler)
        _check_login(self, create_saved_variant_url)

        request_body = {
            'variant': [
                COMPOUND_HET_5_JSON, {
                    'variantId': 'abc123',
                    'xpos': 21003343353,
                    'ref': 'GAGA',
                    'alt': 'G'
                }
            ],
            'note':
            'one_saved_one_not_saved_compount_hets_note',
            'submitToClinvar':
            True,
            'familyGuid':
            'F000001_1',
        }
        response = self.client.post(create_saved_variant_url,
                                    content_type='application/json',
                                    data=json.dumps(request_body))
        self.assertEqual(response.status_code, 200)

        self.assertEqual(len(response.json()['savedVariantsByGuid']), 2)
        compound_het_guids = response.json()['savedVariantsByGuid'].keys()
        compound_het_guids.remove(VARIANT_GUID)
        compound_het_5_guid = compound_het_guids[0]

        saved_compound_het_5 = SavedVariant.objects.get(
            guid=compound_het_5_guid, family__guid='F000001_1')
        self.assertDictEqual(COMPOUND_HET_5_JSON,
                             saved_compound_het_5.saved_variant_json)

        expected_compound_het_5_json = {
            'variantGuid': compound_het_5_guid,
            'selectedMainTranscriptId': None,
            'tagGuids': [],
            'functionalDataGuids': [],
        }
        expected_compound_het_5_json.update(COMPOUND_HET_5_JSON)
        response_json = response.json()
        response_compound_het_5_json = response_json['savedVariantsByGuid'][
            compound_het_5_guid]
        note_guids = response_compound_het_5_json.pop('noteGuids')
        self.assertDictEqual(expected_compound_het_5_json,
                             response_compound_het_5_json)
        self.assertListEqual(
            note_guids,
            response_json['savedVariantsByGuid'][VARIANT_GUID]['noteGuids'])
        self.assertEqual(len(note_guids), 1)

        self.assertEqual(
            'one_saved_one_not_saved_compount_hets_note',
            response_json['variantNotesByGuid'][note_guids[0]]['note'],
        )
예제 #28
0
    def test_update_compound_hets_variant_functional_data(self):
        variant_functional_data = VariantFunctionalData.objects.filter(
            saved_variants__guid__in=[
                COMPOUND_HET_1_GUID, COMPOUND_HET_2_GUID
            ])
        self.assertEqual(len(variant_functional_data), 0)

        # send valid request to creat variant_tag for compound hets
        update_variant_tags_url = reverse(
            update_variant_functional_data_handler,
            args=[','.join([COMPOUND_HET_1_GUID, COMPOUND_HET_2_GUID])])
        _check_login(self, update_variant_tags_url)

        response = self.client.post(update_variant_tags_url,
                                    content_type='application/json',
                                    data=json.dumps({
                                        'functionalData': [{
                                            'name':
                                            'Biochemical Function',
                                            'metadata':
                                            'An updated note'
                                        }, {
                                            'name':
                                            'Bonferroni corrected p-value',
                                            'metadata': 0.05
                                        }],
                                        'familyGuid':
                                        'F000001_1'
                                    }))
        self.assertEqual(response.status_code, 200)

        compound_het_1_functional_data_guids = response.json(
        )['savedVariantsByGuid'][COMPOUND_HET_1_GUID]['functionalDataGuids']
        compound_het_2_functional_data_guids = response.json(
        )['savedVariantsByGuid'][COMPOUND_HET_2_GUID]['functionalDataGuids']
        self.assertEqual(len(compound_het_1_functional_data_guids), 2)
        self.assertEqual(len(compound_het_2_functional_data_guids), 2)
        self.assertSetEqual(
            {"Biochemical Function", "Bonferroni corrected p-value"}, {
                vt['name']
                for vt in response.json()
                ['variantFunctionalDataByGuid'].values()
            })
        self.assertSetEqual({"An updated note", 0.05}, {
            vt['metadata']
            for vt in response.json()['variantFunctionalDataByGuid'].values()
        })
        variant_functional_data = VariantFunctionalData.objects.filter(
            saved_variants__guid__in=[
                COMPOUND_HET_1_GUID, COMPOUND_HET_2_GUID
            ])
        self.assertSetEqual(
            {"Biochemical Function", "Bonferroni corrected p-value"},
            {vt.functional_data_tag
             for vt in variant_functional_data})
        self.assertSetEqual({"An updated note", "0.05"},
                            {vt.metadata
                             for vt in variant_functional_data})
예제 #29
0
    def test_update_individual_hpo_terms(self):
        edit_individuals_url = reverse(update_individual_hpo_terms,
                                       args=[INDIVIDUAL_UPDATE_GUID])
        _check_login(self, edit_individuals_url)

        response = self.client.post(edit_individuals_url,
                                    content_type='application/json',
                                    data=json.dumps(INDIVIDUAL_UPDATE_DATA))

        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertListEqual(response_json.keys(), [INDIVIDUAL_UPDATE_GUID])
        self.assertEqual(response_json[INDIVIDUAL_UPDATE_GUID]['displayName'],
                         'NA20870')
        self.assertListEqual(
            response_json[INDIVIDUAL_UPDATE_GUID]['features'], [
                {
                    'id': 'HP:0002011',
                    'category': 'HP:0000707',
                    'label':
                    'Morphological abnormality of the central nervous system',
                    'qualifiers': [{
                        'type': 'onset',
                        'label': 'congenital'
                    }],
                },
                {
                    'id': 'HP:0011675',
                    'category': 'HP:0001626',
                    'label': 'Arrhythmia',
                    'notes': 'A new term'
                },
            ])
        self.assertListEqual(
            response_json[INDIVIDUAL_UPDATE_GUID]['absentNonstandardFeatures'],
            [{
                'id': 'Some new feature',
                'notes': 'No term for this'
            }])
        self.assertIsNone(
            response_json[INDIVIDUAL_UPDATE_GUID]['absentFeatures'])
        self.assertIsNone(
            response_json[INDIVIDUAL_UPDATE_GUID]['nonstandardFeatures'])

        self.assertListEqual(
            Individual.objects.get(guid=INDIVIDUAL_UPDATE_GUID).features, [
                {
                    'id': 'HP:0002011',
                    'qualifiers': [{
                        'type': 'onset',
                        'label': 'congenital'
                    }]
                },
                {
                    'id': 'HP:0011675',
                    'notes': 'A new term'
                },
            ])
예제 #30
0
    def test_project_page_data(self):
        url = reverse(project_page_data, args=[PROJECT_GUID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        response_json = response.json()
        self.assertSetEqual(
            set(response_json.keys()),
            {'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid', 'locusListsByGuid', 'analysisGroupsByGuid'}
        )
        self.assertSetEqual(
            set(response_json['projectsByGuid'][PROJECT_GUID]['variantTagTypes'][0].keys()),
            {'variantTagTypeGuid', 'name', 'category', 'description', 'color', 'order', 'is_built_in', 'numTags',
             'numTagsPerFamily'}
        )
        self.assertSetEqual(
            set(response_json['projectsByGuid'][PROJECT_GUID].keys()),
            {'collaborators', 'locusListGuids', 'variantTagTypes', 'variantFunctionalTagTypes', 'hasGeneSearch',
             'detailsLoaded', 'projectGuid', 'projectCategoryGuids', 'canEdit', 'name', 'description', 'createdDate',
             'lastModifiedDate', 'isPhenotipsEnabled', 'phenotipsUserId', 'deprecatedProjectId', 'hasNewSearch',
             'lastAccessedDate', 'isMmeEnabled', 'mmePrimaryDataOwner', 'mmeContactInstitution', 'mmeContactUrl',
             'genomeVersion', 'discoveryTags'}
        )
        self.assertEqual(
            response_json['projectsByGuid'][PROJECT_GUID]['lastAccessedDate'][:10], datetime.today().strftime('%Y-%m-%d')
        )
        self.assertSetEqual(
            set(response_json['familiesByGuid'].values()[0].keys()),
            {'projectGuid', 'familyGuid', 'individualGuids', 'analysedBy', 'pedigreeImage', 'familyId', 'displayName',
             'description', 'analysisNotes', 'analysisSummary', 'causalInheritanceMode', 'analysisStatus',
             'pedigreeImage', 'internalAnalysisStatus', 'internalCaseReviewNotes', 'internalCaseReviewSummary',
             'createdDate', 'codedPhenotype', 'postDiscoveryOmimNumber', 'pubmedIds'}
        )
        self.assertSetEqual(
            set(response_json['individualsByGuid'].values()[0].keys()),
            {'projectGuid', 'familyGuid', 'individualGuid', 'sampleGuids', 'caseReviewStatusLastModifiedBy',
             'phenotipsData', 'individualId', 'paternalId', 'maternalId', 'sex', 'affected', 'displayName', 'notes',
             'phenotipsPatientId', 'phenotipsData', 'createdDate', 'lastModifiedDate', 'caseReviewStatus',
             'caseReviewDiscussion', 'caseReviewStatusLastModifiedDate', 'caseReviewStatusLastModifiedBy',
             'paternalGuid', 'maternalGuid', 'mmeSubmittedDate', 'mmeDeletedDate'}
        )
        self.assertSetEqual(
            set(response_json['samplesByGuid'].values()[0].keys()),
            {'projectGuid', 'individualGuid', 'sampleGuid', 'createdDate', 'sampleType', 'datasetType', 'sampleId',
             'sampleStatus',  'loadedDate', 'datasetFilePath', 'elasticsearchIndex'}
        )
        self.assertSetEqual(
            set(response_json['locusListsByGuid'].values()[0].keys()),
            {'locusListGuid', 'description', 'lastModifiedDate', 'numEntries', 'isPublic', 'createdBy', 'createdDate',
             'canEdit', 'name'}
        )
        self.assertSetEqual(
            set(response_json['analysisGroupsByGuid'].values()[0].keys()),
            {'analysisGroupGuid', 'description', 'name', 'projectGuid', 'familyGuids'}
        )
예제 #31
0
    def test_export_case_review_individuals(self):
        url = reverse(export_case_review_individuals, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.get(url + "?file_format=tsv")
        self.assertEqual(response.status_code, 200)

        response = self.client.get(url + "?file_format=xls")
        self.assertEqual(response.status_code, 200)
예제 #32
0
    def test_project_page_data(self):
        url = reverse(project_page_data, args=[PROJECT_GUID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        response_json = response.json()
        self.assertSetEqual(
            set(response_json.keys()),
            {'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid', 'locusListsByGuid', 'analysisGroupsByGuid'}
        )
        self.assertSetEqual(
            set(response_json['projectsByGuid'][PROJECT_GUID]['variantTagTypes'][0].keys()),
            {'variantTagTypeGuid', 'name', 'category', 'description', 'color', 'order', 'numTags', 'numTagsPerFamily'}
        )
        self.assertSetEqual(
            set(response_json['projectsByGuid'][PROJECT_GUID].keys()),
            {'collaborators', 'locusListGuids', 'variantTagTypes', 'variantFunctionalTagTypes',
             'detailsLoaded', 'projectGuid', 'projectCategoryGuids', 'canEdit', 'name', 'description', 'createdDate',
             'lastModifiedDate', 'isPhenotipsEnabled', 'phenotipsUserId', 'deprecatedProjectId', 'hasNewSearch',
             'lastAccessedDate', 'isMmeEnabled', 'mmePrimaryDataOwner', 'mmeContactInstitution', 'mmeContactUrl',
             'genomeVersion', 'discoveryTags'}
        )
        self.assertEqual(
            response_json['projectsByGuid'][PROJECT_GUID]['lastAccessedDate'][:10], datetime.today().strftime('%Y-%m-%d')
        )
        self.assertSetEqual(
            set(response_json['familiesByGuid'].values()[0].keys()),
            {'projectGuid', 'familyGuid', 'individualGuids', 'analysedBy', 'pedigreeImage', 'familyId', 'displayName',
             'description', 'analysisNotes', 'analysisSummary', 'causalInheritanceMode', 'analysisStatus',
             'pedigreeImage', 'internalAnalysisStatus', 'internalCaseReviewNotes', 'internalCaseReviewSummary',
             'createdDate', 'codedPhenotype', 'postDiscoveryOmimNumber', 'pubmedIds', 'assignedAnalyst'}
        )
        self.assertSetEqual(
            set(response_json['individualsByGuid'].values()[0].keys()),
            {'projectGuid', 'familyGuid', 'individualGuid', 'sampleGuids', 'caseReviewStatusLastModifiedBy',
             'phenotipsData', 'individualId', 'paternalId', 'maternalId', 'sex', 'affected', 'displayName', 'notes',
             'phenotipsPatientId', 'phenotipsData', 'createdDate', 'lastModifiedDate', 'caseReviewStatus',
             'caseReviewDiscussion', 'caseReviewStatusLastModifiedDate', 'caseReviewStatusLastModifiedBy',
             'paternalGuid', 'maternalGuid', 'mmeSubmittedDate', 'mmeDeletedDate', 'popPlatformFilters', 'filterFlags',
             'population'}
        )
        self.assertSetEqual(
            set(response_json['samplesByGuid'].values()[0].keys()),
            {'projectGuid', 'individualGuid', 'sampleGuid', 'createdDate', 'sampleType', 'datasetType', 'sampleId',
             'sampleStatus',  'loadedDate', 'datasetFilePath', 'elasticsearchIndex'}
        )
        self.assertSetEqual(
            set(response_json['locusListsByGuid'].values()[0].keys()),
            {'locusListGuid', 'description', 'lastModifiedDate', 'numEntries', 'isPublic', 'createdBy', 'createdDate',
             'canEdit', 'name'}
        )
        self.assertSetEqual(
            set(response_json['analysisGroupsByGuid'].values()[0].keys()),
            {'analysisGroupGuid', 'description', 'name', 'projectGuid', 'familyGuids'}
        )
예제 #33
0
    def test_export_tables(self):
        url = reverse(export_project_individuals_handler, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.get(url+"?file_format=tsv")
        self.assertEqual(response.status_code, 200)

        response = self.client.get(url+"?file_format=xls")
        self.assertEqual(response.status_code, 200)
예제 #34
0
    def test_export_tables(self):
        url = reverse(export_project_individuals_handler, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.get(url + "?file_format=tsv")
        self.assertEqual(response.status_code, 200)

        response = self.client.get(url + "?file_format=xls")
        self.assertEqual(response.status_code, 200)
예제 #35
0
    def test_export_projects_table(self):
        url = reverse(export_projects_table_handler)

        _check_login(self, url)

        response = self.client.get(url+"?file_format=tsv")
        self.assertEqual(response.status_code, 200)

        response = self.client.get(url+"?file_format=xls")
        self.assertEqual(response.status_code, 200)
예제 #36
0
    def test_project_categories_api(self):
        url = reverse(awesomebar_autocomplete_handler)
        _check_login(self, url)

        #self.assertRaisesRegexp(ValueError, "missing", lambda:
        #    self.client.get(url)
        #)

        response = self.client.get(url+"?q=T")
        self.assertEqual(response.status_code, 200)
예제 #37
0
    def test_create_saved_variant(self):
        create_saved_variant_url = reverse(create_saved_variant_handler)
        _check_login(self, create_saved_variant_url)

        variant_json = {
            'alt': 'A',
            'chrom': '2',
            'genotypes': {},
            'genomeVersion': '37',
            'mainTranscript': {},
            'originalAltAlleles': ['A'],
            'populations': {'callset': {'ac': 2, 'af': 0.063, 'an': 32}},
            'pos': 61413835,
            'predictions': {'cadd': 21.9},
            'ref': 'AAAG',
            'transcripts': {},
            'xpos': 2061413835,
            'projectGuid': 'R0001_1kg',
            'familyGuids': ['F000001_1'],
            'variantId': '2-61413835-AAAG-A',
        }

        request_body = {
            'searchHash': 'd380ed0fd28c3127d07a64ea2ba907d7',
            'familyGuid': 'F000001_1',
            'tags': [{'name': 'Review'}],
            'notes': [],
            'functionalData': [],
        }
        request_body.update(variant_json)

        response = self.client.post(create_saved_variant_url, content_type='application/json', data=json.dumps(request_body))
        self.assertEqual(response.status_code, 200)

        self.assertEqual(len(response.json()['savedVariantsByGuid']), 1)
        variant_guid = response.json()['savedVariantsByGuid'].keys()[0]

        saved_variant = SavedVariant.objects.get(guid=variant_guid, family__guid='F000001_1')
        self.assertDictEqual(variant_json, json.loads(saved_variant.saved_variant_json))

        variant_json.update({
            'variantId': variant_guid,
            'variantGuid': variant_guid,
            'notes': [],
            'functionalData': [],
        })
        response_variant_json = response.json()['savedVariantsByGuid'][variant_guid]
        tags = response_variant_json.pop('tags')
        self.assertDictEqual(variant_json, response_variant_json)

        self.assertListEqual(["Review"], [vt['name'] for vt in tags])
        self.assertListEqual(["Review"], [vt.variant_tag_type.name for vt in VariantTag.objects.filter(saved_variant__guid=variant_guid)])
예제 #38
0
    def test_gene_info(self):
        url = reverse(gene_info, args=[GENE_ID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        gene = response.json()['genesById'][GENE_ID]
        self.assertSetEqual(set(gene.keys()), {
            'chromGrch37', 'chromGrch38', 'codingRegionSizeGrch37', 'codingRegionSizeGrch38', 'constraints',
            'diseaseDesc', 'endGrch37', 'endGrch38', 'functionDesc', 'gencodeGeneType', 'geneId', 'geneSymbol',
            'omimPhenotypes', 'mimNumber', 'startGrch37', 'startGrch38', 'notes', 'expression', 'mgiMarkerId',
        })
예제 #39
0
    def test_create_update_and_delete_project(self):
        create_project_url = reverse(create_project_handler)
        _check_login(self, create_project_url)

        # check validation of bad requests
        response = self.client.post(create_project_url, content_type='application/json', data=json.dumps({'bad_json': None}))
        self.assertEqual(response.status_code, 400)

        response = self.client.post(create_project_url, content_type='application/json', data=json.dumps({'form': {'missing_name': True}}))
        self.assertEqual(response.status_code, 400)

        # send valid request to create project
        response = self.client.post(create_project_url, content_type='application/json', data=json.dumps(
            {'name': 'new_project', 'description': 'new project description', 'genomeVersion': '38'}
        ))
        self.assertEqual(response.status_code, 200)

        # check that project was created
        new_project = Project.objects.filter(name='new_project')
        self.assertEqual(len(new_project), 1)
        self.assertEqual(new_project[0].description, 'new project description')
        self.assertEqual(new_project[0].genome_version, '38')

        project_guid = new_project[0].guid
        self.assertSetEqual(set(response.json()['projectsByGuid'].keys()), {project_guid})

        # update the project
        update_project_url = reverse(update_project_handler, args=[project_guid])
        response = self.client.post(update_project_url, content_type='application/json', data=json.dumps(
            {'description': 'updated project description'}
        ))
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json()['projectsByGuid'][project_guid]['description'], 'updated project description')
        self.assertEqual(Project.objects.get(guid=project_guid).description, 'updated project description')

        # genome version should not update
        response = self.client.post(update_project_url, content_type='application/json', data=json.dumps(
            {'genomeVersion': '37'}
        ))
        self.assertEqual(response.json()['projectsByGuid'][project_guid]['genomeVersion'], '38')
        self.assertEqual(Project.objects.get(guid=project_guid).genome_version, '38')

        # delete the project
        delete_project_url = reverse(delete_project_handler, args=[project_guid])
        response = self.client.post(delete_project_url, content_type='application/json')

        self.assertEqual(response.status_code, 200)

        # check that project was deleted
        new_project = Project.objects.filter(name='new_project')
        self.assertEqual(len(new_project), 0)
예제 #40
0
    def test_create_update_and_delete_gene_note(self):
        add_or_edit_url = reverse(add_or_edit_gene_note)
        delete_url = reverse(delete_gene_note, args=[1])
        _check_login(self, add_or_edit_url)

        # check validation of bad requests
        response = self.client.get(add_or_edit_url)
        self.assertTrue(response.json()['is_error'])

        response = self.client.get(add_or_edit_url, {'gene_id': 'ENSG00000008735', 'note_text': 'test note', 'note_id': 1})
        self.assertTrue(response.json()['is_error'])

        response = self.client.get(delete_url)
        self.assertTrue(response.json()['is_error'])

        # check that create works
        response = self.client.get(add_or_edit_url, {'gene_id': 'ENSG00000008735', 'note_text': 'test note'})

        self.assertEqual(response.status_code, 200)
        self.assertFalse(response.json()['is_error'])

        gene_notes = GeneNote.objects.all()
        self.assertEqual(len(gene_notes), 1)
        self.assertEqual(gene_notes[0].note, 'test note')
        self.assertEqual(gene_notes[0].gene_id, 'ENSG00000008735')
        self.assertEqual(gene_notes[0].user.username, 'test_user')
        initial_date_saved = gene_notes[0].date_saved

        # check that edit works
        response = self.client.get(add_or_edit_url, {'gene_id': 'ENSG00000008735', 'note_text': 'edited test note', 'note_id': 1})

        self.assertEqual(response.status_code, 200)
        self.assertFalse(response.json()['is_error'])

        gene_notes = GeneNote.objects.all()
        self.assertEqual(len(gene_notes), 1)
        self.assertEqual(gene_notes[0].note, 'edited test note')
        self.assertGreater(gene_notes[0].date_saved, initial_date_saved)

        # check that edit does not change the gene
        response = self.client.get(add_or_edit_url, {'gene_id': 'ENSG00000000001', 'note_text': 'test note', 'note_id': 1})
        self.assertEqual(response.json()['note']['gene_id'], 'ENSG00000008735')

        # check that delete works
        response = self.client.get(delete_url)

        self.assertEqual(response.status_code, 200)
        self.assertFalse(response.json()['is_error'])

        gene_notes = GeneNote.objects.all()
        self.assertEqual(len(gene_notes), 0)
예제 #41
0
    def test_update_saved_variant_json(self, mock_retrieve_variants):
        mock_retrieve_variants.side_effect = lambda project, variant_tuples: \
            [{'xpos': var[0], 'ref': var[1], 'alt': var[2], 'familyGuids': [var[3].guid]} for var in variant_tuples]

        url = reverse(update_saved_variant_json, args=['R0001_1kg'])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        self.assertSetEqual(
            set(response.json().keys()),
            {'SV0000002_1248367227_r0390_100', 'SV0000001_2103343353_r0390_100', 'SV0000003_2246859832_r0390_100'}
        )
예제 #42
0
    def test_locus_lists(self):
        url = reverse(locus_lists)
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        locus_lists_dict = response.json()['locusListsByGuid']
        self.assertSetEqual(set(locus_lists_dict.keys()), {'LL00049_pid_genes_autosomal_do', 'LL00005_retina_proteome'})

        locus_list = locus_lists_dict[LOCUS_LIST_GUID]
        self.assertSetEqual(
            set(locus_list.keys()),
            {'locusListGuid', 'description', 'lastModifiedDate', 'numEntries', 'isPublic', 'createdBy', 'createdDate',
             'canEdit', 'name'}
        )
예제 #43
0
    def test_search_context(self):
        search_context_url = reverse(search_context_handler)
        _check_login(self, search_context_url)

        response = self.client.get('{}?foo=bar'.format(search_context_url))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'Invalid query params: {"foo": "bar"}')

        response = self.client.get('{}?projectGuid={}'.format(search_context_url, PROJECT_GUID))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', }
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])

        response = self.client.get('{}?familyGuid=F000001_1'.format(search_context_url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', }
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])

        response = self.client.get('{}?analysisGroupGuid=AG0000183_test_group'.format(search_context_url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json),
            {'savedSearchesByGuid', 'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid',
             'locusListsByGuid', 'analysisGroupsByGuid', }
        )
        self.assertEqual(len(response_json['savedSearchesByGuid']), 3)
        self.assertTrue(PROJECT_GUID in response_json['projectsByGuid'])
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
        self.assertTrue('AG0000183_test_group' in response_json['analysisGroupsByGuid'])
예제 #44
0
    def test_empty_project_page_data(self):
        url = reverse(project_page_data, args=[EMPTY_PROJECT_GUID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        response_json = response.json()
        self.assertSetEqual(
            set(response_json.keys()),
            {'projectsByGuid', 'familiesByGuid', 'individualsByGuid', 'samplesByGuid', 'locusListsByGuid', 'analysisGroupsByGuid'}
        )
        self.assertListEqual(response_json['projectsByGuid'].keys(), [EMPTY_PROJECT_GUID])
        self.assertDictEqual(response_json['familiesByGuid'], {})
        self.assertDictEqual(response_json['individualsByGuid'], {})
        self.assertDictEqual(response_json['samplesByGuid'], {})
        self.assertDictEqual(response_json['analysisGroupsByGuid'], {})
예제 #45
0
    def test_create_update_and_delete_variant_note(self):
        create_variant_note_url = reverse(create_variant_note_handler, args=[VARIANT_GUID])
        _check_login(self, create_variant_note_url)

        # send valid request to create variant_note
        response = self.client.post(create_variant_note_url, content_type='application/json', data=json.dumps(
            {'note': 'new_variant_note', 'submitToClinvar': True}
        ))

        self.assertEqual(response.status_code, 200)
        new_note_response = response.json()['savedVariantsByGuid'][VARIANT_GUID]['notes'][0]
        self.assertEqual(new_note_response['note'], 'new_variant_note')
        self.assertEqual(new_note_response['submitToClinvar'], True)

        new_variant_note = VariantNote.objects.filter(guid=new_note_response['noteGuid']).first()
        self.assertIsNotNone(new_variant_note)
        self.assertEqual(new_variant_note.note, new_note_response['note'])
        self.assertEqual(new_variant_note.submit_to_clinvar, new_note_response['submitToClinvar'])

        # update the variant_note
        update_variant_note_url = reverse(update_variant_note_handler, args=[VARIANT_GUID, new_variant_note.guid])
        response = self.client.post(update_variant_note_url, content_type='application/json',  data=json.dumps(
            {'note': 'updated_variant_note', 'submitToClinvar': False}))

        self.assertEqual(response.status_code, 200)

        updated_note_response = response.json()['savedVariantsByGuid'][VARIANT_GUID]['notes'][0]
        self.assertEqual(updated_note_response['note'], 'updated_variant_note')
        self.assertEqual(updated_note_response['submitToClinvar'], False)

        updated_variant_note = VariantNote.objects.filter(guid=updated_note_response['noteGuid']).first()
        self.assertIsNotNone(updated_variant_note)
        self.assertEqual(updated_variant_note.note, updated_note_response['note'])
        self.assertEqual(updated_variant_note.submit_to_clinvar, updated_note_response['submitToClinvar'])

        # delete the variant_note
        delete_variant_note_url = reverse(delete_variant_note_handler, args=[VARIANT_GUID, updated_variant_note.guid])
        response = self.client.post(delete_variant_note_url, content_type='application/json')

        self.assertEqual(response.status_code, 200)

        # check that variant_note was deleted
        new_variant_note = VariantNote.objects.filter(guid=updated_note_response['noteGuid'])
        self.assertEqual(len(new_variant_note), 0)
예제 #46
0
    def test_add_and_remove_project_locus_lists(self):
        project = Project.objects.get(guid=PROJECT_GUID)
        self.assertListEqual(list(get_project_locus_list_models(project)), [])

        # add a locus list
        url = reverse(add_project_locus_lists, args=[PROJECT_GUID])
        _check_login(self, url)

        response = self.client.post(url, content_type='application/json', data=json.dumps({'locusListGuids': [LOCUS_LIST_GUID]}))
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(response.json()['locusListGuids'], [LOCUS_LIST_GUID])
        self.assertListEqual(list(get_project_locus_list_models(project)), [LocusList.objects.get(guid=LOCUS_LIST_GUID)])

        # remove a locus list
        url = reverse(delete_project_locus_lists, args=[PROJECT_GUID])
        response = self.client.post(url, content_type='application/json', data=json.dumps({'locusListGuids': [LOCUS_LIST_GUID]}))
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(response.json()['locusListGuids'], [])
        self.assertListEqual(list(get_project_locus_list_models(project)), [])
예제 #47
0
    def test_query_single_variant(self, mock_get_variant):
        mock_get_variant.return_value = VARIANTS[0]

        url = reverse(query_single_variant_handler, args=['21-3343353-GAGA-G'])
        _check_login(self, url)

        response = self.client.get('{}?familyGuid=F000001_1'.format(url))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(
            set(response_json.keys()),
            {'searchedVariants', 'savedVariantsByGuid', 'genesById', 'projectsByGuid', 'familiesByGuid',
             'individualsByGuid', 'samplesByGuid', 'locusListsByGuid', 'analysisGroupsByGuid',}
        )

        self.assertListEqual(response_json['searchedVariants'], EXPECTED_VARIANTS[:1])
        self.assertSetEqual(set(response_json['savedVariantsByGuid'].keys()), {'SV0000001_2103343353_r0390_100'})
        self.assertSetEqual(set(response_json['genesById'].keys()), {'ENSG00000227232', 'ENSG00000268903'})
        self.assertTrue('F000001_1' in response_json['familiesByGuid'])
예제 #48
0
    def test_locus_list_info(self):
        url = reverse(locus_list_info, args=[LOCUS_LIST_GUID])
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        response_json = response.json()
        locus_lists_dict = response_json['locusListsByGuid']
        self.assertListEqual(locus_lists_dict.keys(), [LOCUS_LIST_GUID])

        locus_list = locus_lists_dict[LOCUS_LIST_GUID]
        self.assertSetEqual(
            set(locus_list.keys()),
            {'locusListGuid', 'description', 'lastModifiedDate', 'numEntries', 'isPublic', 'createdBy', 'createdDate',
             'canEdit', 'name', 'items', 'intervalGenomeVersion'}
        )
        self.assertSetEqual(
            {item['geneId'] for item in locus_list['items'] if item.get('geneId')},
            set(response_json['genesById'].keys())
        )
예제 #49
0
    def test_create_update_and_delete_gene_note(self):
        create_gene_note_url = reverse(create_gene_note_handler, args=[GENE_ID])
        _check_login(self, create_gene_note_url)

        # send valid request to create gene_note
        response = self.client.post(create_gene_note_url, content_type='application/json', data=json.dumps(
            {'note': 'new_gene_note'}
        ))

        self.assertEqual(response.status_code, 200)
        new_note_response = response.json()['genesById'][GENE_ID]['notes'][0]
        self.assertEqual(new_note_response['note'], 'new_gene_note')

        new_gene_note = GeneNote.objects.filter(guid=new_note_response['noteGuid']).first()
        self.assertIsNotNone(new_gene_note)
        self.assertEqual(new_gene_note.note, new_note_response['note'])

        # update the gene_note
        update_gene_note_url = reverse(update_gene_note_handler, args=[GENE_ID, new_gene_note.guid])
        response = self.client.post(update_gene_note_url, content_type='application/json',  data=json.dumps(
            {'note': 'updated_gene_note'}))

        self.assertEqual(response.status_code, 200)

        updated_note_response = response.json()['genesById'][GENE_ID]['notes'][0]
        self.assertEqual(updated_note_response['note'], 'updated_gene_note')

        updated_gene_note = GeneNote.objects.filter(guid=updated_note_response['noteGuid']).first()
        self.assertIsNotNone(updated_gene_note)
        self.assertEqual(updated_gene_note.note, updated_note_response['note'])

        # delete the gene_note
        delete_gene_note_url = reverse(delete_gene_note_handler, args=[GENE_ID, updated_gene_note.guid])
        response = self.client.post(delete_gene_note_url, content_type='application/json')

        self.assertEqual(response.status_code, 200)

        # check that gene_note was deleted
        new_gene_note = GeneNote.objects.filter(guid=updated_note_response['noteGuid'])
        self.assertEqual(len(new_gene_note), 0)
예제 #50
0
    def test_create_staff_user(self, mock_send_mail):
        create_url = reverse(create_staff_user)
        _check_login(self, create_url)

        # send invalid request
        response = self.client.post(create_url, content_type='application/json', data=json.dumps({}))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'Email is required')

        # create
        response = self.client.post(create_url, content_type='application/json', data=json.dumps({
            'email': '*****@*****.**', 'firstName': 'Test', 'lastName': 'Staff'}))
        self.assertEqual(response.status_code, 200)
        user = User.objects.get(email='*****@*****.**')
        self.assertTrue(user.is_staff)

        expected_email_content = """
    Hi there Test Staff--
    
    [email protected] has added you as a collaborator in seqr.  
    
    Please click this link to set up your account:
    /users/set_password/{password_token}
    
    Thanks!
    """.format(password_token=user.password)
        mock_send_mail.assert_called_with(
            'Set up your seqr account',
            expected_email_content,
            None,
            ['*****@*****.**'],
            fail_silently=False,
        )

        # calling create again fails
        response = self.client.post(create_url, content_type='application/json', data=json.dumps({
            'email': '*****@*****.**'}))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'This user already exists')
예제 #51
0
    def test_edit_individuals(self, mock_find_xbrowse_model):
        mock_find_xbrowse_model.return_value.has_elasticsearch_index.return_value = False

        edit_individuals_url = reverse(edit_individuals_handler, args=[PROJECT_GUID])
        _check_login(self, edit_individuals_url)

        # send invalid requests
        response = self.client.post(edit_individuals_url, content_type='application/json', data=json.dumps({
            'individuals': [INDIVIDUAL_IDS_UPDATE_DATA]
        }))
        self.assertEqual(response.status_code, 400)
        self.assertListEqual(response.json()['errors'], ["NA20870 is the mother of NA19678_1 but doesn't have a separate record in the table"])

        response = self.client.post(edit_individuals_url, content_type='application/json', data=json.dumps({
            'individuals': [INDIVIDUAL_IDS_UPDATE_DATA, INDIVIDUAL_FAMILY_UPDATE_DATA]
        }))
        self.assertEqual(response.status_code, 400)
        self.assertListEqual(response.json()['errors'], ['Editing individual_id is disabled for projects which still use the mongo datastore'])

        # send valid request
        mock_find_xbrowse_model.return_value.has_elasticsearch_index.return_value = True
        response = self.client.post(edit_individuals_url, content_type='application/json', data=json.dumps({
            'individuals': [INDIVIDUAL_IDS_UPDATE_DATA, INDIVIDUAL_FAMILY_UPDATE_DATA]
        }))
        self.assertEqual(response.status_code, 200)
        response_json = response.json()

        self.assertSetEqual({'F000001_1', 'F000003_3'}, set(response_json['familiesByGuid']))
        self.assertSetEqual({ID_UPDATE_GUID, FAMILY_UPDATE_GUID, CHILD_UPDATE_GUID, "I000003_na19679"},
                            set(response_json['familiesByGuid']['F000001_1']['individualGuids']))
        self.assertListEqual(response_json['familiesByGuid']['F000003_3']['individualGuids'], [])

        self.assertSetEqual({ID_UPDATE_GUID, FAMILY_UPDATE_GUID, CHILD_UPDATE_GUID}, set(response_json['individualsByGuid']))
        self.assertEqual(response_json['individualsByGuid'][ID_UPDATE_GUID]['individualId'], UPDATED_ID)
        self.assertEqual(response_json['individualsByGuid'][ID_UPDATE_GUID]['maternalId'], UPDATED_MATERNAL_ID)
        self.assertEqual(response_json['individualsByGuid'][CHILD_UPDATE_GUID]['paternalId'], UPDATED_ID)
예제 #52
0
    def test_phenotips_pdf(self):
        url = reverse(phenotips_pdf_handler, args=['R0001_1kg', 'I000001_na19675'])
        _check_login(self, url)

        response = self.client.post(url, content_type='application/json', data=json.dumps({'some_json': 'test'}))
        self.assertEqual(response.status_code, 200)
예제 #53
0
    def test_react_page(self):
        url = reverse(main_app)
        _check_login(self, url)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
예제 #54
0
    def test_search_individual_mme_matches(self, mock_post_to_slack):
        url = reverse(search_individual_mme_matches, args=[INDIVIDUAL_GUID])
        _check_login(self, url)

        responses.add(responses.POST, 'http://*****:*****@broadinstitute.org', 'name': 'Sam Baxter', 'institution': 'Broad Center for Mendelian Genomics'},
                    'species': 'NCBITaxon:9606',
                    'features': [
                        {'id': 'HP:0001252', 'label': 'Muscular hypotonia', 'observed': 'yes'},
                        {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                        {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                    ],
                    'genomicFeatures': [{
                        'gene': {'id': 'ENSG00000186092'},
                        'variant': {
                            'end': 77027548,
                            'start': 77027549,
                            'assembly': 'GRCh38',
                            'referenceName': '14',
                            'alternateBases': 'C',
                            'referenceBases': 'CCACT'
                        },
                        'zygosity': 1
                    }],
                },
                'phenotypes': [
                    {'id': 'HP:0001252', 'label': 'Muscular hypotonia', 'observed': 'yes'},
                    {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                ],
                'geneVariants': [{
                    'geneId': 'ENSG00000186092',
                    'alt': 'C',
                    'ref': 'CCACT',
                    'chrom': '14',
                    'pos': 77027549,
                    'genomeVersion': 'GRCh38',
                }],
            },
            'mmeSubmittedDate': '2018-05-23T09:07:49.719Z',
            'mmeDeletedDate': None,
        }})
        self.assertSetEqual(
            set(response_json['individualsByGuid'][INDIVIDUAL_GUID]['mmeResultGuids']),
            set(response_json['mmeResultsByGuid'].keys()))

        self.assertSetEqual(
            set(response_json['genesById'].keys()),
            {'ENSG00000186092', 'ENSG00000233750', 'ENSG00000223972'}
        )

        # Test proxy calls
        self.assertEqual(len(responses.calls), 3)
        expected_body = json.dumps({
            'patient': {
                'id': 'NA19675_1_01',
                'label': 'NA19675_1',
                'contact': {'href': 'mailto:[email protected]', 'name': 'Sam Baxter', 'institution': 'Broad Center for Mendelian Genomics'},
                'species': 'NCBITaxon:9606',
                'features': [
                    {'id': 'HP:0001252', 'observed': 'yes'},
                    {'id': 'HP:0001263', 'observed': 'no'},
                    {'id': 'HP:0012469', 'observed': 'yes'}
                ],
                'genomicFeatures': [{
                    'gene': {'id': 'ENSG00000186092'},
                    'variant': {
                        'end': 77027548, 'start': 77027549, 'assembly': 'GRCh38', 'referenceName': '14',
                        'alternateBases': 'C', 'referenceBases': 'CCACT',
                    },
                    'zygosity': 1
                }],
            }
        })
        self.assertEqual(responses.calls[1].request.url, 'http://localhost:9020/match')
        self.assertEqual(responses.calls[1].request.headers['X-Auth-Token'], 'abcd')
        self.assertEqual(responses.calls[1].request.headers['Accept'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[1].request.headers['Content-Type'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[1].request.body, expected_body)
        self.assertEqual(responses.calls[2].request.url, 'http://localhost:9020/match/external')
        self.assertEqual(responses.calls[2].request.headers['X-Auth-Token'], 'abcd')
        self.assertEqual(responses.calls[2].request.headers['Accept'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[2].request.headers['Content-Type'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[2].request.body, expected_body)


        # Test slack notification
        slack_message = u"""
    A search from a seqr user from project 1kg project n\xe5me with uni\xe7\xf8de individual NA19675_1 had the following new match(es):
    
     - From Reza Maroofian at institution St Georges, University of London with genes OR4F5 with phenotypes HP:0012469 (Infantile spasms).
    
    https://seqr.broadinstitute.org/project/R0001_1kg/family_page/F000001_1/matchmaker_exchange
    """
        mock_post_to_slack.assert_called_with('matchmaker_seqr_match', slack_message)

        # Test new result model created
        result_model = MatchmakerResult.objects.get(guid=new_result_guid)
        self.assertDictEqual(result_model.result_data, NEW_MATCH_JSON)
예제 #55
0
    def test_update_mme_submission(self):
        responses.add(responses.POST, 'http://*****:*****@broadinstitute.org', 'name': 'PI',
                            'institution': 'Broad Center for Mendelian Genomics'},
                'species': 'NCBITaxon:9606',
            },
            'phenotypes': [
                {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
            ],
            'geneVariants': [{
                'geneId': 'ENSG00000186092',
                'alt': 'C',
                'ref': 'CCACT',
                'chrom': '14',
                'pos': 77027549,
                'genomeVersion': 'GRCh38',
                'numAlt': 2,
            }],
        }))

        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(set(response_json.keys()), {'mmeResultsByGuid', 'individualsByGuid', 'genesById'})

        self.assertEqual(len(response_json['mmeResultsByGuid']), 1)
        self.assertDictEqual(response_json['mmeResultsByGuid'].values()[0], PARSED_NEW_MATCH_JSON)
        self.assertDictEqual(response_json['individualsByGuid'], {NO_SUBMISSION_INDIVIDUAL_GUID: {
            'mmeResultGuids': response_json['mmeResultsByGuid'].keys(),
            'mmeSubmittedData': {
                'patient': {
                    'id': 'HG00733',
                    'label': 'HG00733',
                    'contact': {'href': 'mailto:[email protected]', 'name': 'PI',
                                'institution': 'Broad Center for Mendelian Genomics'},
                    'species': 'NCBITaxon:9606',
                    'features': [
                        {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                    ],
                    'genomicFeatures': [{
                        'gene': {'id': 'ENSG00000186092'},
                        'variant': {
                            'start': 77027549,
                            'assembly': 'GRCh38',
                            'referenceName': '14',
                            'alternateBases': 'C',
                            'referenceBases': 'CCACT'
                        },
                        'zygosity': 0
                    }],
                },
                'phenotypes': [
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                ],
                'geneVariants': [{
                    'geneId': 'ENSG00000186092',
                    'alt': 'C',
                    'ref': 'CCACT',
                    'chrom': '14',
                    'pos': 77027549,
                    'genomeVersion': 'GRCh38',
                }],
            },
            'mmeSubmittedDate': mock.ANY,
            'mmeDeletedDate': None,
        }})
        self.assertEqual(
            response_json['individualsByGuid'][NO_SUBMISSION_INDIVIDUAL_GUID]['mmeSubmittedDate'][:10],
            datetime.today().strftime('%Y-%m-%d')
        )
        self.assertListEqual(response_json['genesById'].keys(), ['ENSG00000186092'])

        # Test proxy calls
        self.assertEqual(len(responses.calls), 4)
        expected_body = {
            'patient': {
                'id': 'HG00733',
                'label': 'HG00733',
                'contact': {'href': 'mailto:[email protected]', 'name': 'PI',
                            'institution': 'Broad Center for Mendelian Genomics'},
                'species': 'NCBITaxon:9606',
                'features': [
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                ],
                'genomicFeatures': [{
                    'gene': {'id': 'ENSG00000186092'},
                    'variant': {
                        'start': 77027549,
                        'assembly': 'GRCh38',
                        'referenceName': '14',
                        'alternateBases': 'C',
                        'referenceBases': 'CCACT'
                    },
                    'zygosity': 0
                }],
            }
        }
        self.assertEqual(responses.calls[1].request.url, 'http://*****:*****@broadinstitute.org', 'name': 'Test Name',
                            'institution': 'Broad Center for Mendelian Genomics'},
                'species': 'NCBITaxon:9606',
            },
            'phenotypes': [
                {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'},
                {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
            ],
        }))

        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(set(response_json.keys()), {'mmeResultsByGuid', 'individualsByGuid', 'genesById'})

        self.assertEqual(len(response_json['mmeResultsByGuid']), 1)
        self.assertDictEqual(response_json['mmeResultsByGuid'].values()[0], PARSED_NEW_MATCH_JSON)
        self.assertDictEqual(response_json['individualsByGuid'], {NO_SUBMISSION_INDIVIDUAL_GUID: {
            'mmeResultGuids': response_json['mmeResultsByGuid'].keys(),
            'mmeSubmittedData': {
                'patient': {
                    'id': 'HG00733',
                    'label': 'HG00733',
                    'contact': {'href': 'mailto:[email protected]', 'name': 'Test Name',
                                'institution': 'Broad Center for Mendelian Genomics'},
                    'species': 'NCBITaxon:9606',
                    'features': [
                        {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'},
                        {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                    ],
                    'genomicFeatures': [],
                },
                'phenotypes': [
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'},
                    {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                ],
                'geneVariants': [],
            },
            'mmeSubmittedDate': mock.ANY,
            'mmeDeletedDate': None,
        }})
        self.assertEqual(
            response_json['individualsByGuid'][NO_SUBMISSION_INDIVIDUAL_GUID]['mmeSubmittedDate'][:10],
            datetime.today().strftime('%Y-%m-%d')
        )
        self.assertListEqual(response_json['genesById'].keys(), ['ENSG00000186092'])

        # Test updates project MME contact
        project = Project.objects.get(family__individual__guid=NO_SUBMISSION_INDIVIDUAL_GUID)
        self.assertEqual(project.mme_primary_data_owner, 'PI,Test Name')
        self.assertEqual(project.mme_contact_url, 'mailto:[email protected],[email protected]')

        # Test proxy calls
        self.assertEqual(len(responses.calls), 7)
        expected_body = {
            'patient': {
                'id': 'HG00733',
                'label': 'HG00733',
                'contact': {'href': 'mailto:[email protected]', 'name': 'Test Name',
                            'institution': 'Broad Center for Mendelian Genomics'},
                'species': 'NCBITaxon:9606',
                'features': [
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'},
                    {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                ],
                'genomicFeatures': [],
            }
        }
        self.assertEqual(responses.calls[4].request.url, 'http://localhost:9020/patient/add')
        self.assertEqual(responses.calls[4].request.headers['X-Auth-Token'], 'abcd')
        self.assertEqual(responses.calls[4].request.headers['Accept'], 'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertEqual(responses.calls[4].request.headers['Content-Type'],
                         'application/vnd.ga4gh.matchmaker.v1.0+json')
        self.assertDictEqual(json.loads(responses.calls[4].request.body), expected_body)
        self.assertEqual(responses.calls[4].response.status_code, 409)
예제 #56
0
    def test_get_individual_mme_matches(self):
        url = reverse(get_individual_mme_matches, args=[INDIVIDUAL_GUID])
        _check_login(self, url)

        response = self.client.get(url)

        self.assertEqual(response.status_code, 200)
        response_json = response.json()
        self.assertSetEqual(set(response_json.keys()), {'mmeResultsByGuid', 'individualsByGuid', 'genesById'})

        self.assertSetEqual(
            set(response_json['mmeResultsByGuid'].keys()), {'MR0007228_VCGS_FAM50_156', RESULT_STATUS_GUID}
        )
        self.assertDictEqual(response_json['mmeResultsByGuid'][RESULT_STATUS_GUID], {
            'id': 'P0004515',
            'score': 0.5706712016939723,
            'patient': {
                'genomicFeatures': [
                    {'gene': {'id': 'OR4F5'}},
                    {'gene': {'id': 'CICP27'}},
                    {'gene': {'id': 'DDX11L1'}},
                ],
                'contact': {
                    'href': 'mailto:[email protected],[email protected]',
                    'name': 'Baylor UDN Clinical Site'
                },
                'id': 'P0004515',
                'features': [
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'},
                    {'id': 'HP:0003273', 'label': 'Hip contracture', 'observed': 'no'},
                ],
            },
            'phenotypes': [
                {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'},
                {'id': 'HP:0003273', 'label': 'Hip contracture', 'observed': 'no'},
            ],
            'geneVariants': [
                {'geneId': 'ENSG00000186092'},
                {'geneId': 'ENSG00000233750'},
                {'geneId': 'ENSG00000223972'},
            ],
            'matchStatus': {
                'matchmakerResultGuid': RESULT_STATUS_GUID,
                'comments': '',
                'weContacted': False,
                'hostContacted': True,
                'deemedIrrelevant': True,
                'flagForAnalysis': False,
                'createdDate': '2019-02-12T18:43:56.358Z',
            },
        })
        self.assertDictEqual(response_json['individualsByGuid'], {INDIVIDUAL_GUID: {
            'mmeResultGuids': mock.ANY,
            'mmeSubmittedData': {
                'patient': {
                    'id': 'NA19675_1_01',
                    'label': 'NA19675_1',
                    'contact': {'href': 'mailto:[email protected]', 'name': 'Sam Baxter', 'institution': 'Broad Center for Mendelian Genomics'},
                    'species': 'NCBITaxon:9606',
                    'features': [
                        {'id': 'HP:0001252', 'label': 'Muscular hypotonia', 'observed': 'yes'},
                        {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                        {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                    ],
                    'genomicFeatures': [{
                        'gene': {'id': 'ENSG00000186092'},
                        'variant': {
                            'end': 77027548,
                            'start': 77027549,
                            'assembly': 'GRCh38',
                            'referenceName': '14',
                            'alternateBases': 'C',
                            'referenceBases': 'CCACT'
                        },
                        'zygosity': 1
                    }],
                },
                'phenotypes': [
                    {'id': 'HP:0001252', 'label': 'Muscular hypotonia', 'observed': 'yes'},
                    {'id': 'HP:0001263', 'label': 'Global developmental delay', 'observed': 'no'},
                    {'id': 'HP:0012469', 'label': 'Infantile spasms', 'observed': 'yes'}
                ],
                'geneVariants': [{
                    'geneId': 'ENSG00000186092',
                    'alt': 'C',
                    'ref': 'CCACT',
                    'chrom': '14',
                    'pos': 77027549,
                    'genomeVersion': 'GRCh38',
                }],
            },
            'mmeSubmittedDate': '2018-05-23T09:07:49.719Z',
            'mmeDeletedDate': None,
        }})
        self.assertSetEqual(
            set(response_json['individualsByGuid'][INDIVIDUAL_GUID]['mmeResultGuids']),
            {'MR0007228_VCGS_FAM50_156', RESULT_STATUS_GUID})

        self.assertSetEqual(
            set(response_json['genesById'].keys()),
            {'ENSG00000186092', 'ENSG00000233750', 'ENSG00000223972'}
        )
예제 #57
0
    def test_create_update_and_delete_locus_list(self):
        create_locus_list_url = reverse(create_locus_list_handler)
        _check_login(self, create_locus_list_url)

        # send invalid requests to create locus_list
        response = self.client.post(create_locus_list_url, content_type='application/json', data=json.dumps({}))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, '"Name" is required')

        response = self.client.post(create_locus_list_url, content_type='application/json', data=json.dumps({
            'name': 'new_locus_list', 'isPublic': True, 'rawItems': 'DDX11L1, foo  10:10-1  chr100:1-10 \n2:1234-5678',
        }))
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.reason_phrase, 'This list contains invalid genes/ intervals. Update them, or select the "Ignore invalid genes and intervals" checkbox to ignore.')
        self.assertListEqual(response.json()['invalidLocusListItems'], ['chr10:10-1', 'chr100:1-10', 'foo'])

        # send valid request to create locus_list
        response = self.client.post(create_locus_list_url, content_type='application/json', data=json.dumps({
            'name': 'new_locus_list', 'isPublic': True, 'ignoreInvalidItems': True,
            'rawItems': 'DDX11L1, foo   chr100:1-1 \nchr2:1234-5678',
        }))
        self.assertEqual(response.status_code, 200)
        new_locus_list_response = response.json()
        self.assertEqual(len(new_locus_list_response['locusListsByGuid']), 1)
        new_locus_list = new_locus_list_response['locusListsByGuid'].values()[0]
        self.assertEqual(new_locus_list['name'], 'new_locus_list')
        self.assertEqual(new_locus_list['isPublic'], True)

        self.assertSetEqual(
            {item['geneId'] for item in new_locus_list['items'] if item.get('geneId')},
            set(new_locus_list_response['genesById'].keys())
        )
        self.assertListEqual(
            new_locus_list['items'],
            [
                {'geneId': 'ENSG00000223972'},
                {'chrom': '2', 'start': 1234, 'end': 5678, 'genomeVersion': '37', 'locusListIntervalGuid': mock.ANY}
            ]
        )

        guid = new_locus_list['locusListGuid']
        gene_id = new_locus_list['items'][0]['geneId']
        new_locus_list_model = LocusList.objects.filter(guid=guid).first()
        self.assertIsNotNone(new_locus_list_model)
        self.assertEqual(new_locus_list_model.name, new_locus_list['name'])
        self.assertEqual(new_locus_list_model.is_public, new_locus_list['isPublic'])

        self.assertEqual(new_locus_list_model.locuslistgene_set.count(), 1)
        self.assertEqual(new_locus_list_model.locuslistgene_set.first().gene_id, gene_id)
        self.assertEqual(new_locus_list_model.locuslistinterval_set.count(), 1)
        new_interval = new_locus_list_model.locuslistinterval_set.first()
        self.assertEqual(new_interval.chrom, '2')
        self.assertEqual(new_interval.start, 1234)

        # update the locus_list
        update_locus_list_url = reverse(update_locus_list_handler, args=[guid])
        response = self.client.post(update_locus_list_url, content_type='application/json',  data=json.dumps(
            {'name': 'updated_locus_list', 'isPublic': False, 'rawItems': 'DDX11L1 FAM138A'}))

        self.assertEqual(response.status_code, 200)
        updated_locus_list_response = response.json()
        self.assertEqual(len(updated_locus_list_response['locusListsByGuid']), 1)
        updated_locus_list = updated_locus_list_response['locusListsByGuid'].values()[0]
        self.assertEqual(updated_locus_list['name'], 'updated_locus_list')
        self.assertEqual(updated_locus_list['isPublic'], False)

        self.assertEqual(len(updated_locus_list_response['genesById']), 2)
        self.assertTrue(gene_id in updated_locus_list_response['genesById'])
        new_gene_id = next(gid for gid in updated_locus_list_response['genesById'] if gid != gene_id)
        self.assertSetEqual({item['geneId'] for item in updated_locus_list['items']}, {new_gene_id, gene_id})

        updated_locus_list_model = LocusList.objects.filter(guid=guid).first()
        self.assertIsNotNone(updated_locus_list_model)
        self.assertEqual(updated_locus_list_model.name, updated_locus_list['name'])
        self.assertEqual(updated_locus_list_model.is_public, updated_locus_list['isPublic'])

        self.assertEqual(updated_locus_list_model.locuslistgene_set.count(), 2)
        self.assertEqual(updated_locus_list_model.locuslistgene_set.last().gene_id, new_gene_id)
        self.assertEqual(updated_locus_list_model.locuslistinterval_set.count(), 0)

        # delete the locus_list
        delete_locus_list_url = reverse(delete_locus_list_handler, args=[guid])
        response = self.client.post(delete_locus_list_url, content_type='application/json')

        self.assertEqual(response.status_code, 200)

        # check that locus_list was deleted
        new_locus_list = LocusList.objects.filter(guid=guid)
        self.assertEqual(len(new_locus_list), 0)