Improve code coverage and API test cases for the Rules module. Fixes #5334

This commit is contained in:
Pradip Parkale 2020-05-07 16:27:58 +05:30 committed by Akshay Joshi
parent 46d186a49f
commit 057a2b2312
9 changed files with 566 additions and 54 deletions

1
.gitignore vendored
View File

@ -41,6 +41,7 @@ web/config_local.py
web/pgadmin/misc/themes/pgadmin.themes.json
web/geckodriver.log
web/regression/test_config.json
web/regression/.coveragerc
node_modules/
web/pgAdmin/static/js/generated
web/pgadmin/static/js/generated

View File

@ -14,6 +14,7 @@ New features
Housekeeping
************
| `Issue #5334 <https://redmine.postgresql.org/issues/5334>`_ - Improve code coverage and API test cases for the Rules module.
| `Issue #5443 <https://redmine.postgresql.org/issues/5443>`_ - Remove support for Python 2.
| `Issue #5444 <https://redmine.postgresql.org/issues/5444>`_ - Cleanup Python detection in the runtime project file.
| `Issue #5455 <https://redmine.postgresql.org/issues/5455>`_ - Refactor pgAdmin4.py so it can be imported and is a lot more readable.

View File

@ -0,0 +1,408 @@
{
"add_rules": [
{
"name": "Add rule Node",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"test_data": {
"schema": "PLACE_HOLDER",
"view": "PLACE_HOLDER",
"name": "PLACE_HOLDER",
"event": "Update"
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Error while adding a rule using wrong table",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"wrong_table_id": true,
"test_data": {
"schema": "PLACE_HOLDER",
"view": "PLACE_HOLDER",
"name": "PLACE_HOLDER",
"event": "Update"
},
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 410
}
},
{
"name": "Error while adding a rule",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"error_creating_rule": true,
"test_data": {
"schema": "PLACE_HOLDER",
"view": "PLACE_HOLDER",
"name": "PLACE_HOLDER",
"event": "Update"
},
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar",
"return_value": "(False, 'Mocked Internal Server Error ')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while while fetching the rule id using rule name",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"internal_server_error": true,
"test_data": {
"schema": "PLACE_HOLDER",
"view": "PLACE_HOLDER",
"name": "PLACE_HOLDER",
"event": "Update"
},
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar",
"return_value": "(True, True),(False, 'Mocked Internal Server Error ')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Exception while adding a rule",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"test_data": {
"schema": "PLACE_HOLDER",
"view": "PLACE_HOLDER",
"name": "PLACE_HOLDER",
"event": "Update"
},
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar",
"return_value": "(False, 'Mocked Internal Server Error ')"
},
"expected_data": {
"status_code": 500
}
}
],
"get_rule": [
{
"name": "Get a rule URL",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Get a rule URL using wrong rule id",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"incorrect_rule_id": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 410
}
},
{
"name": "Get a rules properties under table nodes",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"table_nodes": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Error while fetching a rules properties under table nodes",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"table_nodes": true,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Get a rule Node",
"url": "/browser/rule/nodes/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Get a rule Node using wrong rule id",
"url": "/browser/rule/nodes/",
"is_positive_test": true,
"incorrect_rule_id": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 410
}
},
{
"name": "Get a rule Node dependants",
"url": "/browser/rule/dependent/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Get a rule Node dependency",
"url": "/browser/rule/dependency/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Error while fetching the rules under the table nodes using wrong table id",
"url": "/browser/rule/nodes/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_2darray",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Get all the rules under the table nodes",
"url": "/browser/rule/nodes/",
"is_positive_test": true,
"mocking_required": false,
"table_nodes": true,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Get all the rules under the table nodes using wrong table id",
"url": "/browser/rule/nodes/",
"is_positive_test": true,
"incorrect_table_id": true,
"table_nodes": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Error while fetching all the rules under the table nodes using wrong table id",
"url": "/browser/rule/nodes/",
"is_positive_test": false,
"table_nodes": true,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_2darray",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while fetching a rule SQL",
"url": "/browser/rule/sql/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Get a rule SQL using wrong rule id",
"url": "/browser/rule/sql/",
"is_positive_test": true,
"incorrect_rule_id": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 410
}
},
{
"name": "Fetch msql of rule using wrong rule id",
"url": "/browser/rule/msql/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.browser.server_groups.servers.databases.schemas.tables.rules.RuleView.getSQL",
"return_value": "('', 'Mocked response')"
},
"expected_data": {
"status_code": 200
}
}
],
"delete_rule": [
{
"name": "Delete a rule URL",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Error while fetching a rule to delete",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while deleting the rule",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while fetching a rule to delete",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict",
"return_value": "(True, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Rule not found while deleting a rule",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"invalid_rule_id": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
}
],
"update_rule": [
{
"name": "update a rule URL",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
},
{
"name": "Error while fetching a rule to update",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while updating the rule",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar",
"return_value": "(False, 'Mocked Internal Server Error')"
},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while fetching a rule to update using wrong rule id",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"wrong_rule_id": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 500
}
},
{
"name": "Error while updating the rule",
"url": "/browser/rule/obj/",
"is_positive_test": false,
"mocking_required": true,
"mock_data": {
"function_name": "pgadmin.browser.server_groups.servers.databases.schemas.tables.rules.RuleView.getSQL",
"return_value": "('')"
},
"expected_data": {
"status_code": 500
}
}
],
"delete_multiple_rule": [
{
"name": "Delete multiple rule",
"url": "/browser/rule/obj/",
"is_positive_test": true,
"mocking_required": false,
"mock_data": {},
"expected_data": {
"status_code": 200
}
}
]
}

View File

@ -9,7 +9,7 @@
import json
import uuid
import sys
from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
import utils as tables_utils
from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
@ -19,13 +19,18 @@ from pgadmin.browser.server_groups.servers.databases.tests import utils as \
from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from regression.python_test_utils import test_utils as utils
from . import utils as rules_utils
if sys.version_info < (3, 3):
from mock import patch
else:
from unittest.mock import patch
class RulesAddTestCase(BaseTestGenerator):
"""This class will add new rule under table node."""
scenarios = [
('Add rule Node URL', dict(url='/browser/rule/obj/'))
]
scenarios = utils.generate_scenarios('add_rules',
rules_utils.test_cases)
def setUp(self):
self.db_name = parent_node_dict["database"][-1]["db_name"]
@ -50,20 +55,40 @@ class RulesAddTestCase(BaseTestGenerator):
def runTest(self):
"""This function will rule under table node."""
rule_name = "test_rule_add_%s" % (str(uuid.uuid4())[1:8])
data = {"schema": self.schema_name,
"view": self.table_name,
"name": rule_name,
"event": "Update"
}
response = self.tester.post(
self.test_data['schema'] = self.schema_name
self.test_data['view'] = self.table_name
self.test_data['name'] = "test_rule_add_%s" % (str(uuid.uuid4())[1:8])
data = self.test_data
if self.is_positive_test:
response = self.create_rule(data)
else:
if hasattr(self, 'wrong_table_id'):
del data["name"]
response = self.create_rule(data)
elif hasattr(self, 'internal_server_error'):
with patch(self.mock_data["function_name"],
side_effect=eval(self.mock_data["return_value"])):
response = self.create_rule(data)
elif hasattr(self, 'error_creating_rule'):
with patch(self.mock_data["function_name"],
return_value=eval(self.mock_data["return_value"])):
response = self.create_rule(data)
else:
with patch(self.mock_data["function_name"],
side_effect=eval(self.mock_data["return_value"])):
response = self.create_rule(data)
self.assertEquals(response.status_code,
self.expected_data["status_code"])
def create_rule(self, data):
return self.tester.post(
"{0}{1}/{2}/{3}/{4}/{5}/".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id),
data=json.dumps(data),
content_type='html/json'
)
self.assertEquals(response.status_code, 200)
def tearDown(self):
# Disconnect the database

View File

@ -19,13 +19,18 @@ from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from regression.python_test_utils import test_utils as utils
from . import utils as rules_utils
import sys
if sys.version_info < (3, 3):
from mock import patch
else:
from unittest.mock import patch
class RulesDeleteTestCase(BaseTestGenerator):
"""This class will delete rule under table node."""
scenarios = [
('Delete rule Node URL', dict(url='/browser/rule/obj/'))
]
scenarios = utils.generate_scenarios('delete_rule',
rules_utils.test_cases)
def setUp(self):
self.db_name = parent_node_dict["database"][-1]["db_name"]
@ -53,20 +58,33 @@ class RulesDeleteTestCase(BaseTestGenerator):
self.table_name,
self.rule_name)
def runTest(self):
"""This function will delete rule under table node."""
rule_response = rules_utils.verify_rule(self.server, self.db_name,
self.rule_name)
if not rule_response:
raise Exception("Could not find the rule to delete.")
response = self.tester.delete(
def delete_rules(self):
return self.tester.delete(
"{0}{1}/{2}/{3}/{4}/{5}/{6}".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id,
self.rule_id),
follow_redirects=True
)
self.assertEquals(response.status_code, 200)
def runTest(self):
"""This function will delete rule under table node."""
rule_response = rules_utils.verify_rule(self.server, self.db_name,
self.rule_name)
if not rule_response:
raise Exception("Could not find the rule to delete.")
if self.is_positive_test:
if hasattr(self, "invalid_rule_id"):
self.rule_id = 9999
response = self.delete_rules()
else:
with patch(self.mock_data["function_name"],
return_value=eval(self.mock_data["return_value"])):
response = self.delete_rules()
self.assertEquals(response.status_code,
self.expected_data["status_code"])
def tearDown(self):
# Disconnect the database

View File

@ -24,9 +24,9 @@ from . import utils as rules_utils
class RulesDeleteTestCase(BaseTestGenerator):
"""This class will delete rule under table node."""
scenarios = [
('Delete rule Node URL', dict(url='/browser/rule/obj/'))
]
scenarios = utils.generate_scenarios('delete_multiple_rule',
rules_utils.test_cases)
def setUp(self):
self.db_name = parent_node_dict["database"][-1]["db_name"]
@ -60,6 +60,17 @@ class RulesDeleteTestCase(BaseTestGenerator):
self.rule_name_1),
]
def delete_multiple_rule(self, data):
return self.tester.delete(
"{0}{1}/{2}/{3}/{4}/{5}/".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id
),
follow_redirects=True,
data=json.dumps(data),
content_type='html/json'
)
def runTest(self):
"""This function will delete rule under table node."""
rule_response = rules_utils.verify_rule(self.server, self.db_name,
@ -73,16 +84,10 @@ class RulesDeleteTestCase(BaseTestGenerator):
raise Exception("Could not find the rule to delete.")
data = {'ids': self.rule_ids}
response = self.tester.delete(
"{0}{1}/{2}/{3}/{4}/{5}/".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id
),
follow_redirects=True,
data=json.dumps(data),
content_type='html/json'
)
self.assertEquals(response.status_code, 200)
if self.is_positive_test:
response = self.delete_multiple_rule(data)
self.assertEquals(response.status_code,
self.expected_data["status_code"])
def tearDown(self):
# Disconnect the database

View File

@ -20,12 +20,18 @@ from regression import parent_node_dict
from regression.python_test_utils import test_utils as utils
from . import utils as rules_utils
import sys
if sys.version_info < (3, 3):
from mock import patch
else:
from unittest.mock import patch
class RulesGetTestCase(BaseTestGenerator):
"""This class will fetch the rule under table node."""
scenarios = [
('Fetch rule Node URL', dict(url='/browser/rule/obj/'))
]
scenarios = utils.generate_scenarios('get_rule',
rules_utils.test_cases)
def setUp(self):
self.db_name = parent_node_dict["database"][-1]["db_name"]
@ -53,16 +59,39 @@ class RulesGetTestCase(BaseTestGenerator):
self.table_name,
self.rule_name)
def runTest(self):
"""This function will fetch the rule under table node."""
response = self.tester.get(
def get_rule(self):
return self.tester.get(
"{0}{1}/{2}/{3}/{4}/{5}/{6}".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id,
self.rule_id),
follow_redirects=True
)
self.assertEquals(response.status_code, 200)
def runTest(self):
"""This function will fetch the rule under table node."""
if self.is_positive_test:
if hasattr(self, "incorrect_rule_id"):
self.rule_id = 9999
if hasattr(self, "table_nodes"):
self.rule_id = ''
response = self.get_rule()
else:
response = self.get_rule()
else:
if hasattr(self, "table_nodes"):
self.rule_id = ''
with patch(self.mock_data["function_name"],
return_value=eval(self.mock_data["return_value"])):
response = self.get_rule()
else:
with patch(self.mock_data["function_name"],
return_value=eval(self.mock_data["return_value"])):
response = self.get_rule()
self.assertEquals(response.status_code,
self.expected_data["status_code"])
def tearDown(self):
# Disconnect the database

View File

@ -20,13 +20,17 @@ from pgadmin.utils.route import BaseTestGenerator
from regression import parent_node_dict
from regression.python_test_utils import test_utils as utils
from . import utils as rules_utils
import sys
if sys.version_info < (3, 3):
from mock import patch
else:
from unittest.mock import patch
class RulesUpdateTestCase(BaseTestGenerator):
"""This class will update the rule under table node."""
scenarios = [
('Put rule Node URL', dict(url='/browser/rule/obj/'))
]
scenarios = utils.generate_scenarios('update_rule',
rules_utils.test_cases)
def setUp(self):
self.db_name = parent_node_dict["database"][-1]["db_name"]
@ -54,6 +58,15 @@ class RulesUpdateTestCase(BaseTestGenerator):
self.table_name,
self.rule_name)
def update_rule(self, data):
return self.tester.put(
"{0}{1}/{2}/{3}/{4}/{5}/{6}".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id,
self.rule_id),
data=json.dumps(data),
follow_redirects=True)
def runTest(self):
"""This function will update the rule under table node."""
rule_response = rules_utils.verify_rule(self.server, self.db_name,
@ -63,14 +76,20 @@ class RulesUpdateTestCase(BaseTestGenerator):
}
if not rule_response:
raise Exception("Could not find the rule to update.")
response = self.tester.put(
"{0}{1}/{2}/{3}/{4}/{5}/{6}".format(self.url, utils.SERVER_GROUP,
self.server_id, self.db_id,
self.schema_id, self.table_id,
self.rule_id),
data=json.dumps(data),
follow_redirects=True)
self.assertEquals(response.status_code, 200)
if self.is_positive_test:
if hasattr(self, "wrong_rule_id"):
self.rule_id = 9999
response = self.update_rule(data)
else:
with patch(self.mock_data["function_name"],
return_value=eval(self.mock_data["return_value"])):
if hasattr(self, "wrong_rule_id"):
self.rule_id = 9999
response = self.update_rule(data)
self.assertEquals(response.status_code,
self.expected_data["status_code"])
def tearDown(self):
# Disconnect the database

View File

@ -10,10 +10,16 @@
from __future__ import print_function
import sys
import os
import json
import traceback
from regression.python_test_utils import test_utils as utils
CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
with open(CURRENT_PATH + "/rules_test_data.json") as data_file:
test_cases = json.load(data_file)
def create_rule(server, db_name, schema_name, table_name, rule_name):
"""