Skip to content
Permalink
60cd76fcb8
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
826 lines (634 sloc) 40.8 KB
#!/usr/bin/env python3
from planet import create_app, db
from planet.controllers.help import __TOPICS as topics
from flask_testing import TestCase
from tests.config import LOGIN_ENABLED, BLAST_ENABLED
import json
import unittest
class WebsiteTest(TestCase):
"""
TestCase to check if the website is functional
* a DB will be created and filled with dummy data
* an app will be spawned with the testing config, DO NOT run this against a database that is in use !!
* the DB will be cleared !
"""
def create_app(self):
"""
Creates the app using the tests config (tests/config.py)
:return: flask app with settings from tests/config.py
"""
app = create_app('tests.config')
return app
def setUp(self):
"""
Creates a database and fills it with sufficient dummy data to run the tests.
"""
from planet.models.users import User
from planet.models.expression_profiles import ExpressionProfile
from planet.models.sequences import Sequence
from planet.models.species import Species
from planet.models.interpro import Interpro
from planet.models.go import GO
from planet.models.gene_families import GeneFamily, GeneFamilyMethod
from planet.models.coexpression_clusters import CoexpressionCluster, CoexpressionClusteringMethod
from planet.models.expression_networks import ExpressionNetwork, ExpressionNetworkMethod
from planet.models.relationships import SequenceCoexpressionClusterAssociation, SequenceSequenceECCAssociation
from planet.models.expression_specificity import ExpressionSpecificityMethod
from planet.models.clades import Clade
db.create_all()
test_user = User('admin', 'admin', '', is_admin=True)
test_species = Species('tst', 'Unittest species')
test_interpro = Interpro('IPR_TEST', 'Test label')
test_go = GO('GO:TEST', 'test_process', 'biological_process', 'Test label', False, None, None)
test_go2 = GO('GO:TEST2', 'test2', 'biological_process', 'Test', False, None, None)
test_gf_method = GeneFamilyMethod('test_gf_method')
test_gf = GeneFamily('test_gf')
db.session.add(test_user)
db.session.add(test_species)
db.session.add(test_interpro)
db.session.add(test_go)
db.session.add(test_go2)
db.session.add(test_gf_method)
db.session.add(test_gf)
db.session.commit()
test_gf.method_id = test_gf_method.id
db.session.commit()
test_sequence = Sequence(test_species.id, 'TEST_SEQ_01', 'ATG', description='test sequence')
test_sequence.families.append(test_gf)
test_sequence.interpro_domains.append(test_interpro)
test_sequence.go_labels.append(test_go)
test_sequence2 = Sequence(test_species.id, 'TEST_SEQ_02', 'ATG', description='test sequence')
db.session.add(test_sequence)
db.session.add(test_sequence2)
db.session.commit()
test_profile = ExpressionProfile('test_probe', test_sequence.id, '{"data": {"seedling - hypocotyl 17d": [29.0, 44.0, 35.0], "stage 15 flower - pedicel +21d": [39.0, 18.0, 28.0], "senescing leaf 35d": [104.0, 95.0, 121.0], "stage 12 flower - stamen +21d": [56.0, 41.0, 40.0], "seed - triangle stage 56d": [18.0, 21.0, 37.0], "pollen - uninuclear stage": [17.0, 17.0], "seed - globular stage 56d": [17.0, 28.0, 25.0], "root 21d": [49000.0, 46000.0, 49000.0], "stage 12 flower - carpel +21d": [29.0, 34.0, 38.0], "quiescent center and endodermis, beyond the mature hair zone": [5.0, 5.0, 17.0], "stage 12 flower +21d": [26.0, 39.0, 41.0], "mature seed 56d": [14.0, 12.0, 11.0], "shoot 21d": [94.0, 63.0, 75.0], "stage 10 flower +21d": [83.0, 112.0, 99.0], "stage 12 flower - petal +21d": [68.0, 57.0, 47.0], "seed - heart stage 56d": [44.0, 39.0, 17.0], "stage 1 flower 21d": [126.0, 120.0, 116.0], "stem 2nd internode +21d": [41.0, 42.0, 41.0], "pollen stage 10 - pollen sac 42d": [22.0, 46.0, 31.0], "endodermis, cortex and quiescent center": [13.0, 20.0, 13.0], "rosette leaf 10d": [40.0, 27.0, 44.0], "root 17d": [44.0, 53.0, 51.0], "stage 12 flower - sepal +21d": [56.0, 39.0, 53.0], "stage 9 flower +21d": [113.0, 107.0, 143.0], "~0.15 mm from the root tip": [58.0, 35.0, 17.0, 15.0], "stage 15 flower - carpel +21d": [33.0, 22.0, 24.0], "~0.30 mm from the root tip": [13.0, 13.0, 24.0, 66.0], "rosette leaf - distal half 17d": [18.0, 25.0, 20.0], "petiole 17d": [28.0, 19.0, 20.0], "pollen - bicellular stage": [26.0, 16.0], "atrichoblasts from the quiescent center up": [7.0, 20.0, 8.0], "~0.45 to 2 mm from the root tip": [0.0, 23.0, 20.0, 3.0], "complete rosette 22d": [19.0, 29.0, 24.0], "pollen - tricellular stage": [22.0, 32.0], "stem 1st internode +21d": [72.0, 78.0, 63.0], "stage 15 flower +21d": [32.0, 38.0, 39.0], "pollen - mature": [31.0, 46.0, 22.0], "cauline leaf +21d": [58.0, 41.0, 51.0], "seedling - shoot apex 7d": [27.0, 23.0, 43.0], "complete rosette 23d": [21.0, 20.0, 20.0], "seedling - rosette leaf 7d": [42.0, 40.0, 33.0], "complete rosette 21d": [21.0, 26.0, 22.0], "rosette leaf 17d": [62.0, 57.0, 29.0], "seed - torpedo stage 56d": [24.0, 32.0, 23.0], "rosette leaf - proximal half 17d": [26.0, 17.0, 21.0], "seedling - cotyledon 7d": [50.0, 31.0, 25.0], "stage 15 flower - stamen +21d": [30.0, 18.0, 28.0], "root stele to elongation zone": [20.0, 9.0, 11.0], "stage 15 flower - sepal +21d": [49.0, 28.0, 22.0], "stage 15 flower - petal +21d": [30.0, 19.0, 45.0], "seed - curled cotyledon stage 56d": [16.0, 15.0, 15.0], "lateral root cap and epidermis": [12.0, 6.0, 5.0]}, "order": ["seedling - cotyledon 7d", "seedling - hypocotyl 17d", "seedling - rosette leaf 7d", "seedling - shoot apex 7d", "root 17d", "root 21d", "~0.15 mm from the root tip", "~0.30 mm from the root tip", "~0.45 to 2 mm from the root tip", "atrichoblasts from the quiescent center up", "endodermis, cortex and quiescent center", "lateral root cap and epidermis", "quiescent center and endodermis, beyond the mature hair zone", "root stele to elongation zone", "rosette leaf 10d", "rosette leaf 17d", "rosette leaf - distal half 17d", "rosette leaf - proximal half 17d", "complete rosette 21d", "complete rosette 22d", "complete rosette 23d", "senescing leaf 35d", "cauline leaf +21d", "petiole 17d", "shoot 21d", "stem 1st internode +21d", "stem 2nd internode +21d", "stage 1 flower 21d", "stage 9 flower +21d", "stage 10 flower +21d", "stage 12 flower - carpel +21d", "stage 12 flower - petal +21d", "stage 12 flower - sepal +21d", "stage 12 flower - stamen +21d", "stage 12 flower +21d", "stage 15 flower - carpel +21d", "stage 15 flower - pedicel +21d", "stage 15 flower - petal +21d", "stage 15 flower - sepal +21d", "stage 15 flower - stamen +21d", "stage 15 flower +21d", "seed - curled cotyledon stage 56d", "seed - globular stage 56d", "seed - heart stage 56d", "seed - torpedo stage 56d", "seed - triangle stage 56d", "mature seed 56d", "pollen stage 10 - pollen sac 42d", "pollen - uninuclear stage", "pollen - bicellular stage", "pollen - tricellular stage", "pollen - mature"]}')
test_profile.species_id = test_species.id
test_profile2 = ExpressionProfile('test_probe2', test_sequence2.id, '{"data": {"seedling - hypocotyl 17d": [29.0, 44.0, 35.0], "stage 15 flower - pedicel +21d": [39.0, 18.0, 28.0], "senescing leaf 35d": [104.0, 95.0, 121.0], "stage 12 flower - stamen +21d": [56.0, 41.0, 40.0], "seed - triangle stage 56d": [18.0, 21.0, 37.0], "pollen - uninuclear stage": [17.0, 17.0], "seed - globular stage 56d": [17.0, 28.0, 25.0], "root 21d": [49.0, 46.0, 49.0], "stage 12 flower - carpel +21d": [29.0, 34.0, 38.0], "quiescent center and endodermis, beyond the mature hair zone": [5.0, 5.0, 17.0], "stage 12 flower +21d": [26.0, 39.0, 41.0], "mature seed 56d": [14.0, 12.0, 11.0], "shoot 21d": [94.0, 63.0, 75.0], "stage 10 flower +21d": [83.0, 112.0, 99.0], "stage 12 flower - petal +21d": [68.0, 57.0, 47.0], "seed - heart stage 56d": [44.0, 39.0, 17.0], "stage 1 flower 21d": [126.0, 120.0, 116.0], "stem 2nd internode +21d": [41.0, 42.0, 41.0], "pollen stage 10 - pollen sac 42d": [22.0, 46.0, 31.0], "endodermis, cortex and quiescent center": [13.0, 20.0, 13.0], "rosette leaf 10d": [40.0, 27.0, 44.0], "root 17d": [44.0, 53.0, 51.0], "stage 12 flower - sepal +21d": [56.0, 39.0, 53.0], "stage 9 flower +21d": [113.0, 107.0, 143.0], "~0.15 mm from the root tip": [58.0, 35.0, 17.0, 15.0], "stage 15 flower - carpel +21d": [33.0, 22.0, 24.0], "~0.30 mm from the root tip": [13.0, 13.0, 24.0, 66.0], "rosette leaf - distal half 17d": [18.0, 25.0, 20.0], "petiole 17d": [28.0, 19.0, 20.0], "pollen - bicellular stage": [26.0, 16.0], "atrichoblasts from the quiescent center up": [7.0, 20.0, 8.0], "~0.45 to 2 mm from the root tip": [0.0, 23.0, 20.0, 3.0], "complete rosette 22d": [19.0, 29.0, 24.0], "pollen - tricellular stage": [22.0, 32.0], "stem 1st internode +21d": [72.0, 78.0, 63.0], "stage 15 flower +21d": [32.0, 38.0, 39.0], "pollen - mature": [31.0, 46.0, 22.0], "cauline leaf +21d": [58.0, 41.0, 51.0], "seedling - shoot apex 7d": [27.0, 23.0, 43.0], "complete rosette 23d": [21.0, 20.0, 20.0], "seedling - rosette leaf 7d": [42.0, 40.0, 33.0], "complete rosette 21d": [21.0, 26.0, 22.0], "rosette leaf 17d": [62.0, 57.0, 29.0], "seed - torpedo stage 56d": [24.0, 32.0, 23.0], "rosette leaf - proximal half 17d": [26.0, 17.0, 21.0], "seedling - cotyledon 7d": [50.0, 31.0, 25.0], "stage 15 flower - stamen +21d": [30.0, 18.0, 28.0], "root stele to elongation zone": [20.0, 9.0, 11.0], "stage 15 flower - sepal +21d": [49.0, 28.0, 22.0], "stage 15 flower - petal +21d": [30.0, 19.0, 45.0], "seed - curled cotyledon stage 56d": [16.0, 15.0, 15.0], "lateral root cap and epidermis": [12.0, 6.0, 5.0]}, "order": ["seedling - cotyledon 7d", "seedling - hypocotyl 17d", "seedling - rosette leaf 7d", "seedling - shoot apex 7d", "root 17d", "root 21d", "~0.15 mm from the root tip", "~0.30 mm from the root tip", "~0.45 to 2 mm from the root tip", "atrichoblasts from the quiescent center up", "endodermis, cortex and quiescent center", "lateral root cap and epidermis", "quiescent center and endodermis, beyond the mature hair zone", "root stele to elongation zone", "rosette leaf 10d", "rosette leaf 17d", "rosette leaf - distal half 17d", "rosette leaf - proximal half 17d", "complete rosette 21d", "complete rosette 22d", "complete rosette 23d", "senescing leaf 35d", "cauline leaf +21d", "petiole 17d", "shoot 21d", "stem 1st internode +21d", "stem 2nd internode +21d", "stage 1 flower 21d", "stage 9 flower +21d", "stage 10 flower +21d", "stage 12 flower - carpel +21d", "stage 12 flower - petal +21d", "stage 12 flower - sepal +21d", "stage 12 flower - stamen +21d", "stage 12 flower +21d", "stage 15 flower - carpel +21d", "stage 15 flower - pedicel +21d", "stage 15 flower - petal +21d", "stage 15 flower - sepal +21d", "stage 15 flower - stamen +21d", "stage 15 flower +21d", "seed - curled cotyledon stage 56d", "seed - globular stage 56d", "seed - heart stage 56d", "seed - torpedo stage 56d", "seed - triangle stage 56d", "mature seed 56d", "pollen stage 10 - pollen sac 42d", "pollen - uninuclear stage", "pollen - bicellular stage", "pollen - tricellular stage", "pollen - mature"]}')
test_profile2.species_id = test_species.id
db.session.add(test_profile)
db.session.add(test_profile2)
db.session.commit()
test_expression_network_method = ExpressionNetworkMethod(test_species.id, "Test network method")
db.session.add(test_expression_network_method)
db.session.commit()
test_expression_network = ExpressionNetwork(test_profile.probe,
test_sequence.id,
'[{"gene_name": "TEST_SEQ_02", "gene_id": ' + str(test_sequence2.id)
+ ', "probe_name": "test_probe2", "link_score": 0}]',
test_expression_network_method.id)
test_expression_network2 = ExpressionNetwork(test_profile2.probe,
test_sequence2.id,
'[{"gene_name": "TEST_SEQ_01", "gene_id": ' + str(test_sequence.id)
+ ', "probe_name": "test_probe2", "link_score": 0}]',
test_expression_network_method.id)
db.session.add(test_expression_network)
db.session.add(test_expression_network2)
db.session.commit()
test_expression_network_method.update_count()
test_cluster_method = CoexpressionClusteringMethod()
test_cluster_method.network_method_id = test_expression_network_method.id
test_cluster_method.method = 'test clustering method'
db.session.add(test_cluster_method)
db.session.commit()
test_cluster = CoexpressionCluster()
test_cluster.method_id = test_cluster_method.id
test_cluster.name = 'TEST_COEXP_CLUSTER'
db.session.add(test_cluster)
db.session.commit()
test_cluster_method.update_counts()
new_association = SequenceCoexpressionClusterAssociation()
new_association.probe = test_profile.probe
new_association.sequence_id = test_sequence.id
new_association.coexpression_cluster_id = test_cluster.id
new_association2 = SequenceCoexpressionClusterAssociation()
new_association2.probe = test_profile2.probe
new_association2.sequence_id = test_sequence2.id
new_association2.coexpression_cluster_id = test_cluster.id
db.session.add(new_association)
db.session.add(new_association2)
db.session.commit()
Clade.add_clade('test', ["tst"], "(test:0.01);")
clade = Clade.query.first()
clade.families.append(GeneFamily.query.first())
clade.interpro.append(Interpro.query.first())
db.session.commit()
new_ecc = SequenceSequenceECCAssociation()
new_ecc.query_id = test_sequence.id
new_ecc.target_id = test_sequence2.id
new_ecc.gene_family_method_id = test_gf_method.id
new_ecc.query_network_method_id = test_expression_network_method.id
new_ecc.target_network_method_id = test_expression_network_method.id
new_ecc.ecc = 0.5
new_ecc.p_value = 0.05
new_ecc.corrected_p_value = 0.05
db.session.add(new_ecc)
db.session.commit()
ExpressionSpecificityMethod.calculate_specificities(test_species.id, "Specificity description")
test_species.update_counts()
clade.update_clades()
clade.update_clades_interpro()
def tearDown(self):
"""
Removes test database again, so the next test can start with a clean slate
"""
db.session.remove()
db.drop_all()
def assertCytoscapeJson(self, data, ecc_graph=False):
self.assertTrue('nodes' in data.keys())
self.assertTrue('edges' in data.keys())
for node in data['nodes']:
self.assertTrue('color' in node['data'].keys())
self.assertTrue('id' in node['data'].keys())
compound = node['data']['compound'] if 'compound' in node['data'].keys() else False
if not compound:
required_keys = ['family_color', 'lc_label', 'lc_color', 'lc_shape', 'family_name',
'shape', 'description', 'name', 'gene_name', 'tokens', 'family_clade_count',
'gene_id', 'family_id', 'family_url', 'family_clade', 'family_shape']
self.assertTrue('data' in node.keys())
self.assertTrue(all([k in node['data'].keys() for k in required_keys]))
if not ecc_graph:
self.assertTrue('depth' in node['data'].keys())
self.assertTrue('profile_link' in node['data'].keys())
else:
self.assertTrue('species_name' in node['data'].keys())
self.assertTrue('species_id' in node['data'].keys())
self.assertTrue('species_color' in node['data'].keys())
for edge in data['edges']:
self.assertTrue('data' in edge.keys())
self.assertTrue('source' in edge['data'].keys())
self.assertTrue('target' in edge['data'].keys())
self.assertTrue('color' in edge['data'].keys())
homology = edge['data']['homology'] if 'homology' in edge['data'].keys() else False
if not homology:
self.assertTrue('edge_type' in edge['data'].keys())
if not ecc_graph:
self.assertTrue('link_score' in edge['data'].keys())
self.assertTrue('profile_comparison' in edge['data'].keys())
self.assertTrue('depth' in edge['data'].keys())
else:
self.assertTrue('ecc_score' in edge['data'].keys())
def test_main(self):
response = self.client.get("/")
self.assert_template_used('static_pages/main.html')
self.assert200(response)
response = self.client.get("/about")
self.assert_template_used('static_pages/about.html')
self.assert200(response)
response = self.client.get("/contact")
self.assert_template_used('static_pages/contact.html')
self.assert200(response)
response = self.client.get("/license")
self.assert_template_used('static_pages/license.html')
self.assert200(response)
response = self.client.get("/this_should_not_exist")
self.assert_template_used('error/404.html')
self.assert404(response)
def test_sequence(self):
"""
Test for routes associated with a Sequence
"""
from planet.models.sequences import Sequence
sequence = Sequence.query.first()
response = self.client.get("/sequence/view/%d" % sequence.id)
self.assert_template_used('sequence.html')
self.assert200(response)
response = self.client.get("/sequence/fasta/coding/%d" % sequence.id)
self.assert200(response)
data = response.data.decode("utf-8").strip()
self.assertEqual(len(data.split('\n')), 2)
self.assertEqual(data[0], '>')
self.assertTrue('>' + sequence.name + '\n' in data)
response = self.client.get("/sequence/fasta/protein/%d" % sequence.id)
self.assert200(response)
data = response.data.decode("utf-8").strip()
self.assertEqual(len(data.split('\n')), 2)
self.assertEqual(data[0], '>')
self.assertTrue('>' + sequence.name + '\n' in data)
response = self.client.get("/sequence/find/" + sequence.name)
self.assert_template_used('sequence.html')
self.assert200(response)
response = self.client.get("/sequence/view/a")
self.assert404(response)
def test_species(self):
"""
Test for routes associated with a Species
"""
from planet.models.species import Species
# Should have a main page
response = self.client.get("/species/")
self.assert_template_used('species.html')
self.assert200(response)
species = Species.query.first()
sequence = species.sequences.first()
# Should respresent itself as a string
self.assertEqual(str(species), str(species.id) + '. ' + species.name)
# Should have a detailed page for each species
response = self.client.get("/species/view/%d" % species.id)
self.assert_template_used('species.html')
self.assert200(response)
# Should have a paginated page with the sequences
response = self.client.get("/species/sequences/%d/1" % species.id)
self.assert_template_used('pagination/sequences.html')
self.assert200(response)
# Should have allow downloading coding sequences as a fasta file
response = self.client.get("/species/download/coding/%d" % species.id)
self.assert200(response)
data = response.data.decode("utf-8").strip()
self.assertTrue(len(data.split('\n')) > 0)
self.assertEqual(data[0], '>')
self.assertTrue('>' + sequence.name + '\n' in data)
# Should have allow downloading protein sequences as a fasta file
response = self.client.get("/species/download/protein/%d" % species.id)
self.assert200(response)
data = response.data.decode("utf-8").strip()
self.assertTrue(len(data.split('\n')) > 0)
self.assertEqual(data[0], '>')
self.assertTrue('>' + sequence.name + '\n' in data)
# Should have allow streaming coding sequences as a fasta file
response = self.client.get("/species/stream/coding/%d" % species.id)
self.assert200(response)
data = response.data.decode("utf-8").strip()
self.assertTrue(len(data.split('\n')) > 0)
self.assertEqual(data[0], '>')
self.assertTrue('>' + sequence.name + '\n' in data)
# Should have allow streaming protein sequences as a fasta file
response = self.client.get("/species/stream/protein/%d" % species.id)
self.assert200(response)
data = response.data.decode("utf-8").strip()
self.assertTrue(len(data.split('\n')) > 0)
self.assertEqual(data[0], '>')
self.assertTrue('>' + sequence.name + '\n' in data)
def test_interpro(self):
"""
Test for routes associated with an InterPro domain
"""
from planet.models.interpro import Interpro
# Should redirect to main page as there is no overview
response = self.client.get('/interpro/')
self.assertRedirects(response, "/")
interpro = Interpro.query.first()
# Should show page for each domain
response = self.client.get("/interpro/view/%d" % interpro.id)
self.assert_template_used('interpro.html')
self.assert200(response)
# Should find domains based on their label
response = self.client.get("/interpro/find/" + interpro.label)
self.assert_template_used('interpro.html')
self.assert200(response)
# Should show sequences that have the domain
response = self.client.get("/interpro/sequences/%d/1" % interpro.id)
self.assert_template_used('pagination/sequences.html')
self.assert200(response)
# Should allow downloading sequences that have the domain as csv
response = self.client.get("/interpro/sequences/table/%d" % interpro.id)
self.assert_template_used('tables/sequences.csv')
self.assert200(response)
# Should return phylogenetic profile compatible with charts.js
response = self.client.get("/interpro/json/species/%d" % interpro.id)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue('data' in data.keys())
self.assertTrue('type' in data.keys())
self.assertTrue('labels' in data['data'].keys())
self.assertTrue('datasets' in data['data'].keys())
def test_go(self):
"""
Test for routes associated with a GO label
"""
from planet.models.go import GO
response = self.client.get('/go/')
self.assertRedirects(response, "/")
go = GO.query.first()
response = self.client.get("/go/view/%d" % go.id)
self.assert_template_used('go.html')
self.assert200(response)
response = self.client.get("/go/find/" + go.label)
self.assertRedirects(response, "/go/view/%d" % go.id)
response = self.client.get("/go/sequences/%d/1" % go.id)
self.assert_template_used('pagination/sequences.html')
self.assert200(response)
response = self.client.get("/go/sequences/table/%d" % go.id)
self.assert_template_used('tables/sequences.csv')
self.assert200(response)
response = self.client.get("/go/json/species/%d" % go.id)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue('data' in data.keys())
self.assertTrue('type' in data.keys())
self.assertTrue('labels' in data['data'].keys())
self.assertTrue('datasets' in data['data'].keys())
response = self.client.get("/go/json/genes/" + go.label)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue(1 in data)
response = self.client.get("/go/json/genes/" + 'no_label')
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue(data == [])
def test_family(self):
"""
Test for routes associated with a GeneFamily
"""
from planet.models.gene_families import GeneFamily
response = self.client.get('/family/')
self.assertRedirects(response, "/")
family = GeneFamily.query.first()
response = self.client.get("/family/view/%d" % family.id)
self.assert_template_used('family.html')
self.assert200(response)
response = self.client.get("/family/find/" + family.name)
self.assert_template_used('family.html')
self.assert200(response)
response = self.client.get("/family/sequences/%d/1" % family.id)
self.assert_template_used('pagination/sequences.html')
self.assert200(response)
response = self.client.get("/family/sequences/table/%d" % family.id)
self.assert_template_used('tables/sequences.csv')
self.assert200(response)
response = self.client.get("/family/json/species/%d" % family.id)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue('data' in data.keys())
self.assertTrue('type' in data.keys())
self.assertTrue('labels' in data['data'].keys())
self.assertTrue('datasets' in data['data'].keys())
def test_profile(self):
"""
Test for routes associated with an ExpressionProfile
"""
from planet.models.expression_profiles import ExpressionProfile
response = self.client.get('/profile/')
self.assertRedirects(response, "/")
profile = ExpressionProfile.query.first()
response = self.client.get("/profile/view/%d" % profile.id)
self.assert_template_used('expression_profile.html')
self.assert200(response)
response = self.client.get("/profile/modal/%d" % profile.id)
self.assert_template_used('modals/expression_profile.html')
self.assert200(response)
response = self.client.get("/profile/find/" + profile.probe, follow_redirects=True)
self.assert200(response)
self.assert_template_used('expression_profile.html')
response = self.client.get("/profile/find/%s/%d" % (profile.probe, 2))
self.assert404(response)
response = self.client.get("/profile/compare/%d/%d" % (profile.id, profile.id))
self.assert_template_used('compare_profiles.html')
self.assert200(response)
response = self.client.get("/profile/compare_probes/%s/%s/%d" % (profile.probe, profile.probe, 1))
self.assert_template_used('compare_profiles.html')
self.assert200(response)
response = self.client.get("/profile/compare_probes/%s/%s/%d" % (profile.probe, profile.probe, 2))
self.assert404(response)
response = self.client.get("/profile/json/plot/%d" % profile.id)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue('type' in data.keys())
self.assertTrue('data' in data.keys())
self.assertTrue('labels' in data['data'].keys())
self.assertTrue('datasets' in data['data'].keys())
for i in range(len(data['data']['datasets'])):
self.assertTrue('data' in data['data']['datasets'][i].keys())
response = self.client.get("/profile/json/compare_plot/%d/%d" % (profile.id, profile.id))
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue('type' in data.keys())
self.assertTrue('data' in data.keys())
self.assertTrue('labels' in data['data'].keys())
self.assertTrue('datasets' in data['data'].keys())
for i in range(len(data['data']['datasets'])):
self.assertTrue('data' in data['data']['datasets'][i].keys())
def test_help(self):
"""
Test for help pages (which are static)
"""
for k, v in topics.items():
response = self.client.get("/help/%s" % k)
self.assert_template_used(v)
self.assert200(response)
response = self.client.get("/help/%s" % 'term_does_not_exist')
self.assert404(response)
def test_search(self):
"""
Test different components of the search function
"""
from planet.models.sequences import Sequence
from planet.models.interpro import Interpro
from planet.models.go import GO
sequence = Sequence.query.first()
interpro = Interpro.query.first()
go = GO.query.first()
response = self.client.get('/search/keyword/%s' % sequence.name)
self.assertRedirects(response, '/sequence/view/%d' % sequence.id)
response = self.client.get('/search/keyword/%s' % interpro.label)
self.assertRedirects(response, '/interpro/view/%d' % interpro.id)
response = self.client.get('/search/keyword/%s' % go.label)
self.assertRedirects(response, '/go/view/%d' % go.id)
response = self.client.get('/search/')
self.assertRedirects(response, '/')
response = self.client.post('/search/', data=dict(terms="TEST_SEQ_01"))
self.assertRedirects(response, '/sequence/view/%d' % sequence.id)
response = self.client.post('/search/', data=dict(terms='Test label'))
self.assert_template_used('search_results.html')
self.assert200(response)
response = self.client.get('/search/json/genes/%s' % go.label)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue(sequence.id in data)
# TODO: search_enriched_clusters() is currently untested !
response = self.client.get('/search/typeahead/go/prefetch')
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue(len(data) == 1)
for d in data:
self.assertTrue('value' in d.keys())
self.assertTrue('tokens' in d.keys())
response = self.client.get('/search/typeahead/go/test.json')
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue(len(data) == 2)
for d in data:
self.assertTrue('value' in d.keys())
self.assertTrue('tokens' in d.keys())
@unittest.skipIf(not LOGIN_ENABLED, "Skipping test because LOGIN is not enabled")
def test_auth(self):
"""
Test if a user can log in
"""
response = self.client.get('/auth/login')
self.assert_template_used('login.html')
self.assert200(response)
response = self.client.post('/auth/login', data=dict(username='admin', password='admin', keep_logged='y'),
follow_redirects=True)
self.assert200(response)
self.assertTrue('You have successfully logged in.' in response.data.decode('utf-8'))
response = self.client.get('/auth/logout', follow_redirects=True)
self.assert200(response)
self.assertTrue('You have successfully logged out.' in response.data.decode('utf-8'))
response = self.client.post('/auth/login', data=dict(username='admin', password='wrong', keep_logged='y'),
follow_redirects=True)
self.assert200(response)
self.assertTrue('Invalid username or password. Please try again.' in response.data.decode('utf-8'))
@unittest.skipIf(not BLAST_ENABLED, "Skipping test because BLAST is not enabled")
def test_blast(self):
"""
Test basic components of the BLAST search
TODO: check if BLAST is configured correctly !
"""
response = self.client.get('/blast/')
self.assert_template_used('blast.html')
self.assert200(response)
response = self.client.get('/blast/results/testtoken')
self.assert_template_used('blast.html')
self.assert200(response)
response = self.client.get('/blast/results/json/testtoken')
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertTrue('status' in data)
def test_heatmap(self):
from planet.models.expression_profiles import ExpressionProfile
from planet.models.coexpression_clusters import CoexpressionCluster
profile = ExpressionProfile.query.first()
cluster = CoexpressionCluster.query.first()
response = self.client.get('/heatmap/')
self.assert_template_used('expression_heatmap.html')
self.assert200(response)
response = self.client.post('/heatmap/', data=dict(probes=profile.probe, species_id=profile.species_id))
self.assert_template_used('expression_heatmap.html')
self.assert200(response)
self.assertTrue('<td>' + profile.probe + '</td>' in response.data.decode('utf-8'))
response = self.client.get('/heatmap/cluster/%d' % cluster.id)
self.assert_template_used('expression_heatmap.html')
self.assert200(response)
def test_profile_comparison(self):
from planet.models.expression_profiles import ExpressionProfile
from planet.models.coexpression_clusters import CoexpressionCluster
profile = ExpressionProfile.query.first()
cluster = CoexpressionCluster.query.first()
response = self.client.get('/profile_comparison/')
self.assert_template_used('expression_profile_comparison.html')
self.assert200(response)
response = self.client.post('/profile_comparison/', data=dict(probes=profile.probe, species_id=profile.species_id, normalize='y'))
self.assert_template_used('expression_profile_comparison.html')
self.assert200(response)
response = self.client.post('/profile_comparison/', data=dict(probes=profile.probe, species_id=profile.species_id, normalize='n'))
self.assert_template_used('expression_profile_comparison.html')
self.assert200(response)
response = self.client.get('/profile_comparison/cluster/%d/%d' % (cluster.id, 0))
self.assert_template_used('expression_profile_comparison.html')
self.assert200(response)
response = self.client.get('/profile_comparison/cluster/%d/%d' % (cluster.id, 1))
self.assert_template_used('expression_profile_comparison.html')
self.assert200(response)
def test_expression_network(self):
from planet.models.species import Species
from planet.models.expression_networks import ExpressionNetwork
species = Species.query.first()
expression_network = ExpressionNetwork.query.first()
response = self.client.get('/network/')
self.assert_template_used('expression_network.html')
self.assert200(response)
self.assertTrue(species.name in response.data.decode('utf-8'))
response = self.client.get('/network/species/%d' % species.id)
self.assert_template_used('expression_network.html')
self.assert200(response)
self.assertTrue(species.name in response.data.decode('utf-8'))
response = self.client.get('/network/graph/%d' % expression_network.id)
self.assert_template_used('expression_graph.html')
self.assert200(response)
response = self.client.get('/network/json/%d' % expression_network.id)
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertCytoscapeJson(data)
def test_coexpression_cluster(self):
from planet.models.species import Species
from planet.models.coexpression_clusters import CoexpressionCluster
from planet.models.gene_families import GeneFamilyMethod
species = Species.query.first()
cluster = CoexpressionCluster.query.first()
sequence = cluster.sequences.first()
gf_method = GeneFamilyMethod.query.first()
response = self.client.get('/cluster/')
self.assert_template_used('expression_cluster.html')
self.assert200(response)
self.assertTrue(species.name in response.data.decode('utf-8'))
response = self.client.get('/cluster/view/%d' % cluster.id)
self.assert_template_used('expression_cluster.html')
self.assert200(response)
response = self.client.get('/cluster/sequences/%d/%d' % (cluster.id, 1))
self.assert200(response)
self.assert_template_used('pagination/cluster_probes.html')
self.assertTrue(sequence.name in response.data.decode('utf-8'))
response = self.client.get('/cluster/download/%d' % cluster.id)
self.assert200(response)
self.assertTrue(sequence.name in response.data.decode('utf-8'))
response = self.client.get('/cluster/graph/%d/%d' % (cluster.id, gf_method.id))
self.assert200(response)
self.assert_template_used('expression_graph.html')
response = self.client.get('/cluster/json/%d/%d' % (cluster.id, gf_method.id))
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertCytoscapeJson(data)
def test_graph_comparison(self):
from planet.models.coexpression_clusters import CoexpressionCluster
from planet.models.gene_families import GeneFamilyMethod
cluster = CoexpressionCluster.query.first()
gf_method = GeneFamilyMethod.query.first()
response = self.client.get('/graph_comparison/cluster/%d/%d/%d' % (cluster.id, cluster.id, gf_method.id))
self.assert200(response)
self.assert_template_used('expression_graph.html')
response = self.client.get('/graph_comparison/cluster/json/%d/%d/%d' % (cluster.id, cluster.id, gf_method.id))
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertCytoscapeJson(data)
def test_clades(self):
from planet.models.clades import Clade
from planet.models.gene_families import GeneFamily
from planet.models.interpro import Interpro
clade = Clade.query.first()
family = GeneFamily.query.first()
interpro = Interpro.query.first()
response = self.client.get('/clade/')
self.assertRedirects(response, "/")
response = self.client.get('/clade/view/%d' % clade.id)
self.assert200(response)
self.assert_template_used('clade.html')
response = self.client.get('/clade/families/%d/1' % clade.id)
self.assert200(response)
self.assert_template_used('pagination/families.html')
response = self.client.get('/clade/families/table/%d' % clade.id)
self.assert200(response)
self.assert_template_used('tables/families.csv')
self.assertTrue(family.name in response.data.decode('utf-8'))
response = self.client.get('/clade/interpro/%d/1' % clade.id)
self.assert200(response)
self.assert_template_used('pagination/interpro.html')
response = self.client.get('/clade/interpro/table/%d' % clade.id)
self.assert200(response)
self.assert_template_used('tables/interpro.csv')
self.assertTrue(interpro.label in response.data.decode('utf-8'))
def test_ecc(self):
from planet.models.relationships import SequenceSequenceECCAssociation
ecc = SequenceSequenceECCAssociation.query.first()
response = self.client.get('/ecc/')
self.assertRedirects(response, "/")
response = self.client.get('/ecc/graph/%d/%d/%d' % (ecc.query_id, ecc.query_network_method_id, ecc.gene_family_method.id))
self.assert200(response)
self.assert_template_used('expression_graph.html')
response = self.client.get('/ecc/json/%d/%d/%d' % (ecc.query_id, ecc.query_network_method_id, ecc.gene_family_method.id))
self.assert200(response)
data = json.loads(response.data.decode('utf-8'))
self.assertCytoscapeJson(data, ecc_graph=True)
def test_specificity_search(self):
from planet.models.sequences import Sequence
response = self.client.get('/search/specific/profiles')
self.assert200(response)
self.assert_template_used('search_specific_profiles.html')
# first gene should be in the results
sequence = Sequence.query.first()
response = self.client.post('/search/specific/profiles', data=dict(species=1,
methods=1,
conditions="root 21d",
cutoff=0.85))
self.assert200(response)
self.assert_template_used('search_specific_profiles.html')
self.assertTrue(sequence.name in response.data.decode('utf-8'))