diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index aab7ea0..0000000 --- a/test/.gitignore +++ /dev/null @@ -1,110 +0,0 @@ - -# Created by https://www.gitignore.io/api/python -# Edit at https://www.gitignore.io/?templates=python - -### Python ### -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -pip-wheel-metadata/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# pyenv -.python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# End of https://www.gitignore.io/api/python diff --git a/test/README.md b/test/README.md deleted file mode 100644 index c63fb28..0000000 --- a/test/README.md +++ /dev/null @@ -1,39 +0,0 @@ -## Web-Base Test Suite - -### Introduction - -This script performs database and API tests on a clean local environment. It assumes, the web-base is running on http://localhost/. The test tool can either -use an existing database or create a temporary database (recommended). - -### Usage - -To use this tool, some requirements must be installed. This can be done using: `pip install -r requirements.txt` - -``` -usage: test.py [-h] [--username USERNAME] [--password PASSWORD] [--host HOST] - [--port PORT] [--database DATABASE] [--force] - DBMS - -Web-Base database test suite - -positional arguments: - DBMS the dbms to setup, must be one of: mysql, postgres, - oracle - -optional arguments: - -h, --help show this help message and exit - --username USERNAME, -u USERNAME - the username used for connecting to the dbms, default: - root - --password PASSWORD, -p PASSWORD - the password used for connecting to the dbms, default: - (empty) - --host HOST, -H HOST the host where the dbms is running on, default: - localhost - --port PORT, -P PORT the port where the dbms is running on, default: - (depends on dbms) - --database DATABASE, -d DATABASE - the name of the database for the test suite, default: - randomly chosen and created - --force Delete existing configuration files -``` diff --git a/test/apiTest.py b/test/apiTest.py deleted file mode 100644 index 6ee848f..0000000 --- a/test/apiTest.py +++ /dev/null @@ -1,72 +0,0 @@ -from phpTest import PhpTest - -class ApiTestCase(PhpTest): - - def __init__(self): - super().__init__({ - "Testing login…": self.test_login, - "Testing already logged in…": self.test_already_logged_in, - - # ApiKeys - "Testing get api keys empty…": self.test_get_api_keys_empty, - "Testing create api key…": self.test_create_api_key, - "Testing refresh api key…": self.test_refresh_api_key, - "Testing revoke api key…": self.test_revoke_api_key, - - # Notifications - "Testing fetch notifications…": self.test_fetch_notifications, - - "Testing logout…": self.test_logout, - }) - - def api(self, method): - return "/api/%s" % method - - def getApiKeys(self): - obj = self.httpPost(self.api("apiKey/fetch")) - self.assertEquals(True, obj["success"], obj["msg"]) - return obj - - def test_login(self): - obj = self.httpPost(self.api("user/login"), data={ "username": PhpTest.ADMIN_USERNAME, "password": PhpTest.ADMIN_PASSWORD }) - self.assertEquals(True, obj["success"], obj["msg"]) - return obj - - def test_already_logged_in(self): - obj = self.test_login() - self.assertEquals("You are already logged in", obj["msg"]) - - def test_get_api_keys_empty(self): - obj = self.getApiKeys() - self.assertEquals([], obj["api_keys"]) - - def test_create_api_key(self): - obj = self.httpPost(self.api("apiKey/create")) - self.assertEquals(True, obj["success"], obj["msg"]) - self.assertTrue("api_key" in obj) - self.apiKey = obj["api_key"] - - obj = self.getApiKeys() - self.assertEquals(1, len(obj["api_keys"])) - self.assertDictEqual(self.apiKey, obj["api_keys"][0]) - - def test_refresh_api_key(self): - obj = self.httpPost(self.api("apiKey/refresh"), data={"id": self.apiKey["uid"]}) - self.assertEquals(True, obj["success"], obj["msg"]) - self.assertTrue("valid_until" in obj) - self.assertTrue(obj["valid_until"] >= self.apiKey["valid_until"]) - - def test_revoke_api_key(self): - obj = self.httpPost(self.api("apiKey/revoke"), data={"id": self.apiKey["uid"]}) - self.assertEquals(True, obj["success"], obj["msg"]) - self.test_get_api_keys_empty() - - def test_fetch_notifications(self): - obj = self.httpPost(self.api("notifications/fetch")) - self.assertEquals(True, obj["success"], obj["msg"]) - - def test_logout(self): - obj = self.httpPost(self.api("user/logout")) - self.assertEquals(True, obj["success"], obj["msg"]) - obj = self.httpPost(self.api("user/logout")) - self.assertEquals(False, obj["success"]) diff --git a/test/installTest.py b/test/installTest.py deleted file mode 100644 index 7c6da71..0000000 --- a/test/installTest.py +++ /dev/null @@ -1,59 +0,0 @@ -from phpTest import PhpTest - -import sys - -class InstallTestCase(PhpTest): - - def __init__(self, args): - super().__init__({ - "Testing connection…": self.test_connection, - "Testing database setup…": self.test_database_setup, - "Testing invalid usernames…": self.test_invalid_usernames, - "Testing invalid password…": self.test_invalid_password, - "Testing not matching password…": self.test_not_matching_passwords, - "Testing invalid email…": self.test_invalid_email, - "Testing user creation…": self.test_create_user, - "Testing skip mail configuration…": self.test_skil_mail_config, - "Testing complete setup…": self.test_complete_setup, - }) - self.args = args - - def test_connection(self): - self.httpGet() - - def test_database_setup(self): - obj = self.httpPost(data=vars(self.args)) - self.assertEquals(True, obj["success"], obj["msg"]) - - def test_invalid_usernames(self): - for username in ["a", "a"*33]: - obj = self.httpPost(data={ "username": username, "password": "123456", "confirmPassword": "123456" }) - self.assertEquals(False, obj["success"]) - self.assertEquals("The username should be between 5 and 32 characters long", obj["msg"]) - - def test_invalid_password(self): - obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": "1", "confirmPassword": "1" }) - self.assertEquals(False, obj["success"]) - self.assertEquals("The password should be at least 6 characters long", obj["msg"]) - - def test_not_matching_passwords(self): - obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": "1", "confirmPassword": "2" }) - self.assertEquals(False, obj["success"]) - self.assertEquals("The given passwords do not match", obj["msg"]) - - def test_invalid_email(self): - obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": PhpTest.ADMIN_PASSWORD, "confirmPassword": PhpTest.ADMIN_PASSWORD, "email": "123abc" }) - self.assertEquals(False, obj["success"]) - self.assertEquals("Invalid email address", obj["msg"]) - - def test_create_user(self): - obj = self.httpPost(data={ "username": PhpTest.ADMIN_USERNAME, "password": PhpTest.ADMIN_PASSWORD, "confirmPassword": PhpTest.ADMIN_PASSWORD, "email": "test@test.com" }) - self.assertEquals(True, obj["success"], obj["msg"]) - - def test_skil_mail_config(self): - obj = self.httpPost(data={ "skip": "true" }) - self.assertEquals(True, obj["success"], obj["msg"]) - - def test_complete_setup(self): - res = self.httpGet() - self.assertTrue("Installation finished" in res.text) diff --git a/test/phpTest.py b/test/phpTest.py deleted file mode 100644 index 19ca157..0000000 --- a/test/phpTest.py +++ /dev/null @@ -1,67 +0,0 @@ -import unittest -import string -import random -import requests -import re -import json -import sys - -class PhpTest(unittest.TestCase): - - def randomString(length): - letters = string.ascii_lowercase + string.ascii_uppercase + string.digits - return ''.join(random.choice(letters) for i in range(length)) - - ADMIN_USERNAME = "Administrator" - ADMIN_PASSWORD = randomString(16) - - def __init__(self, methods): - super().__init__("test_methods") - keywords = ["Fatal error", "Warning", "Notice", "Parse error", "Deprecated"] - self.methods = methods - self.phpPattern = re.compile("(%s):" % ("|".join(keywords))) - self.url = "http://localhost" - self.session = requests.Session() - - def httpError(self, res): - return "Server returned: %d %s" % (res.status_code, res.reason) - - def getPhpErrors(self, res): - return [line for line in res.text.split("\n") if self.phpPattern.search(line)] - - def httpGet(self, target="/"): - url = self.url + target - res = self.session.get(url) - self.assertEquals(200, res.status_code, self.httpError(res)) - self.assertEquals([], self.getPhpErrors(res)) - return res - - def httpPost(self, target="/", data={}): - url = self.url + target - res = self.session.post(url, data=data) - self.assertEquals(200, res.status_code, self.httpError(res)) - self.assertEquals([], self.getPhpErrors(res)) - obj = self.getJson(res) - return obj - - def getJson(self, res): - obj = None - try: - obj = json.loads(res.text) - except: - pass - finally: - self.assertTrue(isinstance(obj, dict), res.text) - return obj - - def test_methods(self): - print() - print("Running Tests in %s" % self.__class__.__name__) - for msg, method in self.methods.items(): - self.test_method(msg, method) - - def test_method(self, msg, method): - sys.stdout.write("[ ] %s" % msg) - method() - sys.stdout.write("\r[+] %s\n" % msg) - sys.stdout.flush() diff --git a/test/requirements.txt b/test/requirements.txt deleted file mode 100644 index 2134b16..0000000 --- a/test/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -requests==2.23.0 -psycopg2==2.8.4 -mysql_connector_repackaged==0.3.1 diff --git a/test/test.py b/test/test.py deleted file mode 100644 index eb63682..0000000 --- a/test/test.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -import argparse -import random -import string -import unittest - -import mysql.connector -import psycopg2 - -from installTest import InstallTestCase -from apiTest import ApiTestCase - -CONFIG_FILES = ["../core/Configuration/Database.class.php","../core/Configuration/JWT.class.php","../core/Configuration/Mail.class.php"] - -def randomName(length): - letters = string.ascii_lowercase - return ''.join(random.choice(letters) for i in range(length)) - -def performTest(args): - suite = unittest.TestSuite() - suite.addTest(InstallTestCase(args)) - suite.addTest(ApiTestCase()) - runner = unittest.TextTestRunner() - runner.run(suite) - -def testMysql(args): - - # Create a temporary database - if args.database is None: - args.database = "webbase_test_%s" % randomName(6) - config = { - "host": args.host, - "user": args.username, - "passwd": args.password, - "port": args.port - } - - print("[ ] Connecting to dbms…") - connection = mysql.connector.connect(**config) - print("[+] Success") - cursor = connection.cursor() - print("[ ] Creating temporary databse %s" % args.database) - cursor.execute("CREATE DATABASE %s" % args.database) - print("[+] Success") - - # perform test - try: - args.type = "mysql" - performTest(args) - finally: - if cursor is not None: - print("[ ] Deleting temporary database") - cursor.execute("DROP DATABASE %s" % args.database) - cursor.close() - print("[+] Success") - - if connection is not None: - print("[ ] Closing connection…") - connection.close() - -def testPostgres(args): - - # Create a temporary database - if args.database is None: - args.database = "webbase_test_%s" % randomName(6) - connection_string = "host=%s port=%d user=%s password=%s" % (args.host, args.port, args.username, args.password) - - print("[ ] Connecting to dbms…") - connection = psycopg2.connect(connection_string) - connection.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT) - print("[+] Success") - cursor = connection.cursor() - print("[ ] Creating temporary databse %s" % args.database) - cursor.execute("CREATE DATABASE %s" % args.database) - print("[+] Success") - - # perform test - try: - args.type = "postgres" - performTest(args) - finally: - if cursor is not None: - print("[ ] Deleting temporary database") - cursor.execute("DROP DATABASE %s" % args.database) - cursor.close() - print("[+] Success") - - if connection is not None: - print("[ ] Closing connection…") - connection.close() - -if __name__ == "__main__": - - supportedDbms = { - "mysql": 3306, - "postgres": 5432, - "oracle": 1521 - } - - parser = argparse.ArgumentParser(description='Web-Base database test suite') - parser.add_argument('dbms', metavar='DBMS', type=str, help='the dbms to setup, must be one of: %s' % ", ".join(supportedDbms.keys())) - parser.add_argument('--username', '-u', type=str, help='the username used for connecting to the dbms, default: root', default='root') - parser.add_argument('--password', '-p', type=str, help='the password used for connecting to the dbms, default: (empty)', default='') - parser.add_argument('--host', '-H', type=str, help='the host where the dbms is running on, default: localhost', default='localhost') - parser.add_argument('--port', '-P', type=int, help='the port where the dbms is running on, default: (depends on dbms)') - parser.add_argument('--database', '-d', type=str, help='the name of the database for the test suite, default: randomly chosen and created') - parser.add_argument('--force', action='store_const', help='Delete existing configuration files', const=True) - - args = parser.parse_args() - if args.dbms not in supportedDbms: - print("Unsupported dbms. Supported values: %s" % ", ".join(supportedDbms.keys())) - exit(1) - - for f in CONFIG_FILES: - if os.path.isfile(f): - if not args.force: - print("File %s exists. The testsuite is required to perform tests on a clean environment. Specify --force to delete those files" % f) - exit(1) - else: - os.remove(f) - - if args.port is None: - args.port = supportedDbms[args.dbms] - - if args.dbms == "mysql": - testMysql(args) - elif args.dbms == "postgres": - testPostgres(args) - - for f in CONFIG_FILES: - if os.path.isfile(f): - os.remove(f)