aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gn3/api/menu.py14
-rw-r--r--gn3/app.py2
-rw-r--r--gn3/db/menu.py229
-rw-r--r--tests/unit/db/test_gen_menu.py442
4 files changed, 687 insertions, 0 deletions
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",))