From 375935b23778148eba40ebce4a4f4def823aa3f0 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 15 Feb 2018 15:00:47 +0000 Subject: Requests added --- test/requests/test-website.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100755 test/requests/test-website.py (limited to 'test/requests') diff --git a/test/requests/test-website.py b/test/requests/test-website.py new file mode 100755 index 00000000..d02b71aa --- /dev/null +++ b/test/requests/test-website.py @@ -0,0 +1,20 @@ +# Run with something like +# +# env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 +# +# Mostly to pick up the Guix GN2_PROFILE and python modules + +import requests as req +import sys + +print "Mechanical Rob firing up..." + +if len(sys.argv)<1: + raise "Problem with arguments" + +url = sys.argv[1] +print url + +r = req.get(url) + +print r -- cgit v1.2.3 From c5b1028a15c771508b2b88994869912330c1148e Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 16 Feb 2018 14:22:17 +0300 Subject: Add registration test * Add integration test to check the registration process. --- test/requests/test-registration.py | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/requests/test-registration.py (limited to 'test/requests') diff --git a/test/requests/test-registration.py b/test/requests/test-registration.py new file mode 100644 index 00000000..bcb1642f --- /dev/null +++ b/test/requests/test-registration.py @@ -0,0 +1,59 @@ +import sys +import unittest +import requests +import logging +from elasticsearch import Elasticsearch, TransportError +#from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + +GN2_SERVER = None +ES_SERVER = None + +class TestRegistration(unittest.TestCase): + + + def setUp(self): + self.url = GN2_SERVER+"/n/register" + self.es = Elasticsearch([ES_SERVER]) + self.es_cleanup = [] + + es_logger = logging.getLogger("elasticsearch") + es_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) + es_trace_logger = logging.getLogger("elasticsearch.trace") + es_trace_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) + + def tearDown(self): + for item in self.es_cleanup: + self.es.delete(index="users", doc_type="local", id=item["_id"]) + + def testRegistrationPage(self): + if self.es.ping(): + data = { + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + requests.post(self.url, data) + response = self.es.search( + index="users" + , doc_type="local" + , body={ + "query": {"match": {"email_address": "test@user.com"}}}) + self.assertEqual(len(response["hits"]["hits"]), 1) + self.es_cleanup.append(response["hits"]["hits"][0]) + else: + self.skipTest("The elasticsearch server is down") + +def main(): + suite = unittest.TestSuite() + suite.addTest(TestRegistration("testRegistrationPage")) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + GN2_SERVER = sys.argv[1] + ES_SERVER = sys.argv[2] + main() -- cgit v1.2.3 From 0f1197ce8afdc2a869e4cc6f78122641df009e42 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:46:47 +0300 Subject: Rename file and move common code * Rename the file to make it an importable module * Refactor the test to move common code out to a super class. --- test/requests/test-registration.py | 59 -------------------------------------- test/requests/test_registration.py | 41 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 59 deletions(-) delete mode 100644 test/requests/test-registration.py create mode 100644 test/requests/test_registration.py (limited to 'test/requests') diff --git a/test/requests/test-registration.py b/test/requests/test-registration.py deleted file mode 100644 index bcb1642f..00000000 --- a/test/requests/test-registration.py +++ /dev/null @@ -1,59 +0,0 @@ -import sys -import unittest -import requests -import logging -from elasticsearch import Elasticsearch, TransportError -#from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT - -GN2_SERVER = None -ES_SERVER = None - -class TestRegistration(unittest.TestCase): - - - def setUp(self): - self.url = GN2_SERVER+"/n/register" - self.es = Elasticsearch([ES_SERVER]) - self.es_cleanup = [] - - es_logger = logging.getLogger("elasticsearch") - es_logger.addHandler( - logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) - es_trace_logger = logging.getLogger("elasticsearch.trace") - es_trace_logger.addHandler( - logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) - - def tearDown(self): - for item in self.es_cleanup: - self.es.delete(index="users", doc_type="local", id=item["_id"]) - - def testRegistrationPage(self): - if self.es.ping(): - data = { - "email_address": "test@user.com", - "full_name": "Test User", - "organization": "Test Organisation", - "password": "test_password", - "password_confirm": "test_password" - } - requests.post(self.url, data) - response = self.es.search( - index="users" - , doc_type="local" - , body={ - "query": {"match": {"email_address": "test@user.com"}}}) - self.assertEqual(len(response["hits"]["hits"]), 1) - self.es_cleanup.append(response["hits"]["hits"][0]) - else: - self.skipTest("The elasticsearch server is down") - -def main(): - suite = unittest.TestSuite() - suite.addTest(TestRegistration("testRegistrationPage")) - runner = unittest.TextTestRunner() - runner.run(suite) - -if __name__ == "__main__": - GN2_SERVER = sys.argv[1] - ES_SERVER = sys.argv[2] - main() diff --git a/test/requests/test_registration.py b/test/requests/test_registration.py new file mode 100644 index 00000000..0047e8a6 --- /dev/null +++ b/test/requests/test_registration.py @@ -0,0 +1,41 @@ +import sys +import requests +from parametrized_test import ParametrizedTest + +class TestRegistration(ParametrizedTest): + + def tearDown(self): + for item in self.es_cleanup: + self.es.delete(index="users", doc_type="local", id=item["_id"]) + + def testRegistrationPage(self): + if self.es.ping(): + data = { + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + requests.post(self.gn2_url+"/n/register", data) + response = self.es.search( + index="users" + , doc_type="local" + , body={ + "query": {"match": {"email_address": "test@user.com"}}}) + self.assertEqual(len(response["hits"]["hits"]), 1) + else: + self.skipTest("The elasticsearch server is down") + +def main(gn2, es): + import unittest + suite = unittest.TestSuite() + suite.addTest(TestRegistration(methodName="testRegistrationPage", gn2_url=gn2, es_url=es)) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception("Required arguments missing") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From f74b1615567d5cbf2cb00572cc14450ffd4b0c1c Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:48:36 +0300 Subject: Create parametrized superclass for tests * Since the tests require that some parameters be provided while running the tests, create a class that helps abstract away the details of retrieving and setting the expected parameters. --- test/requests/parametrized_test.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/requests/parametrized_test.py (limited to 'test/requests') diff --git a/test/requests/parametrized_test.py b/test/requests/parametrized_test.py new file mode 100644 index 00000000..abf98fce --- /dev/null +++ b/test/requests/parametrized_test.py @@ -0,0 +1,27 @@ +import logging +import unittest +from elasticsearch import Elasticsearch, TransportError + +class ParametrizedTest(unittest.TestCase): + + def __init__(self, methodName='runTest', gn2_url="http://localhost:5003", es_url="localhost:9200"): + super(ParametrizedTest, self).__init__(methodName=methodName) + self.gn2_url = gn2_url + self.es_url = es_url + + def setUp(self): + self.es = Elasticsearch([self.es_url]) + self.es_cleanup = [] + + es_logger = logging.getLogger("elasticsearch") + es_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationInfo.log")) + es_trace_logger = logging.getLogger("elasticsearch.trace") + es_trace_logger.addHandler( + logging.FileHandler("/tmp/es_TestRegistrationTrace.log")) + + def tearDown(self): + self.es.delete_by_query( + index="users" + , doc_type="local" + , body={"query":{"match":{"email_address":"test@user.com"}}}) -- cgit v1.2.3 From c84bd98971aa5839cb6aa999889a92071890f579 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:50:30 +0300 Subject: Add test for local login * Add an integration test to test that the login process for users registered locally to genenetwork2 works as expected. --- test/requests/test_login_local.py | 56 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test/requests/test_login_local.py (limited to 'test/requests') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py new file mode 100644 index 00000000..bced1ee9 --- /dev/null +++ b/test/requests/test_login_local.py @@ -0,0 +1,56 @@ +import requests +from wqflask import user_manager +from parametrized_test import ParametrizedTest + +class TestLoginLocal(ParametrizedTest): + + def setUp(self): + super(TestLoginLocal, self).setUp() + self.login_url = self.gn2_url +"/n/login" + data = { + "es_connection": self.es, + "email_address": "test@user.com", + "full_name": "Test User", + "organization": "Test Organisation", + "password": "test_password", + "password_confirm": "test_password" + } + user_manager.basic_info = lambda : { "basic_info": "basic" } + user_manager.RegisterUser(data) + + def testLoginNonRegisteredUser(self): + data = { + "email_address": "non@existent.email", + "password": "doesitmatter?" + } + result = requests.post(self.login_url, data=data) + self.assertEqual(result.url, self.login_url, "") + + def testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse(self): + data = { + "email_address": "test@user.com", + "password": "test_password" + } + result = requests.post(self.login_url, data=data) + print("THE COOKIES? ", result.cookies) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=false" + , "Login should have been successful") + + + +def main(gn2, es): + import unittest + suite = unittest.TestSuite() + suite.addTest(TestLoginLocal(methodName="testLoginNonRegisteredUser", gn2_url=gn2, es_url=es)) + suite.addTest(TestLoginLocal(methodName="testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse", gn2_url=gn2, es_url=es)) + runner = unittest.TextTestRunner() + runner.run(suite) + +if __name__ == "__main__": + import sys + if len(sys.argv) < 3: + raise Exception("Required arguments missing") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From db86c21577e50b30ee222c47aae43e49a574c007 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 12:52:32 +0300 Subject: Add a runner for all integration tests. --- test/requests/run-integration-tests.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 test/requests/run-integration-tests.py (limited to 'test/requests') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py new file mode 100644 index 00000000..0fd7bb20 --- /dev/null +++ b/test/requests/run-integration-tests.py @@ -0,0 +1,30 @@ +import sys +from test_login_local import TestLoginLocal +from test_registration import TestRegistration +from unittest import TestSuite, TextTestRunner, TestLoader + +test_cases = [ + TestLoginLocal, + TestRegistration +] + +def suite(gn2_url, es_url): + the_suite = TestSuite() + for case in test_cases: + the_suite.addTests(initTest(case, gn2_url, es_url)) + return the_suite + +def initTest(klass, gn2_url, es_url): + loader = TestLoader() + methodNames = loader.getTestCaseNames(klass) + return [klass(mname, gn2_url, es_url) for mname in methodNames] + +def main(gn2_url, es_url): + runner = TextTestRunner() + runner.run(suite(gn2_url, es_url)) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise Exception("Required arguments missing:\n\tTry running `run-integration-test.py `") + else: + main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From e4b7e72d83a6dba40a38c58e62e338bd257862ef Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 19 Feb 2018 14:12:59 +0300 Subject: Add more login tests. --- test/requests/test_login_local.py | 39 +++++++++++++++++++++++++++++++++++++-- wqflask/wqflask/user_manager.py | 2 -- 2 files changed, 37 insertions(+), 4 deletions(-) (limited to 'test/requests') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index bced1ee9..acad45c9 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -32,12 +32,47 @@ class TestLoginLocal(ParametrizedTest): "password": "test_password" } result = requests.post(self.login_url, data=data) - print("THE COOKIES? ", result.cookies) self.assertEqual( result.url , self.gn2_url+"/?import_collections=false" , "Login should have been successful") - + + def testLoginWithRegisteredUserImportCollectionsTrueAndRememberMeFalse(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "import_collections": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=true" + , "Login should have been successful") + + def testLoginWithRegisteredUserImportCollectionsFalseAndRememberMeTrue(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=false" + , "Login should have been successful") + + def testLoginWithRegisteredUserBothImportCollectionsAndRememberMeTrue(self): + data = { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y", + "import_collections": "y" + } + result = requests.post(self.login_url, data=data) + self.assertEqual( + result.url + , self.gn2_url+"/?import_collections=true" + , "Login should have been successful") def main(gn2, es): diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index c8471cb1..fd1d56ff 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -642,7 +642,6 @@ class LoginUser(object): user = model.User(); for key in user_details: user.__dict__[key] = user_details[key] - print("RETRIEVED USER: ", user) valid = False; submitted_password = params['password'] @@ -689,7 +688,6 @@ class LoginUser(object): """The meat of the logging in process""" session_id_signed = self.successful_login(user, assumed_by) flash("Thank you for logging in {}.".format(user.full_name), "alert-success") - print("IMPORT1:", import_collections) response = make_response(redirect(url_for('index_page', import_collections=import_collections))) if self.remember_me: max_age = self.remember_time -- cgit v1.2.3 From e1e3ea41578947e47b2f394e6e3ba4f45eceeb82 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 21 Feb 2018 12:51:34 +0300 Subject: Simplify test. Check for content, rather than url * The test functions were very similar, so this commit refactors out the common test code to a single method, and passes in the data to the test using the parameterized package. * Check that the page content after a login attempt is the expected content, rather than checking the url. --- test/requests/test_login_local.py | 93 ++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 54 deletions(-) (limited to 'test/requests') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index acad45c9..8e2dec4e 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -1,7 +1,11 @@ import requests from wqflask import user_manager +from parameterized import parameterized from parametrized_test import ParametrizedTest +login_link_text = 'Sign in' +logout_link_text = 'Sign out' + class TestLoginLocal(ParametrizedTest): def setUp(self): @@ -18,61 +22,42 @@ class TestLoginLocal(ParametrizedTest): user_manager.basic_info = lambda : { "basic_info": "basic" } user_manager.RegisterUser(data) - def testLoginNonRegisteredUser(self): - data = { - "email_address": "non@existent.email", - "password": "doesitmatter?" - } - result = requests.post(self.login_url, data=data) - self.assertEqual(result.url, self.login_url, "") - - def testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse(self): - data = { - "email_address": "test@user.com", - "password": "test_password" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=false" - , "Login should have been successful") - - def testLoginWithRegisteredUserImportCollectionsTrueAndRememberMeFalse(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "import_collections": "y" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=true" - , "Login should have been successful") - - def testLoginWithRegisteredUserImportCollectionsFalseAndRememberMeTrue(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "remember_me": "y" - } - result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=false" - , "Login should have been successful") - - def testLoginWithRegisteredUserBothImportCollectionsAndRememberMeTrue(self): - data = { - "email_address": "test@user.com", - "password": "test_password", - "remember_me": "y", - "import_collections": "y" - } + + @parameterized.expand([ + ( + { + "email_address": "non@existent.email", + "password": "doesitmatter?" + }, login_link_text, "Login should have failed with the wrong user details."), + ( + { + "email_address": "test@user.com", + "password": "test_password" + }, logout_link_text, "Login should have been successful with correct user details and neither import_collections nor remember_me set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "import_collections": "y" + }, logout_link_text, "Login should have been successful with correct user details and only import_collections set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y" + }, logout_link_text, "Login should have been successful with correct user details and only remember_me set"), + ( + { + "email_address": "test@user.com", + "password": "test_password", + "remember_me": "y", + "import_collections": "y" + }, logout_link_text, "Login should have been successful with correct user details, and both remember_me, and import_collections set") + ]) + def testLogin(self, data, expected, message): result = requests.post(self.login_url, data=data) - self.assertEqual( - result.url - , self.gn2_url+"/?import_collections=true" - , "Login should have been successful") + index = result.content.find(expected) + self.assertTrue(index >= 0, message) def main(gn2, es): -- cgit v1.2.3 From e982d7223141d247954ab5b5c1ff9bbed907c603 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:24:55 +0300 Subject: Remove failing code * With the parameterized module, the testcase cannot be run independently at this time. --- test/requests/test_login_local.py | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'test/requests') diff --git a/test/requests/test_login_local.py b/test/requests/test_login_local.py index 8e2dec4e..808649ca 100644 --- a/test/requests/test_login_local.py +++ b/test/requests/test_login_local.py @@ -58,19 +58,3 @@ class TestLoginLocal(ParametrizedTest): result = requests.post(self.login_url, data=data) index = result.content.find(expected) self.assertTrue(index >= 0, message) - - -def main(gn2, es): - import unittest - suite = unittest.TestSuite() - suite.addTest(TestLoginLocal(methodName="testLoginNonRegisteredUser", gn2_url=gn2, es_url=es)) - suite.addTest(TestLoginLocal(methodName="testLoginWithRegisteredUserBothRememberMeAndImportCollectionsFalse", gn2_url=gn2, es_url=es)) - runner = unittest.TextTestRunner() - runner.run(suite) - -if __name__ == "__main__": - import sys - if len(sys.argv) < 3: - raise Exception("Required arguments missing") - else: - main(sys.argv[1], sys.argv[2]) -- cgit v1.2.3 From 7ea87a27735242889ac369dcbd5aec83a1e1caff Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:26:42 +0300 Subject: Add new test for github logins --- test/requests/run-integration-tests.py | 4 +++- test/requests/test_login_github.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/requests/test_login_github.py (limited to 'test/requests') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py index 0fd7bb20..fc795779 100644 --- a/test/requests/run-integration-tests.py +++ b/test/requests/run-integration-tests.py @@ -1,11 +1,13 @@ import sys from test_login_local import TestLoginLocal +from test_login_github import TestLoginGithub from test_registration import TestRegistration from unittest import TestSuite, TextTestRunner, TestLoader test_cases = [ - TestLoginLocal, TestRegistration + , TestLoginLocal + , TestLoginGithub ] def suite(gn2_url, es_url): diff --git a/test/requests/test_login_github.py b/test/requests/test_login_github.py new file mode 100644 index 00000000..15bf18ae --- /dev/null +++ b/test/requests/test_login_github.py @@ -0,0 +1,40 @@ +import uuid +import requests +from time import sleep +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +login_link_text = 'Sign in' +logout_link_text = 'Sign out' +uid = str(uuid.uuid4()) + +class TestLoginGithub(ParametrizedTest): + + def setUp(self): + super(TestLoginGithub, self).setUp() + data = { + "user_id": uid + , "name": "A. T. Est User" + , "github_id": 693024 + , "user_url": "https://fake-github.com/atestuser" + , "login_type": "github" + , "organization": "" + , "active": 1 + , "confirmed": 1 + } + self.es.create(index="users", doc_type="local", body=data, id=uid) + sleep(1) + + def tearDown(self): + super(TestLoginGithub, self).tearDown() + self.es.delete(index="users", doc_type="local", id=uid) + + @parameterized.expand([ + ("1234", login_link_text, "Login should have failed with non-existing user") + , (uid, logout_link_text, "Login should have been successful with existing user") + ]) + def testLogin(self, test_uid, expected, message): + url = self.gn2_url+"/n/login?type=github&uid="+test_uid + result = requests.get(url) + index = result.content.find(expected) + self.assertTrue(index >= 0, message) -- cgit v1.2.3 From 20d9af4812426e4457e7417cfcea601c1a870168 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 17:36:29 +0300 Subject: Add new tests for orcid logins --- test/requests/run-integration-tests.py | 2 ++ test/requests/test_login_orcid.py | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/requests/test_login_orcid.py (limited to 'test/requests') diff --git a/test/requests/run-integration-tests.py b/test/requests/run-integration-tests.py index fc795779..5e816549 100644 --- a/test/requests/run-integration-tests.py +++ b/test/requests/run-integration-tests.py @@ -1,5 +1,6 @@ import sys from test_login_local import TestLoginLocal +from test_login_orcid import TestLoginOrcid from test_login_github import TestLoginGithub from test_registration import TestRegistration from unittest import TestSuite, TextTestRunner, TestLoader @@ -8,6 +9,7 @@ test_cases = [ TestRegistration , TestLoginLocal , TestLoginGithub + , TestLoginOrcid ] def suite(gn2_url, es_url): diff --git a/test/requests/test_login_orcid.py b/test/requests/test_login_orcid.py new file mode 100644 index 00000000..6e40ece5 --- /dev/null +++ b/test/requests/test_login_orcid.py @@ -0,0 +1,40 @@ +import uuid +import requests +from time import sleep +from parameterized import parameterized +from parametrized_test import ParametrizedTest + +login_link_text = 'Sign in' +logout_link_text = 'Sign out' +uid = str(uuid.uuid4()) + +class TestLoginOrcid(ParametrizedTest): + + def setUp(self): + super(TestLoginOrcid, self).setUp() + data = { + "user_id": uid + , "name": "A. T. Est User" + , "orcid": 345872 + , "user_url": "https://fake-orcid.org/atestuser" + , "login_type": "orcid" + , "organization": "" + , "active": 1 + , "confirmed": 1 + } + self.es.create(index="users", doc_type="local", body=data, id=uid) + sleep(1) + + def tearDown(self): + super(TestLoginOrcid, self).tearDown() + self.es.delete(index="users", doc_type="local", id=uid) + + @parameterized.expand([ + ("1234", login_link_text, "Login should have failed with non-existing user") + , (uid, logout_link_text, "Login should have been successful with existing user") + ]) + def testLogin(self, test_uid, expected, message): + url = self.gn2_url+"/n/login?type=orcid&uid="+test_uid + result = requests.get(url) + index = result.content.find(expected) + self.assertTrue(index >= 0, message) -- cgit v1.2.3 From 07b792f0898d7ecec94b938aa3081e6aa64bc435 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 23 Feb 2018 18:11:33 +0300 Subject: Add tests to check that the UI is setup correctly * Check that the links for OAuth2 logins via ORCID and GitHub are setup correctly. --- test/requests/test_login_github.py | 7 +++++++ test/requests/test_login_orcid.py | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'test/requests') diff --git a/test/requests/test_login_github.py b/test/requests/test_login_github.py index 15bf18ae..1bf4f695 100644 --- a/test/requests/test_login_github.py +++ b/test/requests/test_login_github.py @@ -1,6 +1,7 @@ import uuid import requests from time import sleep +from wqflask import app from parameterized import parameterized from parametrized_test import ParametrizedTest @@ -29,6 +30,12 @@ class TestLoginGithub(ParametrizedTest): super(TestLoginGithub, self).tearDown() self.es.delete(index="users", doc_type="local", id=uid) + def testLoginUrl(self): + login_button_text = 'Login with Github' + result = requests.get(self.gn2_url+"/n/login") + index = result.content.find(login_button_text) + self.assertTrue(index >= 0, "Should have found `Login with Github` button") + @parameterized.expand([ ("1234", login_link_text, "Login should have failed with non-existing user") , (uid, logout_link_text, "Login should have been successful with existing user") diff --git a/test/requests/test_login_orcid.py b/test/requests/test_login_orcid.py index 6e40ece5..ea15642e 100644 --- a/test/requests/test_login_orcid.py +++ b/test/requests/test_login_orcid.py @@ -1,6 +1,7 @@ import uuid import requests from time import sleep +from wqflask import app from parameterized import parameterized from parametrized_test import ParametrizedTest @@ -29,6 +30,12 @@ class TestLoginOrcid(ParametrizedTest): super(TestLoginOrcid, self).tearDown() self.es.delete(index="users", doc_type="local", id=uid) + def testLoginUrl(self): + login_button_text = 'a href="https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=' + app.config.get("ORCID_CLIENT_ID") + '&client_secret=' + app.config.get("ORCID_CLIENT_SECRET") + '" title="Login with ORCID" class="btn btn-info btn-group">Login with ORCID' + result = requests.get(self.gn2_url+"/n/login") + index = result.content.find(login_button_text) + self.assertTrue(index >= 0, "Should have found `Login with ORCID` button") + @parameterized.expand([ ("1234", login_link_text, "Login should have failed with non-existing user") , (uid, logout_link_text, "Login should have been successful with existing user") -- cgit v1.2.3 From 428371a67a7c742e239d96914a96558171f9f59e Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Mar 2018 18:12:58 +0300 Subject: Use argparse to handle arguments * Use argparse to handle commandline arguments. * Create initial layout of how the code might end up - lots of the code is currently commented out. --- test/requests/test-website.py | 60 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 9 deletions(-) (limited to 'test/requests') diff --git a/test/requests/test-website.py b/test/requests/test-website.py index d02b71aa..9637b87f 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -3,18 +3,60 @@ # env GN2_PROFILE=/home/wrk/opt/gn-latest ./bin/genenetwork2 ./etc/default_settings.py -c ../test/requests/test-website.py http://localhost:5003 # # Mostly to pick up the Guix GN2_PROFILE and python modules +from __future__ import print_function +from link_checker import check_links +import argparse -import requests as req -import sys +print("Mechanical Rob firing up...") -print "Mechanical Rob firing up..." +def run_all(args_obj, parser): + print("") + print("Running all tests.") + check_links(args_obj, parser) + # TODO: Add other functions as they are created. -if len(sys.argv)<1: - raise "Problem with arguments" +def print_help(args_obj, parser): + print(parser.format_help()) -url = sys.argv[1] -print url +def dummy(args_obj, parser): + print("Not implemented yet.") -r = req.get(url) -print r +desc = """ +This is Mechanical-Rob - an automated web server tester for + Genenetwork.org +""" +parser = argparse.ArgumentParser(description=desc) + +parser.add_argument("-d", "--database", metavar="DB", type=str + , default="db_webqtl_s" + , help="Use database (default db_webqtl_s)") + +parser.add_argument("host", metavar="HOST", type=str + , default="http://localhost:5003" + , help="The url to the web server") + +parser.add_argument("-a", "--all", dest="accumulate", action="store_const" + , const=run_all, default=print_help + , help="Runs all tests.") + +parser.add_argument("-l", "--link-checker", dest="accumulate" + , action='store_const', const=check_links, default=print_help + , help="Checks for dead links.") + +# parser.add_argument("-n", "--navigation", dest="accumulate" +# , action="store_const", const=check_navigation, default=print_help +# , help="Checks for navigation.") + +# parser.add_argument("-m", "--mapping", dest="accumulate" +# , action="store_const", const=check_mapping, default=print_help +# , help="Checks for mapping.") + +# parser.add_argument("-s", "--skip-broken", dest="accumulate" +# , action="store_const", const=dummy, default=print_help +# , help="Skip tests that are known to be broken.") + +args = parser.parse_args() +# print("The arguments object: ", args) + +args.accumulate(args, parser) -- cgit v1.2.3 From a29c16b770aa0bb53c632eecc1764caf02789fe7 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Mar 2018 18:15:19 +0300 Subject: Add link_checker module * Add the module that will hold the code to test the links on the system. --- test/requests/link_checker.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 test/requests/link_checker.py (limited to 'test/requests') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py new file mode 100644 index 00000000..f171c12a --- /dev/null +++ b/test/requests/link_checker.py @@ -0,0 +1,9 @@ +import requests + +def check_links(args_obj, parser): + print("") + print("Checking links") + print("########################") + print("Not implemented yet.") + print("This is supposed to check all links in the system.") + print("########################") -- cgit v1.2.3 From dd5ec1d3080b74fa065620f6915eeacf2cca8a2d Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 12 Mar 2018 13:00:03 +0300 Subject: Add tests to check links. --- test/requests/link_checker.py | 62 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'test/requests') diff --git a/test/requests/link_checker.py b/test/requests/link_checker.py index f171c12a..256bf6ef 100644 --- a/test/requests/link_checker.py +++ b/test/requests/link_checker.py @@ -1,9 +1,63 @@ +from __future__ import print_function +import re import requests +from lxml.html import parse +from requests.exceptions import ConnectionError + +def is_root_link(link): + pattern = re.compile("^/$") + return pattern.match(link) + +def is_mailto_link(link): + pattern = re.compile("^mailto:.*") + return pattern.match(link) + +def is_internal_link(link): + pattern = re.compile("^/.*") + return pattern.match(link) + +def get_links(doc): + return filter( + lambda x: not ( + is_root_link(x) + or is_mailto_link(x)) + , map(lambda y: y.get("href") + , doc.cssselect("a"))) + +def verify_link(link): + try: + result = requests.get(link, timeout=20) + if result.status_code == 200: + print(link+" ==> OK") + else: + print("ERROR: link `"+link+"` failed with status " + , result.status_code) + except ConnectionError as ex: + print("ERROR: ", link, ex) + +def check_page(host, start_url): + print("") + print("Checking links in page `"+start_url+"`") + doc = parse(start_url).getroot() + links = get_links(doc) + internal_links = filter(is_internal_link, links) + external_links = filter(lambda x: not is_internal_link(x), links) + external_links.append("http://somenon-existentsite.brr") + for link in internal_links: + verify_link(host+link) + + for link in external_links: + verify_link(link) def check_links(args_obj, parser): print("") print("Checking links") - print("########################") - print("Not implemented yet.") - print("This is supposed to check all links in the system.") - print("########################") + host = args_obj.host + + # Check the home page + check_page(host, host) + + # Check traits page + check_page( + host, + host+"/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") -- cgit v1.2.3 From 8ff3dbd9bd5737b6cd0df8d279a70073c40786ec Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 14 Mar 2018 02:16:59 +0300 Subject: Add tests for main web functionality --- test/requests/main_web_functionality.py | 40 +++++++++++++++++++++++++++++++++ test/requests/test-website.py | 7 ++++++ 2 files changed, 47 insertions(+) create mode 100644 test/requests/main_web_functionality.py (limited to 'test/requests') diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py new file mode 100644 index 00000000..f6b32340 --- /dev/null +++ b/test/requests/main_web_functionality.py @@ -0,0 +1,40 @@ +from __future__ import print_function +import re +import requests +from lxml.html import parse +from requests.exceptions import ConnectionError + +def check_home(url): + doc = parse(url).getroot() + search_button = doc.cssselect("#btsearch") + assert(search_button[0].value == "Search") + print("OK") + +def check_search_page(host): + data = dict( + species="mouse" + , group="BXD" + , type="Hippocampus mRNA" + , dataset="HC_M2_0606_P" + , search_terms_or="" + , search_terms_and="MEAN=(15 16) LRS=(23 46)") + result = requests.get(host+"/search", params=data) + found = result.text.find("/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + assert(found >= 0) + print("OK") + check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") + +def check_traits_page(host, traits_url): + from link_checker import check_page + doc = parse(host+traits_url).getroot() + traits_form = doc.forms[1] + assert(traits_form.fields["corr_dataset"] == "HC_M2_0606_P") + print("OK") + check_page(host, host+traits_url) + +def check_main_web_functionality(args_obj, parser): + print("") + print("Checking main web functionality...") + host = args_obj.host + check_home(host) + check_search_page(host) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index 9637b87f..f65c3fc8 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -4,6 +4,7 @@ # # Mostly to pick up the Guix GN2_PROFILE and python modules from __future__ import print_function +from main_web_functionality import check_main_web_functionality from link_checker import check_links import argparse @@ -12,6 +13,7 @@ print("Mechanical Rob firing up...") def run_all(args_obj, parser): print("") print("Running all tests.") + check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) # TODO: Add other functions as they are created. @@ -44,6 +46,11 @@ parser.add_argument("-l", "--link-checker", dest="accumulate" , action='store_const', const=check_links, default=print_help , help="Checks for dead links.") +parser.add_argument("-f", "--main-functionality", dest="accumulate" + , action='store_const', const=check_main_web_functionality + , default=print_help + , help="Checks for main web functionality.") + # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help # , help="Checks for navigation.") -- cgit v1.2.3 From 6a111c64c50ffe6daa387034ef8fc3ad3e90fc75 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 18 Mar 2018 08:54:03 +0300 Subject: Move import to the top of the page. * Mainly to tell the dependencies easily. --- test/requests/main_web_functionality.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/requests') diff --git a/test/requests/main_web_functionality.py b/test/requests/main_web_functionality.py index f6b32340..7b89b833 100644 --- a/test/requests/main_web_functionality.py +++ b/test/requests/main_web_functionality.py @@ -2,6 +2,7 @@ from __future__ import print_function import re import requests from lxml.html import parse +from link_checker import check_page from requests.exceptions import ConnectionError def check_home(url): @@ -25,7 +26,6 @@ def check_search_page(host): check_traits_page(host, "/show_trait?trait_id=1435395_s_at&dataset=HC_M2_0606_P") def check_traits_page(host, traits_url): - from link_checker import check_page doc = parse(host+traits_url).getroot() traits_form = doc.forms[1] assert(traits_form.fields["corr_dataset"] == "HC_M2_0606_P") -- cgit v1.2.3 From c3fab61242796ef4b7544d784fceb39f4545828e Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Sun, 18 Mar 2018 08:56:03 +0300 Subject: Initialise mapping tests * Add mapping tests, and build the first of the tests. --- test/requests/mapping_tests.py | 43 ++++++++++++++++++++++++++++++++++++++++++ test/requests/test-website.py | 14 ++++++++------ 2 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 test/requests/mapping_tests.py (limited to 'test/requests') diff --git a/test/requests/mapping_tests.py b/test/requests/mapping_tests.py new file mode 100644 index 00000000..fd20df11 --- /dev/null +++ b/test/requests/mapping_tests.py @@ -0,0 +1,43 @@ +from __future__ import print_function +import re +import json +import requests +from lxml.html import fromstring + +def get_data(list_item): + try: + value = list_item[1] + except: + value = None + #print("list_item:", list_item, "==>", value) + return value + +def load_data_from_file(): + filename = "../test/data/input/mapping/1435395_s_at_HC_M2_0606_P.json" + file_handle = open(filename, "r") + file_data = json.loads(file_handle.read().encode("utf-8")) + return file_data + +def check_pylmm_tool_selection(host, data): + data["method"] = "pylmm" + page = requests.post(host+"/marker_regression", data=data) + doc = fromstring(page.text) + form = doc.forms[1] + assert form.fields["dataset"] == "HC_M2_0606_P" + assert form.fields["value:BXD1"] == "15.034" # Check value in the file + +def check_R_qtl_tool_selection(host, data): + pass + +def check_CIM_tool_selection(host, data): + pass + +def check_mapping(args_obj, parser): + print("") + print("Checking mapping") + + host = args_obj.host + data = load_data_from_file() + check_pylmm_tool_selection(host, data) + check_R_qtl_tool_selection(host, data) + check_CIM_tool_selection(host, data) diff --git a/test/requests/test-website.py b/test/requests/test-website.py index f65c3fc8..2bef6eb1 100755 --- a/test/requests/test-website.py +++ b/test/requests/test-website.py @@ -4,9 +4,10 @@ # # Mostly to pick up the Guix GN2_PROFILE and python modules from __future__ import print_function -from main_web_functionality import check_main_web_functionality -from link_checker import check_links import argparse +from link_checker import check_links +from mapping_tests import check_mapping +from main_web_functionality import check_main_web_functionality print("Mechanical Rob firing up...") @@ -15,6 +16,7 @@ def run_all(args_obj, parser): print("Running all tests.") check_main_web_functionality(args_obj, parser) check_links(args_obj, parser) + check_mapping(args_obj, parser) # TODO: Add other functions as they are created. def print_help(args_obj, parser): @@ -51,14 +53,14 @@ parser.add_argument("-f", "--main-functionality", dest="accumulate" , default=print_help , help="Checks for main web functionality.") +parser.add_argument("-m", "--mapping", dest="accumulate" + , action="store_const", const=check_mapping, default=print_help + , help="Checks for mapping.") + # parser.add_argument("-n", "--navigation", dest="accumulate" # , action="store_const", const=check_navigation, default=print_help # , help="Checks for navigation.") -# parser.add_argument("-m", "--mapping", dest="accumulate" -# , action="store_const", const=check_mapping, default=print_help -# , help="Checks for mapping.") - # parser.add_argument("-s", "--skip-broken", dest="accumulate" # , action="store_const", const=dummy, default=print_help # , help="Skip tests that are known to be broken.") -- cgit v1.2.3