From 236d9236c794d7870258eab9e087f990c557462a Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Thu, 26 May 2022 16:42:27 +0300 Subject: Add Endpoint to get menu items for use in UI --- gn3/api/menu.py | 14 ++ gn3/app.py | 2 + gn3/db/menu.py | 229 +++++++++++++++++++++ tests/unit/db/test_gen_menu.py | 442 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 687 insertions(+) create mode 100644 gn3/api/menu.py create mode 100644 gn3/db/menu.py create mode 100644 tests/unit/db/test_gen_menu.py diff --git a/gn3/api/menu.py b/gn3/api/menu.py new file mode 100644 index 0000000..cc77ab8 --- /dev/null +++ b/gn3/api/menu.py @@ -0,0 +1,14 @@ +"""API for data used to generate menus""" + +from flask import jsonify, Blueprint + +from gn3.db.menu import gen_dropdown_json +from gn3.db_utils import database_connector + +menu = Blueprint("menu", __name__) + +@menu.route("/generate/json") +def generate_json(): + """Get the menu in the JSON format""" + with database_connector() as conn: + return jsonify(gen_dropdown_json(conn)) diff --git a/gn3/app.py b/gn3/app.py index 790e87c..8a44983 100644 --- a/gn3/app.py +++ b/gn3/app.py @@ -16,6 +16,7 @@ from gn3.api.data_entry import data_entry from gn3.api.wgcna import wgcna from gn3.api.ctl import ctl from gn3.api.async_commands import async_commands +from gn3.api.menu import menu def create_app(config: Union[Dict, str, None] = None) -> Flask: """Create a new flask object""" @@ -49,4 +50,5 @@ def create_app(config: Union[Dict, str, None] = None) -> Flask: app.register_blueprint(wgcna, url_prefix="/api/wgcna") app.register_blueprint(ctl, url_prefix="/api/ctl") app.register_blueprint(async_commands, url_prefix="/api/async_commands") + app.register_blueprint(menu, url_prefix="/api/menu") return app diff --git a/gn3/db/menu.py b/gn3/db/menu.py new file mode 100644 index 0000000..8dccabf --- /dev/null +++ b/gn3/db/menu.py @@ -0,0 +1,229 @@ +"""Menu generation code for the data in the dropdowns in the index page.""" + +from typing import Tuple +from functools import reduce + +from gn3.db.species import get_all_species + +def gen_dropdown_json(conn): + """ + Generates and outputs (as json file) the data for the main dropdown menus on + the home page. + """ + species = get_all_species(conn) + groups = get_groups(conn, tuple(row[0] for row in species)) + types = get_types(conn, groups) + datasets = get_datasets(conn, types) + return dict(species=species, + groups=groups, + types=types, + datasets=datasets) + +def get_groups(conn, species_names: Tuple[str, ...]): + """Build groups list""" + with conn.cursor() as cursor: + query = ( + "SELECT InbredSet.Name, InbredSet.FullName, " + "IFNULL(InbredSet.Family, 'None'), " + "Species.Name AS species_name " + "FROM Species " + "INNER JOIN InbredSet ON InbredSet.SpeciesId = Species.Id " + "WHERE Species.Name IN " + f"({', '.join(['%s']*len(species_names))}) " + "GROUP BY InbredSet.Name " + "ORDER BY IFNULL(InbredSet.FamilyOrder, InbredSet.FullName) ASC, " + "IFNULL(InbredSet.Family, InbredSet.FullName) ASC, " + "InbredSet.FullName ASC, " + "InbredSet.MenuOrderId ASC") + cursor.execute(query, tuple(species_names)) + results = cursor.fetchall() + + def __organise_by_species(acc, row): + family_name = f"Family:{str(row[2])}" + species_name = row[3] + key_exists = bool(acc.get(species_name, False)) + if not key_exists: + return { + **acc, + species_name: [[str(row[0]), str(row[1]), family_name],] + } + + return { + **acc, + species_name: acc[species_name] + [ + [str(row[0]), str(row[1]), family_name],] + } + + return reduce(__organise_by_species, results, {}) + +def get_types(conn, groups): + """Build types list""" + types = {} + + for species, group_dict in list(groups.items()): + types[species] = {} + for group_name, _group_full_name, _family_name in group_dict: + if phenotypes_exist(conn, group_name): + types[species][group_name] = [ + ("Phenotypes", "Traits and Cofactors", "Phenotypes")] + if genotypes_exist(conn, group_name): + if group_name in types[species]: + types[species][group_name] += [ + ("Genotypes", "DNA Markers and SNPs", "Genotypes")] + else: + types[species][group_name] = [ + ("Genotypes", "DNA Markers and SNPs", "Genotypes")] + if group_name in types[species]: + types_list = build_types(conn, species, group_name) + if len(types_list) > 0: + types[species][group_name] += types_list + else: + types_list = build_types(conn, species, group_name) + if len(types_list) > 0: + types[species][group_name] = types_list + else: + types[species].pop(group_name, None) + groups[species] = list( + group for group in groups[species] + if group[0] != group_name) + return types + +def phenotypes_exist(conn, group_name): + "Check whether phenotypes exist for the given group" + with conn.cursor() as cursor: + cursor.execute( + ("SELECT Name FROM PublishFreeze " + "WHERE PublishFreeze.Name = %s"), + (group_name + "Publish",)) + results = cursor.fetchone() + return bool(results) + +def genotypes_exist(conn, group_name): + "Check whether genotypes exist for the given group" + with conn.cursor() as cursor: + cursor.execute( + ("SELECT Name FROM GenoFreeze " + + "WHERE GenoFreeze.Name = %s"), + (group_name + "Geno",)) + results = cursor.fetchone() + return bool(results) + +def build_types(conn, species, group): + """Fetches tissues + + Gets the tissues with data for this species/group + (all types except phenotype/genotype are tissues) + """ + query = ( + "SELECT DISTINCT Tissue.Name " + "FROM ProbeFreeze, ProbeSetFreeze, InbredSet, " + "Tissue, Species WHERE Species.Name = %s " + "AND Species.Id = InbredSet.SpeciesId AND " + "InbredSet.Name = %s AND ProbeFreeze.TissueId = " + "Tissue.Id AND ProbeFreeze.InbredSetId = InbredSet.Id " + "AND ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id " + "ORDER BY Tissue.Name") + results = [] + with conn.cursor() as cursor: + cursor.execute(query, (species, group)) + for result in cursor.fetchall(): + if bool(result): + these_datasets = build_datasets(conn, species, group, result[0]) + if len(these_datasets) > 0: + results.append([ + str(result[0]), str(result[0]), "Molecular Traits"]) + + return results + +def get_datasets(conn, types): + """Build datasets list""" + datasets = {} + for species, group_dict in list(types.items()): + datasets[species] = {} + for group, type_list in list(group_dict.items()): + datasets[species][group] = {} + for type_name in type_list: + these_datasets = build_datasets( + conn, species, group, type_name[0]) + if bool(these_datasets): + datasets[species][group][type_name[0]] = these_datasets + + return datasets + +def build_datasets(conn, species, group, type_name): + """Gets dataset names from database""" + dataset_text = dataset_value = None + datasets = [] + with conn.cursor() as cursor: + if type_name == "Phenotypes": + cursor.execute( + ("SELECT InfoFiles.GN_AccesionId, PublishFreeze.Name, " + "PublishFreeze.FullName FROM InfoFiles, PublishFreeze, " + "InbredSet WHERE InbredSet.Name = %s AND " + "PublishFreeze.InbredSetId = InbredSet.Id AND " + "InfoFiles.InfoPageName = PublishFreeze.Name " + "ORDER BY PublishFreeze.CreateTime ASC"), (group,)) + results = cursor.fetchall() + if bool(results): + for result in results: + dataset_id = str(result[0]) + dataset_value = str(result[1]) + dataset_text = str(result[2]) + if group == 'MDP': + dataset_text = "Mouse Phenome Database" + + datasets.append([dataset_id, dataset_value, dataset_text]) + else: + cursor.execute( + ("SELECT PublishFreeze.Name, PublishFreeze.FullName " + "FROM PublishFreeze, InbredSet " + "WHERE InbredSet.Name = %s AND " + "PublishFreeze.InbredSetId = InbredSet.Id " + "ORDER BY PublishFreeze.CreateTime ASC"), (group,)) + result = cursor.fetchone() + dataset_id = "None" + dataset_value = str(result[0]) + dataset_text = str(result[1]) + datasets.append([dataset_id, dataset_value, dataset_text]) + + elif type_name == "Genotypes": + cursor.execute( + ("SELECT InfoFiles.GN_AccesionId " + "FROM InfoFiles, GenoFreeze, InbredSet " + "WHERE InbredSet.Name = %s AND " + "GenoFreeze.InbredSetId = InbredSet.Id AND " + "InfoFiles.InfoPageName = GenoFreeze.ShortName " + "ORDER BY GenoFreeze.CreateTime " + "DESC"), (group,)) + results = cursor.fetchone() + dataset_id = "None" + if bool(results): + dataset_id = str(results[0]) + + dataset_value = f"{group}Geno" + dataset_text = f"{group} Genotypes" + datasets.append([dataset_id, dataset_value, dataset_text]) + + else: # for mRNA expression/ProbeSet + cursor.execute( + ("SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, " + "ProbeSetFreeze.FullName FROM ProbeSetFreeze, " + "ProbeFreeze, InbredSet, Tissue, Species WHERE " + "Species.Name = %s AND Species.Id = " + "InbredSet.SpeciesId AND InbredSet.Name = %s " + "AND ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id " + "AND Tissue.Name = %s AND ProbeFreeze.TissueId = " + "Tissue.Id AND ProbeFreeze.InbredSetId = InbredSet.Id " + "AND ProbeSetFreeze.public > 0 " + "ORDER BY -ProbeSetFreeze.OrderList DESC, " + "ProbeSetFreeze.CreateTime " + "DESC"), (species, group, type_name)) + results = cursor.fetchall() + datasets = [] + for dataset_info in results: + this_dataset_info = [] + for info in dataset_info: + this_dataset_info.append(str(info)) + datasets.append(this_dataset_info) + + return datasets diff --git a/tests/unit/db/test_gen_menu.py b/tests/unit/db/test_gen_menu.py new file mode 100644 index 0000000..e6b5711 --- /dev/null +++ b/tests/unit/db/test_gen_menu.py @@ -0,0 +1,442 @@ +"""Test cases for gn3.db.menu""" +import unittest +from unittest import mock + +import pytest + +from gn3.db.menu import gen_dropdown_json +from gn3.db.menu import get_groups +from gn3.db.menu import get_types +from gn3.db.menu import get_datasets +from gn3.db.menu import phenotypes_exist +from gn3.db.menu import genotypes_exist +from gn3.db.menu import build_datasets +from gn3.db.menu import build_types + + +class TestGenMenu(unittest.TestCase): + """Tests for the gen_menu module""" + + def setUp(self): + self.test_group = { + 'mouse': [ + ['H_T1', + 'H_T', + 'Family:DescriptionA' + ], + ['H_T2', "H_T'", 'Family:None'] + ], + 'human': [ + ['BXD', 'BXD', 'Family:None'], + ['HLC', 'Liver: Normal Gene Expression with Genotypes (Merck)', + 'Family:Test'] + ] + } + + self.test_type = { + 'mouse': { + 'H_T2': [('Phenotypes', + 'Traits and Cofactors', + 'Phenotypes'), + ('Genotypes', + 'DNA Markers and SNPs', + 'Genotypes'), + ['M', 'M', 'Molecular Trait Datasets']], + 'H_T1': [('Phenotypes', + 'Traits and Cofactors', + 'Phenotypes'), + ('Genotypes', + 'DNA Markers and SNPs', + 'Genotypes'), + ['M', 'M', 'Molecular Trait Datasets']] + }, + 'human': { + 'HLC': [('Phenotypes', + 'Traits and Cofactors', + 'Phenotypes'), + ('Genotypes', + 'DNA Markers and SNPs', + 'Genotypes'), + ['M', 'M', 'Molecular Trait Datasets']], + 'BXD': [('Phenotypes', + 'Traits and Cofactors', + 'Phenotypes'), + ('Genotypes', + 'DNA Markers and SNPs', + 'Genotypes'), + ['M', 'M', 'Molecular Trait Datasets']] + } + } + + @pytest.mark.unit_test + def test_get_groups(self): + """Test that species groups are grouped correctly""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchall.side_effect = [( + # Human + ('BXD', 'BXD', None, "human"), + ( + 'HLC', + ('Liver: Normal Gene Expression with Genotypes (Merck)'), + 'Test', + "human"), + # Mouse + ('H_T1', "H_T", "DescriptionA", "mouse"), + ('H_T2', "H_T'", None, "mouse") + )] + + self.assertEqual( + get_groups(db_mock, ["human", "mouse"]), self.test_group) + + cursor.execute.assert_called_once_with( + ("SELECT InbredSet.Name, InbredSet.FullName, " + "IFNULL(InbredSet.Family, 'None'), Species.Name AS " + "species_name FROM Species INNER JOIN InbredSet " + "ON InbredSet.SpeciesId = Species.Id " + "WHERE " + "Species.Name IN (%s, %s) " + "GROUP BY " + "InbredSet.Name ORDER BY IFNULL(InbredSet.FamilyOrder, " + "InbredSet.FullName) ASC, IFNULL(InbredSet.Family, " + "InbredSet.FullName) ASC, InbredSet.FullName ASC, " + "InbredSet.MenuOrderId ASC"), + ("human", "mouse")) + + @pytest.mark.unit_test + def test_phenotypes_exist_with_falsy_values(self): + """Test that phenotype check returns correctly when given + a None value""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + for item in [None, False, (), [], ""]: + cursor.fetchone.return_value = item + self.assertFalse(phenotypes_exist(db_mock, "test")) + + @pytest.mark.unit_test + def test_phenotypes_exist_with_truthy_value(self): + """Test that phenotype check returns correctly when given Truthy""" + db_mock = mock.MagicMock() + with db_mock.cursor() as conn: + with conn.cursor() as cursor: + for item in ["x", ("result"), ["result"], [1]]: + cursor.fetchone.return_value = (item) + self.assertTrue(phenotypes_exist(db_mock, "test")) + + @pytest.mark.unit_test + def test_genotypes_exist_with_falsy_values(self): + """Test that genotype check returns correctly when given a None value + + """ + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + for item in [None, False, (), [], ""]: + cursor.fetchone.return_value = item + self.assertFalse(genotypes_exist(db_mock, "test")) + + @pytest.mark.unit_test + def test_genotypes_exist_with_truthy_value(self): + """Test that genotype check returns correctly when given Truthy """ + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + for item in ["x", ("result"), ["result"], [1]]: + cursor.fetchone.return_value = (item) + self.assertTrue(phenotypes_exist(db_mock, "test")) + + @pytest.mark.unit_test + def test_build_datasets_with_type_phenotypes(self): + """Test that correct dataset is returned for a phenotype type""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchall.return_value = ( + (602, "BXDPublish", "BXD Published Phenotypes"), + ) + self.assertEqual(build_datasets(db_mock, "Mouse", "BXD", + "Phenotypes"), + [['602', "BXDPublish", + "BXD Published Phenotypes"]]) + cursor.execute.assert_called_with(( + "SELECT InfoFiles.GN_AccesionId, PublishFreeze.Name, " + "PublishFreeze.FullName FROM InfoFiles, PublishFreeze, " + "InbredSet WHERE InbredSet.Name = %s AND " + "PublishFreeze.InbredSetId = InbredSet.Id AND " + "InfoFiles.InfoPageName = PublishFreeze.Name " + "ORDER BY PublishFreeze.CreateTime ASC" + ), ("BXD",)) + self.assertEqual( + build_datasets(db_mock, "Mouse", "MDP","Phenotypes"), + [['602', "BXDPublish", "Mouse Phenome Database"]]) + + cursor.fetchall.return_value = () + cursor.fetchone.return_value = ( + "BXDPublish", "Mouse Phenome Database" + ) + self.assertEqual( + build_datasets(db_mock, "Mouse", "MDP", "Phenotypes"), + [["None", "BXDPublish", "Mouse Phenome Database"]]) + + @pytest.mark.unit_test + def test_build_datasets_with_type_phenotypes_and_no_results(self): + """Test that correct dataset is returned for a phenotype type with no + results + + """ + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchall.return_value = None + cursor.fetchone.return_value = (121, + "text value") + self.assertEqual( + build_datasets(db_mock, "Mouse", "BXD", "Phenotypes"), + [["None", "121", "text value"]]) + cursor.execute.assert_called_with(( + "SELECT PublishFreeze.Name, PublishFreeze.FullName " + "FROM PublishFreeze, InbredSet " + "WHERE InbredSet.Name = %s AND " + "PublishFreeze.InbredSetId = InbredSet.Id " + "ORDER BY PublishFreeze.CreateTime ASC" + ), ("BXD",)) + + @pytest.mark.unit_test + def test_build_datasets_with_type_genotypes(self): + """Test that correct dataset is returned for a phenotype type""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchone.return_value = ( + 635, "HLCPublish", "HLC Published Genotypes" + ) + self.assertEqual( + build_datasets(db_mock, "Mouse", "HLC", "Genotypes"), + [["635", "HLCGeno", "HLC Genotypes"]]) + cursor.execute.assert_called_with(( + "SELECT InfoFiles.GN_AccesionId FROM InfoFiles, " + "GenoFreeze, InbredSet WHERE InbredSet.Name = %s AND " + "GenoFreeze.InbredSetId = InbredSet.Id AND " + "InfoFiles.InfoPageName = GenoFreeze.ShortName " + "ORDER BY GenoFreeze.CreateTime DESC" + ), ("HLC",)) + cursor.fetchone.return_value = () + self.assertEqual( + build_datasets(db_mock, "Mouse", "HLC", "Genotypes"), + [["None", "HLCGeno", "HLC Genotypes"]]) + + @pytest.mark.unit_test + def test_build_datasets_with_type_mrna(self): + """Test that correct dataset is returned for a mRNA + expression/ Probeset""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchall.return_value = ( + (112, "HC_M2_0606_P", + "Hippocampus Consortium M430v2 (Jun06) PDNN"), ) + self.assertEqual( + build_datasets(db_mock, "Mouse", "HLC", "mRNA"), + [["112", 'HC_M2_0606_P', + "Hippocampus Consortium M430v2 (Jun06) PDNN"]]) + cursor.execute.assert_called_once_with(( + "SELECT ProbeSetFreeze.Id, ProbeSetFreeze.Name, " + "ProbeSetFreeze.FullName FROM ProbeSetFreeze, " + "ProbeFreeze, InbredSet, Tissue, Species WHERE " + "Species.Name = %s AND Species.Id = " + "InbredSet.SpeciesId AND InbredSet.Name = %s AND " + "ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND " + "Tissue.Name = %s AND ProbeFreeze.TissueId = " + "Tissue.Id AND ProbeFreeze.InbredSetId = InbredSet.Id AND " + "ProbeSetFreeze.public > 0 " + "ORDER BY -ProbeSetFreeze.OrderList DESC, " + "ProbeSetFreeze.CreateTime DESC"), ("Mouse", "HLC", "mRNA")) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.build_datasets') + def test_build_types(self, datasets_mock): + """Test that correct tissue metadata is returned""" + db_mock = mock.MagicMock() + datasets_mock.return_value = [ + ["112", 'HC_M2_0606_P', + "Hippocampus Consortium M430v2 (Jun06) PDNN"] + ] + with db_mock.cursor() as cursor: + cursor.fetchall.return_value = ( + ('Mouse Tissue'), ('Human Tissue'), ('Rat Tissue') + ) + self.assertEqual( + build_types(db_mock, 'mouse', 'random group'), + [['M', 'M', 'Molecular Traits'], + ['H', 'H', 'Molecular Traits'], + ['R', 'R', 'Molecular Traits']]) + cursor.execute.assert_called_once_with(( + "SELECT DISTINCT Tissue.Name " + "FROM ProbeFreeze, ProbeSetFreeze, InbredSet, " + "Tissue, Species WHERE Species.Name = %s " + "AND Species.Id = InbredSet.SpeciesId AND " + "InbredSet.Name = %s AND " + "ProbeFreeze.TissueId = Tissue.Id AND " + "ProbeFreeze.InbredSetId = InbredSet.Id AND " + "ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id " + "ORDER BY Tissue.Name" + ), ("mouse", "random group")) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.build_types') + @mock.patch('gn3.db.menu.genotypes_exist') + @mock.patch('gn3.db.menu.phenotypes_exist') + def test_get_types_with_existing_genotype_and_phenotypes( + self, + phenotypes_exist_mock, + genotypes_exist_mock, + build_types_mock): + """Test that build types are constructed correctly if phenotypes and genotypes + exist + + """ + phenotypes_exist_mock.return_value = True + genotypes_exist_mock.return_value = True + + expected_result = self.test_type + + build_types_mock.return_value = [ + ['M', 'M', 'Molecular Trait Datasets'] + ] + self.assertEqual( + get_types(mock.MagicMock(), self.test_group,), expected_result) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.build_types') + @mock.patch('gn3.db.menu.genotypes_exist') + @mock.patch('gn3.db.menu.phenotypes_exist') + def test_get_types_with_buildtype_and_non_existent_genotype_and_phenotypes( + self, + phenotypes_exist_mock, + genotypes_exist_mock, + build_types_mock): + """Test that build types are constructed correctly if phenotypes_exist and + genotypes_exist are false but build_type is falsy + + """ + phenotypes_exist_mock.return_value = False + genotypes_exist_mock.return_value = False + + build_types_mock.return_value = [] + self.assertEqual(get_types(mock.MagicMock(), self.test_group), + {'mouse': {}, 'human': {}}) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.build_types') + @mock.patch('gn3.db.menu.genotypes_exist') + @mock.patch('gn3.db.menu.phenotypes_exist') + def test_get_types_with_non_existent_genotype_phenotypes_and_buildtype( + self, + phenotypes_exist_mock, + genotypes_exist_mock, + build_types_mock): + """Test that build types are constructed correctly if phenotypes_exist, + genotypes_exist and build_types are truthy + + """ + phenotypes_exist_mock.return_value = False + genotypes_exist_mock.return_value = False + + build_types_mock.return_value = [ + ['M', 'M', 'Molecular Trait Datasets'] + ] + expected_result = { + 'mouse': { + 'H_T2': [['M', 'M', 'Molecular Trait Datasets']], + 'H_T1': [['M', 'M', 'Molecular Trait Datasets']]}, + 'human': { + 'HLC': [['M', 'M', 'Molecular Trait Datasets']], + 'BXD': [['M', 'M', 'Molecular Trait Datasets']]}} + self.assertEqual(get_types(mock.MagicMock(), self.test_group), + expected_result) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.build_datasets') + def test_get_datasets_with_existent_datasets( + self, build_datasets_mock): + """Test correct dataset is returned with existent build_datasets""" + build_datasets_mock.return_value = "Test" + expected_result = { + 'mouse': { + 'H_T2': {'Genotypes': 'Test', + 'M': 'Test', + 'Phenotypes': 'Test'}, + 'H_T1': {'Genotypes': 'Test', + 'M': 'Test', + 'Phenotypes': 'Test'}}, + 'human': {'HLC': {'Genotypes': 'Test', + 'M': 'Test', + 'Phenotypes': 'Test'}, + 'BXD': {'Genotypes': 'Test', + 'M': 'Test', + 'Phenotypes': 'Test'}}} + self.assertEqual( + get_datasets(mock.MagicMock(), self.test_type), expected_result) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.build_datasets') + def test_get_datasets_with_non_existent_datasets(self, + build_datasets_mock): + """Test correct dataset is returned with non-existent build_datasets""" + build_datasets_mock.return_value = None + expected_result = { + 'mouse': { + 'H_T2': {}, + 'H_T1': {}}, + 'human': {'HLC': {}, + 'BXD': {}}} + self.assertEqual( + get_datasets(mock.MagicMock(), self.test_type), expected_result) + + @pytest.mark.unit_test + @mock.patch('gn3.db.menu.get_datasets') + @mock.patch('gn3.db.menu.get_types') + @mock.patch('gn3.db.menu.get_groups') + @mock.patch('gn3.db.menu.get_all_species') + def test_gen_dropdown_json(self, + species_mock, + groups_mock, + types_mock, + datasets_mock): + "Test that the correct dictionary is constructed properly" + species_mock.return_value = ("speciesA speciesB speciesC speciesD" + .split(" ")) + datasets_mock.return_value = ("datasetA datasetB datasetC datasetD" + .split(" ")) + groups_mock.return_value = ("groupA groupB groupC groupD" + .split(" ")) + types_mock.return_value = ("typeA typeB typeC typeD" + .split(" ")) + datasets_mock.return_value = ("datasetA datasetB datasetC datasetD" + .split(" ")) + + expected_result = { + 'datasets': ['datasetA', 'datasetB', 'datasetC', 'datasetD'], + 'types': ['typeA', 'typeB', 'typeC', 'typeD'], + 'groups': ['groupA', 'groupB', 'groupC', 'groupD'], + 'species': ['speciesA', 'speciesB', 'speciesC', 'speciesD']} + + self.assertEqual(gen_dropdown_json(mock.MagicMock()), expected_result) + +@pytest.mark.unit_test +def test_phenotypes_exist_called_with_correct_query(): + """Test that phenotypes_exist is called with the correct query""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchone.return_value = None + phenotypes_exist(db_mock, "test") + cursor.execute.assert_called_with(( + "SELECT Name FROM PublishFreeze " + "WHERE PublishFreeze.Name = %s" + ), ("testPublish",)) + +@pytest.mark.unit_test +def test_genotypes_exist_called_with_correct_query(): + """Test that genotypes_exist is called with the correct query""" + db_mock = mock.MagicMock() + with db_mock.cursor() as cursor: + cursor.fetchone.return_value = None + genotypes_exist(db_mock, "test") + cursor.execute.assert_called_with(( + "SELECT Name FROM GenoFreeze WHERE " + "GenoFreeze.Name = %s" + ), ("testGeno",)) -- cgit v1.2.3