diff --git a/docs/en_US/release_notes_4_29.rst b/docs/en_US/release_notes_4_29.rst index a350ee882..5a59969ec 100644 --- a/docs/en_US/release_notes_4_29.rst +++ b/docs/en_US/release_notes_4_29.rst @@ -13,6 +13,7 @@ New features Housekeeping ************ +| `Issue #5337 `_ - Improve code coverage and API test cases for Views and Materialized Views. Bug fixes ********* diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/test_compound_triggers_add.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/test_compound_triggers_add.py index f9169dd25..93bbd3243 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/test_compound_triggers_add.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/test_compound_triggers_add.py @@ -73,10 +73,11 @@ class CompoundTriggersAddTestCase(BaseTestGenerator): "ALTER TABLE %s.%s OWNER TO %s" self.view_name = \ "view_compound_trigger_%s" % (str(uuid.uuid4())[1:8]) - self.view_id = view_utils.create_view(self.server, self.db_name, - self.schema_name, - view_sql, - self.view_name) + self.view_id = compound_trigger_utils.create_view(self.server, + self.db_name, + self.schema_name, + view_sql, + self.view_name) def create_compound_trigger(self, object_id): return self.tester.post( diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/utils.py index 2c6baa590..d119f3df3 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/tests/utils.py @@ -74,6 +74,49 @@ def create_compound_trigger(server, db_name, schema_name, table_name, raise +def create_view(server, db_name, schema_name, sql_query, view_name): + """ + This function creates a table under provided schema. + :param server: server details + :type server: dict + :param db_name: database name + :type db_name: str + :param schema_name: schema name + :type schema_name: str + :param sql_query: sql query to create view + :type sql_query: str + :param view_name: view name + :type view_name: str + :return view_id: view id + :rtype: int + """ + try: + connection = utils.get_db_connection(db_name, + server['username'], + server['db_password'], + server['host'], + server['port'], + server['sslmode']) + old_isolation_level = connection.isolation_level + connection.set_isolation_level(0) + pg_cursor = connection.cursor() + query = sql_query % (schema_name, view_name, schema_name, view_name, + server['username']) + pg_cursor.execute(query) + connection.set_isolation_level(old_isolation_level) + connection.commit() + # Get 'oid' from newly created view + pg_cursor.execute("select oid from pg_class where relname='%s'" % + view_name) + view = pg_cursor.fetchone() + view_id = view[0] + connection.close() + return view_id + except Exception: + traceback.print_exc(file=sys.stderr) + raise + + def verify_compound_trigger(server, db_name, trigger_name): """ This function verifies table exist in database or not. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_parameters.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_parameters.py deleted file mode 100644 index 47a3c6ed7..000000000 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_parameters.py +++ /dev/null @@ -1,188 +0,0 @@ -########################################################################## -# -# pgAdmin 4 - PostgreSQL Tools -# -# Copyright (C) 2013 - 2020, The pgAdmin Development Team -# This software is released under the PostgreSQL Licence -# -########################################################################## - -import json -import uuid - -from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ - utils as schema_utils -from pgadmin.browser.server_groups.servers.databases.tests import utils as \ - database_utils -from pgadmin.utils import server_utils as server_utils -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 views_utils - - -class MViewsUpdateParameterTestCase(BaseTestGenerator): - """This class will update the view/mview under schema node.""" - scenarios = [ - # Fetching default URL for table node. - ('Enable custom auto vacuum and set the parameters for table ' - 'without autovacuum_enabled', - dict(url='/browser/mview/obj/', - api_data={ - 'autovacuum_custom': True, - 'vacuum_table': { - 'changed': [ - {'name': 'autovacuum_vacuum_cost_delay', - 'value': 20}, - {'name': 'autovacuum_vacuum_threshold', - 'value': 20} - ] - }} - ) - ), - ('Change a parameter to zero value ' - 'without autovacuum_enabled', - dict(url='/browser/mview/obj/', - api_data={ - 'vacuum_table': { - 'changed': [ - {'name': 'autovacuum_vacuum_cost_delay', - 'value': 0} - ] - }} - ) - ), - ('Enable autovacuum_enabled', - dict(url='/browser/mview/obj/', - api_data={'autovacuum_enabled': 't'} - ) - ), - ('Reset individual parameters for table', - dict(url='/browser/mview/obj/', - api_data={ - 'autovacuum_enabled': 'x', - 'vacuum_table': { - 'changed': [ - {'name': 'autovacuum_vacuum_cost_delay', - 'value': None}, - ] - }} - ) - ), - ('Reset custom auto vacuum', - dict(url='/browser/mview/obj/', - api_data={'autovacuum_custom': False} - ) - ), - ('Enable toast custom auto vacuum and set the parameters for table ' - 'without autovacuum_enabled', - dict(url='/browser/mview/obj/', - api_data={ - 'toast_autovacuum': True, - 'vacuum_toast': { - 'changed': [ - {'name': 'autovacuum_vacuum_cost_delay', - 'value': 20}, - {'name': 'autovacuum_vacuum_threshold', - 'value': 20} - ] - }} - ) - ), - ('Change a toast parameter to zero value ' - 'without autovacuum_enabled', - dict(url='/browser/mview/obj/', - api_data={ - 'vacuum_toast': { - 'changed': [ - {'name': 'autovacuum_vacuum_cost_delay', - 'value': 0} - ] - }} - ) - ), - ('Enable toast.autovacuum_enabled', - dict(url='/browser/mview/obj/', - api_data={'toast_autovacuum_enabled': 't'} - ) - ), - ('Reset individual toast parameters for table', - dict(url='/browser/mview/obj/', - api_data={ - 'toast_autovacuum_enabled': 'x', - 'vacuum_toast': { - 'changed': [ - {'name': 'autovacuum_vacuum_cost_delay', - 'value': None}, - ] - }} - ) - ), - ('Reset auto vacuum', - dict(url='/browser/mview/obj/', - api_data={'toast_autovacuum': False} - ) - ), - ] - - m_view_name = "test_mview_put_%s" % (str(uuid.uuid4())[1:8]) - - def setUp(self): - self.db_name = parent_node_dict["database"][-1]["db_name"] - schema_info = parent_node_dict["schema"][-1] - self.server_id = schema_info["server_id"] - self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, - self.server_id, self.db_id) - if not db_con['data']["connected"]: - raise Exception("Could not connect to database to update a mview.") - self.schema_id = schema_info["schema_id"] - self.schema_name = schema_info["schema_name"] - schema_response = schema_utils.verify_schemas(self.server, - self.db_name, - self.schema_name) - if not schema_response: - raise Exception("Could not find the schema to update a mview.") - - self.m_view_id = views_utils.get_view_id(self.server, self.db_name, - self.m_view_name) - - if self.m_view_id is None: - m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE " \ - "pg_default AS SELECT 'test_pgadmin' WITH NO " \ - "DATA;ALTER TABLE %s.%s OWNER TO %s" - self.m_view_id = views_utils.create_view(self.server, - self.db_name, - self.schema_name, - m_view_sql, - self.m_view_name) - - def runTest(self): - """This function will update the view/mview under schema node.""" - mview_response = views_utils.verify_view(self.server, self.db_name, - self.m_view_name) - if not mview_response: - raise Exception("Could not find the mview to update.") - - data = self.api_data - data['oid'] = self.m_view_id - - response = self.tester.put(self.url + str(utils.SERVER_GROUP) + '/' + - str(self.server_id) + '/' + - str(self.db_id) + '/' + - str(self.schema_id) + '/' + - str(self.m_view_id), - data=json.dumps(data), - follow_redirects=True) - self.assertEqual(response.status_code, 200) - - def tearDown(self): - # Disconnect the database - database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_refresh.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_refresh.py index f54a47a5f..2e0699907 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_refresh.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_mviews_refresh.py @@ -20,50 +20,28 @@ from regression import parent_node_dict from regression.python_test_utils import test_utils as utils from . import utils as views_utils -MVIEW_CHECK_UTILITY_URL = 'browser/mview/check_utility_exists/' -MVIEW_REFRESH_URL = 'browser/mview/refresh_data/' -IS_UTILITY_EXISTS = True - class MViewsUpdateParameterTestCase(BaseTestGenerator): """This class will check materialized view refresh functionality.""" - scenarios = [ - ('Check utility route', - dict(type='check_utility') - ), - ('Refresh materialized view with invalid oid', - dict(type='invalid') - ), - ('Refresh materialized view with data', - dict(type='with_data') - ), - ('Refresh materialized view with no data', - dict(type='with_no_data') - ), - ('Refresh materialized view with data (concurrently)', - dict(type='with_data_concurrently') - ), - ('Refresh materialized view with no data (concurrently)', - dict(type='with_no_data_concurrently') - ), - ] + # Generates scenarios + scenarios = utils.generate_scenarios("mview_refresh", + views_utils.test_cases) def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection self.db_name = parent_node_dict["database"][-1]["db_name"] schema_info = parent_node_dict["schema"][-1] self.server_id = schema_info["server_id"] self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, self.server_id, self.db_id) if not db_con['data']["connected"]: raise Exception("Could not connect to database to update a mview.") + + # Create schema self.schema_id = schema_info["schema_id"] self.schema_name = schema_info["schema_name"] schema_response = schema_utils.verify_schemas(self.server, @@ -72,75 +50,55 @@ class MViewsUpdateParameterTestCase(BaseTestGenerator): if not schema_response: raise Exception("Could not find the schema to update a mview.") - self.m_view_name = "test_mview_put_%s" % (str(uuid.uuid4())[1:8]) - m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default " \ - "AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE " \ - "%s.%s OWNER TO %s" + query = self.inventory_data['query'] - self.m_view_id = views_utils.create_view(self.server, - self.db_name, - self.schema_name, - m_view_sql, - self.m_view_name) + self.m_view_name = "test_mview_put_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.m_view_name, + query) def runTest(self): """This class will check materialized view refresh functionality""" - mview_response = views_utils.verify_view(self.server, self.db_name, self.m_view_name) if not mview_response: raise Exception("Could not find the mview to update.") - data = None - is_put_request = True + if self.is_put_request: + # Check utility + url_from_test_data = self.url + self.url = 'browser/mview/check_utility_exists/' + response = views_utils.api_get(self) + if response.json['success'] == 0: + self.skipTest("Couldn't check materialized view refresh " + "functionality because utility/binary does " + "not exists.") + # reset self.url value + self.url = url_from_test_data - if self.type == 'check_utility': - is_put_request = False - elif self.type == 'invalid': - data = dict({'concurrent': 'false', 'with_data': 'false'}) - elif self.type == 'with_data': - data = dict({'concurrent': 'false', 'with_data': 'true'}) - elif self.type == 'with_no_data': - data = dict({'concurrent': 'false', 'with_data': 'false'}) - elif self.type == 'with_data_concurrently': - data = dict({'concurrent': 'true', 'with_data': 'true'}) - elif self.type == 'with_no_data_concurrently': - data = dict({'concurrent': 'true', 'with_data': 'false'}) + if self.is_positive_test: + response = views_utils.api_put(self) - response = self.tester.get( - MVIEW_CHECK_UTILITY_URL + str(utils.SERVER_GROUP) + '/' + - str(self.server_id) + '/' + - str(self.db_id) + '/' + - str(self.schema_id) + '/' + - str(self.m_view_id), - content_type='html/json' - ) - self.assertEqual(response.status_code, 200) - if is_put_request and response.json['success'] == 0: - self.skipTest( - "Couldn't check materialized view refresh" - " functionality because utility/binary does not exists." - ) - - if is_put_request: - mvid = self.m_view_id - if self.type == 'invalid': - mvid = 99999 - response = self.tester.put( - MVIEW_REFRESH_URL + str(utils.SERVER_GROUP) + '/' + - str(self.server_id) + '/' + - str(self.db_id) + '/' + - str(self.schema_id) + '/' + - str(mvid), - data=json.dumps(data), - follow_redirects=True - ) - if self.type == 'invalid': - self.assertEqual(response.status_code, 410) - else: - self.assertEqual(response.status_code, 200) - # On success we get job_id from server + # Assert response + utils.assert_status_code(self, response) self.assertTrue('job_id' in response.json['data']) + else: + if 'm_view_id' in self.data: + self.view_id = self.data['m_view_id'] + response = views_utils.api_put(self) + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) + + else: + # only check utility + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) def tearDown(self): # Disconnect the database diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_add.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_add.py index a582c6076..09581ddb6 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_add.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_add.py @@ -6,9 +6,8 @@ # This software is released under the PostgreSQL Licence # ########################################################################## -import json import uuid - +from unittest.mock import patch from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ utils as schema_utils from pgadmin.browser.server_groups.servers.databases.tests import utils as \ @@ -17,68 +16,31 @@ from pgadmin.utils import server_utils as server_utils 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 views_utils class ViewsAddTestCase(BaseTestGenerator): """This class will add new view under schema node.""" - view_name = "test_view_add_%s" % (str(uuid.uuid4())[1:8]) - v_data = {"schema": "", - "owner": "", - "datacl": [], - "seclabels": [], - "name": view_name, - "definition": "SELECT 'Hello World';" - } - m_view_name = "test_mview_add_%s" % (str(uuid.uuid4())[1:8]) - m_view_data = {"spcname": "pg_default", - "toast_autovacuum_enabled": False, - "autovacuum_enabled": False, - "schema": "", - "owner": "", - "vacuum_table": [ - {"name": "autovacuum_analyze_scale_factor"}, - {"name": "autovacuum_analyze_threshold"}, - {"name": "autovacuum_freeze_max_age"}, - {"name": "autovacuum_vacuum_cost_delay"}, - {"name": "autovacuum_vacuum_cost_limit"}, - {"name": "autovacuum_vacuum_scale_factor"}, - {"name": "autovacuum_vacuum_threshold"}, - {"name": "autovacuum_freeze_min_age"}, - {"name": "autovacuum_freeze_table_age"}], - "vacuum_toast": [{"name": "autovacuum_freeze_max_age"}, - {"name": "autovacuum_vacuum_cost_delay"}, - {"name": "autovacuum_vacuum_cost_limit"}, - {"name": "autovacuum_vacuum_scale_factor"}, - {"name": "autovacuum_vacuum_threshold"}, - {"name": "autovacuum_freeze_min_age"}, - {"name": "autovacuum_freeze_table_age"}], - "datacl": [], - "seclabels": [], - "name": m_view_name, - "definition": "SELECT 'test_pgadmin';"} - scenarios = [ - ('Add view under schema node', dict(url='/browser/view/obj/', - data=v_data)), - ('Add materialized view under schema node', - dict(url='/browser/mview/obj/', data=m_view_data)) - ] + + # Generates scenarios + scenarios = utils.generate_scenarios("view_create", + views_utils.test_cases) def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection self.db_name = parent_node_dict["database"][-1]["db_name"] schema_info = parent_node_dict["schema"][-1] self.server_id = schema_info["server_id"] self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, self.server_id, self.db_id) if not db_con['data']["connected"]: raise Exception("Could not connect to database to add view.") + + # Create schema self.schema_id = schema_info["schema_id"] self.schema_name = schema_info["schema_name"] schema_response = schema_utils.verify_schemas(self.server, @@ -90,13 +52,44 @@ class ViewsAddTestCase(BaseTestGenerator): def runTest(self): """This function will add view under schema node.""" db_user = self.server["username"] - self.data["schema"] = self.schema_name + self.data["schema"] = self.schema_id self.data["owner"] = db_user - response = self.tester.post( - self.url + str(utils.SERVER_GROUP) + '/' + str(self.server_id) + - '/' + str(self.db_id) + '/' + str(self.schema_id) + '/', - data=json.dumps(self.data), content_type='html/json') - self.assertEqual(response.status_code, 200) + + if "name" in self.data: + view_name = \ + self.data["name"] + (str(uuid.uuid4())[1:8]) + self.data["name"] = view_name + + if self.is_positive_test: + response = views_utils.api_create(self) + + # Assert response + utils.assert_status_code(self, response) + + # Verify in backend + cross_check_res = views_utils.verify_view(self.server, + self.db_name, + self.data["name"]) + + self.assertIsNotNone(cross_check_res, "Could not find the newly" + " created check view.") + else: + if self.mocking_required: + with patch(self.mock_data["function_name"], + side_effect=eval(self.mock_data["return_value"])): + response = views_utils.api_create(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) + else: + if 'table_id' in self.data: + self.table_id = self.data['table_id'] + response = views_utils.api_create(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) def tearDown(self): # Disconnect the database diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete.py index 7b6ff7a81..edc9c0492 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete.py @@ -8,6 +8,7 @@ ########################################################################## import uuid +from unittest.mock import patch from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ utils as schema_utils @@ -22,38 +23,26 @@ from . import utils as views_utils class ViewsDeleteTestCase(BaseTestGenerator): """This class will delete the view/mview under schema node.""" - view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \ - "ALTER TABLE %s.%s OWNER TO %s" - m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \ - "SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \ - " TO %s" - scenarios = [ - ('Delete view under schema node', dict( - url='/browser/view/obj/', - view_name="test_view_delete_%s" % (str(uuid.uuid4())[1:8]), - sql_query=view_sql)), - ('Delete materialized view under schema node', - dict(url='/browser/mview/obj/', - view_name="test_mview_delete_%s" % (str(uuid.uuid4())[1:8]), - sql_query=m_view_sql)) - ] + + # Generates scenarios + scenarios = utils.generate_scenarios("view_delete", + views_utils.test_cases) def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection self.db_name = parent_node_dict["database"][-1]["db_name"] schema_info = parent_node_dict["schema"][-1] self.server_id = schema_info["server_id"] self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, self.server_id, self.db_id) if not db_con['data']["connected"]: raise Exception("Could not connect to database to delete view.") + + # Create schema self.schema_id = schema_info["schema_id"] self.schema_name = schema_info["schema_name"] schema_response = schema_utils.verify_schemas(self.server, @@ -61,26 +50,69 @@ class ViewsDeleteTestCase(BaseTestGenerator): self.schema_name) if not schema_response: raise Exception("Could not find the schema to delete the view.") + + # Create view + query = self.inventory_data['query'] + + self.view_name = "test_view_delete_%s" % (str(uuid.uuid4())[1:8]) + self.view_id = views_utils.create_view(self.server, self.db_name, self.schema_name, - self.sql_query, - self.view_name) + self.view_name, + query) - def runTest(self): - """This function will delete the view/mview under schema node.""" view_response = views_utils.verify_view(self.server, self.db_name, self.view_name) if not view_response: raise Exception("Could not find the view to delete.") - 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.view_id - ), - follow_redirects=True - ) - self.assertEqual(response.status_code, 200) + + if self.is_list: + self.view_name_2 = "test_view_delete_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id_2 = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name_2, + query) + + view_response = views_utils.verify_view(self.server, self.db_name, + self.view_name_2) + if not view_response: + raise Exception("Could not find the view to delete.") + + # list to delete views + self.data['ids'] = [self.view_id, self.view_id_2] + + def runTest(self): + """This function will delete the view/mview under schema node.""" + + if self.is_positive_test: + + if self.is_list: + response = views_utils.api_delete(self, '') + else: + response = views_utils.api_delete(self) + + # Assert response + utils.assert_status_code(self, response) + + # Verify in backend + view_response = views_utils.verify_view(self.server, self.db_name, + self.view_name) + self.assertIsNone(view_response, "Deleted view still present") + else: + if self.mocking_required: + with patch(self.mock_data["function_name"], + side_effect=[eval(self.mock_data["return_value"])]): + response = views_utils.api_delete(self) + elif 'view_id' in self.data: + self.view_id = self.data["view_id"] + response = views_utils.api_delete(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) def tearDown(self): # Disconnect the database diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete_multiple.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete_multiple.py deleted file mode 100644 index 4c33b0a7a..000000000 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_delete_multiple.py +++ /dev/null @@ -1,104 +0,0 @@ -########################################################################## -# -# pgAdmin 4 - PostgreSQL Tools -# -# Copyright (C) 2013 - 2020, The pgAdmin Development Team -# This software is released under the PostgreSQL Licence -# -########################################################################## - -import uuid -import json - -from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ - utils as schema_utils -from pgadmin.browser.server_groups.servers.databases.tests import utils as \ - database_utils -from pgadmin.utils import server_utils as server_utils -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 views_utils - - -class ViewsDeleteMultipleTestCase(BaseTestGenerator): - """This class will delete the view/mview under schema node.""" - view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \ - "ALTER TABLE %s.%s OWNER TO %s" - m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \ - "SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \ - " TO %s" - scenarios = [ - ('Delete multiple view under schema node', dict( - url='/browser/view/obj/', - view_name=["test_view_delete_%s" % (str(uuid.uuid4())[1:8]), - "test_view_delete_%s" % (str(uuid.uuid4())[1:8])], - sql_query=view_sql)), - ('Delete multiple materialized view under schema node', - dict(url='/browser/mview/obj/', - view_name=["test_mview_delete_%s" % (str(uuid.uuid4())[1:8]), - "test_mview_delete_%s" % (str(uuid.uuid4())[1:8])], - sql_query=m_view_sql)) - ] - - def setUp(self): - self.db_name = parent_node_dict["database"][-1]["db_name"] - schema_info = parent_node_dict["schema"][-1] - self.server_id = schema_info["server_id"] - self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, - self.server_id, self.db_id) - if not db_con['data']["connected"]: - raise Exception("Could not connect to database to delete view.") - self.schema_id = schema_info["schema_id"] - self.schema_name = schema_info["schema_name"] - schema_response = schema_utils.verify_schemas(self.server, - self.db_name, - self.schema_name) - if not schema_response: - raise Exception("Could not find the schema to delete the view.") - self.view_ids = [views_utils.create_view(self.server, - self.db_name, - self.schema_name, - self.sql_query, - self.view_name[0]), - views_utils.create_view(self.server, - self.db_name, - self.schema_name, - self.sql_query, - self.view_name[1]) - ] - - def runTest(self): - """This function will delete the view/mview under schema node.""" - view_response = views_utils.verify_view(self.server, self.db_name, - self.view_name[0]) - if not view_response: - raise Exception("Could not find the view to delete.") - view_response = views_utils.verify_view(self.server, self.db_name, - self.view_name[1]) - if not view_response: - raise Exception("Could not find the view to delete.") - - data = {'ids': self.view_ids} - response = self.tester.delete( - "{0}{1}/{2}/{3}/{4}/".format(self.url, utils.SERVER_GROUP, - self.server_id, self.db_id, - self.schema_id - ), - follow_redirects=True, - data=json.dumps(data), - content_type='html/json' - ) - self.assertEqual(response.status_code, 200) - - def tearDown(self): - # Disconnect the database - database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get.py index 479cd7afa..d8491a738 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get.py @@ -9,6 +9,7 @@ import uuid import json +from unittest.mock import patch from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ utils as schema_utils @@ -23,52 +24,25 @@ from . import utils as views_utils class ViewsGetTestCase(BaseTestGenerator): """This class will fetch the view under schema node.""" - view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \ - "ALTER TABLE %s.%s OWNER TO %s" - m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \ - "SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \ - " TO %s" - view_sql_with_bracket = "CREATE OR REPLACE VIEW %s.%s AS " \ - "SELECT CASE WHEN (pg_db.datistemplate = false " \ - "AND pg_db.datallowconn = true AND " \ - "(pg_db.datconnlimit = -1 OR " \ - "pg_db.datacl is null)) then true else false " \ - "end as res FROM pg_database pg_db; " \ - "ALTER TABLE %s.%s OWNER TO %s" - scenarios = [ - ('Get view under schema node', dict( - url='/browser/view/obj/', - view_name="test_view_get_%s" % (str(uuid.uuid4())[1:8]), - sql_query=view_sql, - type='view_without_conditions')), - ('Get materialized view under schema node', - dict(url='/browser/mview/obj/', - view_name="test_mview_get_%s" % (str(uuid.uuid4())[1:8]), - sql_query=m_view_sql, - type='m_view_without_conditions')), - ('Get view having brackets in script under schema node', dict( - url='/browser/view/obj/', - view_name="test_view_get_%s" % (str(uuid.uuid4())[1:8]), - sql_query=view_sql_with_bracket, - type='view_with_conditions')) - ] + + # Generates scenarios + scenarios = utils.generate_scenarios("view_get", views_utils.test_cases) def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection self.db_name = parent_node_dict["database"][-1]["db_name"] schema_info = parent_node_dict["schema"][-1] self.server_id = schema_info["server_id"] self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, self.server_id, self.db_id) if not db_con['data']["connected"]: raise Exception("Could not connect to database to fetch the view.") + + # Create schema self.schema_id = schema_info["schema_id"] self.schema_name = schema_info["schema_name"] schema_response = schema_utils.verify_schemas(self.server, @@ -76,25 +50,56 @@ class ViewsGetTestCase(BaseTestGenerator): self.schema_name) if not schema_response: raise Exception("Could not find the schema to fetch the view.") + + # Create view + query = self.inventory_data['query'] + + self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8]) + self.view_id = views_utils.create_view(self.server, self.db_name, self.schema_name, - self.sql_query, - self.view_name) + self.view_name, + query) + # In case of multiple views + if self.is_list: + self.view_name_2 = "test_view_get_%s" % (str(uuid.uuid4())[1:8]) + self.view_id_2 = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name_2, + query) def runTest(self): """This function will fetch the view/mview under schema node.""" - response = self.tester.get( - "{0}{1}/{2}/{3}/{4}/{5}".format(self.url, utils.SERVER_GROUP, - self.server_id, self.db_id, - self.schema_id, self.view_id - ), - follow_redirects=True - ) - self.assertEqual(response.status_code, 200) - if self.type == 'view_with_conditions': - response_data = json.loads(response.data.decode('utf-8')) - self.assertIn('((pg_db.datistemplate', response_data['definition']) + if self.is_positive_test: + if self.is_list: + response = views_utils.api_get(self, '') + else: + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + + # Check definition data + test_result_data = self.expected_data["test_result_data"] + if bool(test_result_data): + response_data = json.loads(response.data.decode('utf-8')) + self.assertIn(test_result_data["definition"], + response_data['definition']) + else: + if self.mocking_required: + with patch(self.mock_data["function_name"], + side_effect=[eval(self.mock_data["return_value"])]): + response = views_utils.api_get(self) + elif 'view_id' in self.data: + # Non-existing view id + self.view_id = self.data["view_id"] + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) def tearDown(self): # Disconnect the database diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_dependencies_dependents.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_dependencies_dependents.py new file mode 100644 index 000000000..a38612163 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_dependencies_dependents.py @@ -0,0 +1,82 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid +import json +from unittest.mock import patch + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils import server_utils as server_utils +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 views_utils + + +class ViewsDependeciesDependentsGetTestCase(BaseTestGenerator): + """This class will fetch dependenciey & dependents for + the view under schema node.""" + + # Generates scenarios + scenarios = utils.generate_scenarios("view_dependecies_dependents", + views_utils.test_cases) + + def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to fetch the view.") + + # Create schema + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to fetch the view.") + + # Create view + query = self.inventory_data['query'] + + self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name, + query) + + def runTest(self): + """This function will fetch dependenciey & dependents for + the view/mview under schema node.""" + if self.is_positive_test: + if self.is_dependent: + self.url = self.url + 'dependent/' + response = views_utils.api_get(self) + else: + self.url = self.url + 'dependency/' + response = views_utils.api_get(self) + + utils.assert_status_code(self, response) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_msql.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_msql.py new file mode 100644 index 000000000..eb89117d5 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_msql.py @@ -0,0 +1,90 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid +import json +from unittest.mock import patch + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils import server_utils as server_utils +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 views_utils + + +class ViewsGetMsqlTestCase(BaseTestGenerator): + """This class will fetch the modified view/mview sql under schema node.""" + + # Generates scenarios + scenarios = utils.generate_scenarios("view_get_msql", + views_utils.test_cases) + + def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to fetch the view.") + + # Create schema + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to fetch the view.") + + # Create view + query = self.inventory_data['query'] + + self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name, + query) + + def runTest(self): + """This function will fetch the modified view/mview sql under + schema node.""" + + if self.is_positive_test: + url_encode_data = {"oid": self.view_id, + "comment": self.data['comment']} + + response = views_utils.api_get_msql(self, url_encode_data) + + # Assert response + utils.assert_status_code(self, response) + else: + if 'view_id' in self.data: + # Non-existing view id + self.view_id = self.data["view_id"] + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_nodes.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_nodes.py new file mode 100644 index 000000000..6f6e42ece --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_get_nodes.py @@ -0,0 +1,99 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid +import json +from unittest.mock import patch + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils import server_utils as server_utils +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 views_utils + + +class ViewsGetNodesTestCase(BaseTestGenerator): + """This class will fetch the view nodes under schema node.""" + + # Generates scenarios + scenarios = utils.generate_scenarios("view_get_nodes", + views_utils.test_cases) + + def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to fetch the view.") + + # Create schema + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to fetch the view.") + + # Create view + query = self.inventory_data['query'] + + self.view_name = "test_view_get_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name, + query) + # In case of multiple views + if self.is_list: + self.view_name_2 = "test_view_get_%s" % (str(uuid.uuid4())[1:8]) + self.check_constraint_id_2 = views_utils.\ + create_view(self.server, self.db_name, self.schema_name, + self.view_name_2, query) + + def runTest(self): + """This function will fetch the view/mview nodes under schema node.""" + if self.is_positive_test: + if self.is_list: + response = views_utils.api_get(self, '') + else: + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + + else: + if self.mocking_required: + with patch(self.mock_data["function_name"], + side_effect=[eval(self.mock_data["return_value"])]): + response = views_utils.api_get(self) + elif 'view_id' in self.data: + # Non-existing view/mview id + self.view_id = self.data["view_id"] + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_put.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_put.py index 5a68040b6..f1af5797b 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_put.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_put.py @@ -9,6 +9,7 @@ import json import uuid +from unittest.mock import patch from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ utils as schema_utils @@ -23,38 +24,24 @@ from . import utils as views_utils class ViewsUpdateTestCase(BaseTestGenerator): """This class will update the view/mview under schema node.""" - view_sql = "CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; " \ - "ALTER TABLE %s.%s OWNER TO %s" - m_view_sql = "CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS " \ - "SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER" \ - " TO %s" - scenarios = [ - ('Update view under schema node', dict( - url='/browser/view/obj/', - view_name="test_view_put_%s" % (str(uuid.uuid4())[1:8]), - sql_query=view_sql)), - ('Update materialized view under schema node', - dict(url='/browser/mview/obj/', - view_name="test_mview_put_%s" % (str(uuid.uuid4())[1:8]), - sql_query=m_view_sql)) - ] + # Generates scenarios + scenarios = utils.generate_scenarios("view_put", views_utils.test_cases) def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection self.db_name = parent_node_dict["database"][-1]["db_name"] schema_info = parent_node_dict["schema"][-1] self.server_id = schema_info["server_id"] self.db_id = schema_info["db_id"] - server_response = server_utils.connect_server(self, self.server_id) - - if server_response["data"]["version"] < 90300 and "mview" in self.url: - message = "Materialized Views are not supported by PG9.2 " \ - "and PPAS9.2 and below." - self.skipTest(message) - db_con = database_utils.connect_database(self, utils.SERVER_GROUP, self.server_id, self.db_id) if not db_con['data']["connected"]: raise Exception("Could not connect to database to update a view.") + + # Create schema self.schema_id = schema_info["schema_id"] self.schema_name = schema_info["schema_name"] schema_response = schema_utils.verify_schemas(self.server, @@ -62,11 +49,18 @@ class ViewsUpdateTestCase(BaseTestGenerator): self.schema_name) if not schema_response: raise Exception("Could not find the schema to update a view.") - self.view_id = views_utils.create_view(self.server, - self.db_name, - self.schema_name, - self.sql_query, + + query = self.inventory_data['query'] + + self.view_name = "test_view_update_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id = views_utils.get_view_id(self.server, self.db_name, self.view_name) + if self.view_id is None: + self.view_id = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name, query) def runTest(self): """This function will update the view/mview under schema node.""" @@ -74,17 +68,23 @@ class ViewsUpdateTestCase(BaseTestGenerator): self.view_name) if not view_response: raise Exception("Could not find the view to update.") - data = {"id": self.view_id, - "comment": "This is test comment" - } - response = self.tester.put( - "{0}{1}/{2}/{3}/{4}/{5}".format(self.url, utils.SERVER_GROUP, - self.server_id, self.db_id, - self.schema_id, self.view_id - ), - data=json.dumps(data), - follow_redirects=True) - self.assertEqual(response.status_code, 200) + + self.data["oid"] = self.view_id + + if self.is_positive_test: + response = views_utils.api_put(self) + + # Assert response + utils.assert_status_code(self, response) + else: + if self.mocking_required: + with patch(self.mock_data["function_name"], + side_effect=[eval(self.mock_data["return_value"])]): + response = views_utils.api_put(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) def tearDown(self): # Disconnect the database diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_sql.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_sql.py new file mode 100644 index 000000000..8d12b793c --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/test_views_sql.py @@ -0,0 +1,119 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import uuid +import json +from unittest.mock import patch + +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils import server_utils as server_utils +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 views_utils + + +class ViewsSqlTestCase(BaseTestGenerator): + """This class will fetch the view/mview sql under schema node.""" + + # Generates scenarios + scenarios = utils.generate_scenarios("view_sql", views_utils.test_cases) + + def setUp(self): + # Load test data + self.data = self.test_data + + # Create db connection + self.db_name = parent_node_dict["database"][-1]["db_name"] + schema_info = parent_node_dict["schema"][-1] + self.server_id = schema_info["server_id"] + self.db_id = schema_info["db_id"] + db_con = database_utils.connect_database(self, utils.SERVER_GROUP, + self.server_id, self.db_id) + + # Check DB version + if "server_min_version" in self.data: + server_con = server_utils.connect_server(self, self.server_id) + if not server_con["info"] == "Server connected.": + raise Exception("Could not connect to server to check version") + if "type" in server_con["data"] and \ + server_con["data"]["type"] == "pg": + self.skipTest("Compound Triggers are not supported by PG.") + elif server_con["data"]["type"] == "ppas" \ + and server_con["data"]["version"] < self.data[ + "server_min_version"]: + self.skipTest(self.data["skip_msg"]) + + if not db_con['data']["connected"]: + raise Exception("Could not connect to database to fetch the view.") + + # Create schema + self.schema_id = schema_info["schema_id"] + self.schema_name = schema_info["schema_name"] + schema_response = schema_utils.verify_schemas(self.server, + self.db_name, + self.schema_name) + if not schema_response: + raise Exception("Could not find the schema to fetch the view.") + + # Create view + query = self.inventory_data['query'] + + self.view_name = "test_view_sql_%s" % (str(uuid.uuid4())[1:8]) + + self.view_id = views_utils.create_view(self.server, + self.db_name, + self.schema_name, + self.view_name, + query) + + if hasattr(self, "trigger_fun_required"): + self.func_name = "trigger_func_get_%s" % str(uuid.uuid4())[1:8] + self.function_info = views_utils.\ + create_trigger_function_with_trigger(self.server, self.db_name, + self.schema_name, + self.func_name) + self.trigger_name = \ + "test_trigger_get_%s" % (str(uuid.uuid4())[1:8]) + self.trigger_id = views_utils.create_trigger(self.server, + self.db_name, + self.schema_name, + self.view_name, + self.trigger_name, + self.func_name, + "a") + + def runTest(self): + """This function will fetch the view/mview sql under schema node.""" + if self.is_positive_test: + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + + else: + if self.mocking_required: + with patch(self.mock_data["function_name"], + side_effect=[eval(self.mock_data["return_value"])]): + response = views_utils.api_get(self) + elif 'view_id' in self.data: + # Non-existing view id + self.view_id = self.data["view_id"] + response = views_utils.api_get(self) + + # Assert response + utils.assert_status_code(self, response) + utils.assert_error_message(self, response) + + def tearDown(self): + # Disconnect the database + database_utils.disconnect_database(self, self.server_id, self.db_id) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/utils.py index a76a370a9..58f25e7d2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/utils.py @@ -10,11 +10,150 @@ import sys import traceback +import os +import json from regression.python_test_utils import test_utils as utils +from urllib.parse import urlencode + +# Load test data from json file. +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/view_test_data.json") as data_file: + test_cases = json.load(data_file) -def create_view(server, db_name, schema_name, sql_query, view_name): +# api call methods +def api_create(self): + return self.tester.post("{0}{1}/{2}/{3}/{4}/". + format(self.url, utils.SERVER_GROUP, + self.server_id, self.db_id, + self.schema_id + ), + data=json.dumps(self.data), + content_type='html/json') + + +def api_get(self, view_id=None): + if view_id is None: + view_id = self.view_id + return self.tester.get("{0}{1}/{2}/{3}/{4}/{5}". + format(self.url, utils.SERVER_GROUP, + self.server_id, self.db_id, + self.schema_id, view_id), + follow_redirects=True) + + +def api_get_msql(self, url_encode_data): + 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.view_id, + urlencode(url_encode_data)), + follow_redirects=True + ) + + +def api_delete(self, view_id=None): + if view_id is None: + view_id = self.view_id + 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, view_id), + data=json.dumps(self.data), + follow_redirects=True) + + +def api_put(self): + return self.tester.put("{0}{1}/{2}/{3}/{4}/{5}". + format(self.url, utils.SERVER_GROUP, + self.server_id, self.db_id, + self.schema_id, self.view_id), + data=json.dumps(self.data), + follow_redirects=True) + + +def create_trigger_function_with_trigger(server, db_name, schema_name, + func_name): + """This function add the trigger function to schema""" + try: + connection = utils.get_db_connection(db_name, + server['username'], + server['db_password'], + server['host'], + server['port'], + server['sslmode']) + pg_cursor = connection.cursor() + query = "CREATE FUNCTION " + schema_name + "." + func_name + \ + "()" \ + " RETURNS trigger LANGUAGE 'plpgsql' STABLE LEAKPROOF" \ + " SECURITY DEFINER SET enable_sort=true AS $BODY$ BEGIN" \ + " NULL; END; $BODY$" + pg_cursor.execute(query) + connection.commit() + # Get 'oid' from newly created function + pg_cursor.execute("SELECT pro.oid, pro.proname FROM" + " pg_proc pro WHERE pro.proname='%s'" % + func_name) + functions = pg_cursor.fetchone() + connection.close() + return functions + except Exception: + traceback.print_exc(file=sys.stderr) + + +def create_trigger(server, db_name, schema_name, table_name, trigger_name, + trigger_func_name, trigger_func_arg=None): + """ + This function creates a column under provided table. + :param server: server details + :type server: dict + :param db_name: database name + :type db_name: str + :param schema_name: schema name + :type schema_name: str + :param table_name: table name + :type table_name: str + :param trigger_name: trigger name + :type trigger_name: str + :param trigger_func_name: trigger function name + :type trigger_func_name: str + :return trigger_id: trigger id + :rtype: int + """ + try: + connection = utils.get_db_connection(db_name, + server['username'], + server['db_password'], + server['host'], + server['port'], + server['sslmode']) + old_isolation_level = connection.isolation_level + connection.set_isolation_level(0) + pg_cursor = connection.cursor() + query = "CREATE TRIGGER %s INSTEAD OF DELETE ON %s.%s FOR EACH ROW " \ + "EXECUTE PROCEDURE %s.%s(%s)" % (trigger_name, schema_name, + table_name, schema_name, + trigger_func_name, + trigger_func_arg) + pg_cursor.execute(query) + connection.set_isolation_level(old_isolation_level) + connection.commit() + pg_cursor.execute("SELECT oid FROM pg_trigger where tgname='%s'" % + trigger_name) + trigger = pg_cursor.fetchone() + trigger_id = '' + if trigger: + trigger_id = trigger[0] + connection.close() + return trigger_id + except Exception: + traceback.print_exc(file=sys.stderr) + raise + + +def create_view(server, db_name, schema_name, view_name, sql_query=None, + mview_index=None): """ This function creates a table under provided schema. :param server: server details @@ -40,8 +179,7 @@ def create_view(server, db_name, schema_name, sql_query, view_name): old_isolation_level = connection.isolation_level connection.set_isolation_level(0) pg_cursor = connection.cursor() - query = sql_query % (schema_name, view_name, schema_name, view_name, - server['username']) + query = eval(sql_query) pg_cursor.execute(query) connection.set_isolation_level(old_isolation_level) connection.commit() diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/view_test_data.json b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/view_test_data.json new file mode 100644 index 000000000..11038c418 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/tests/view_test_data.json @@ -0,0 +1,1537 @@ +{ + "view_create": [ + { + "name": "Create view: With valid data.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": {}, + "test_data": { + "schema": "", + "owner": "", + "datacl": [], + "seclabels": [], + "name": "test_view_add_", + "definition": "SELECT 'Hello World';" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Create mview: With valid data.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": {}, + "test_data": { + "spcname": "pg_default", + "toast_autovacuum_enabled": false, + "autovacuum_enabled": false, + "schema": "", + "owner": "", + "vacuum_table": [ + { + "name": "autovacuum_analyze_scale_factor" + }, + { + "name": "autovacuum_analyze_threshold" + }, + { + "name": "autovacuum_freeze_max_age" + }, + { + "name": "autovacuum_vacuum_cost_delay" + }, + { + "name": "autovacuum_vacuum_cost_limit" + }, + { + "name": "autovacuum_vacuum_scale_factor" + }, + { + "name": "autovacuum_vacuum_threshold" + }, + { + "name": "autovacuum_freeze_min_age" + }, + { + "name": "autovacuum_freeze_table_age" + } + ], + "vacuum_toast": [ + { + "name": "autovacuum_freeze_max_age" + }, + { + "name": "autovacuum_vacuum_cost_delay" + }, + { + "name": "autovacuum_vacuum_cost_limit" + }, + { + "name": "autovacuum_vacuum_scale_factor" + }, + { + "name": "autovacuum_vacuum_threshold" + }, + { + "name": "autovacuum_freeze_min_age" + }, + { + "name": "autovacuum_freeze_table_age" + } + ], + "datacl": [], + "seclabels": [], + "name": "test_mview_add_", + "definition": "SELECT 'test_pgadmin';" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Create view: With insufficent data.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": {}, + "test_data": { + "owner": "", + "datacl": [] + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "Could not find the required parameter (name).", + "test_result_data": {} + } + } + ], + "view_get": [ + { + "name": "Get view: With existing view.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s; GRANT ALL ON TABLE %s.%s TO %s; GRANT INSERT ON TABLE %s.%s TO PUBLIC;\" % (schema_name, view_name, schema_name, view_name, server['username'],schema_name, view_name,server['username'], schema_name, view_name)" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With existing view with rule.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s; CREATE OR REPLACE RULE view_rule AS ON DELETE TO %s.%s DO NOTHING;\" % (schema_name, view_name, schema_name, view_name, server['username'],schema_name, view_name)" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With existing view having brackets.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT CASE WHEN (pg_db.datistemplate = false AND pg_db.datallowconn = true AND (pg_db.datconnlimit = -1 OR pg_db.datacl is null)) then true else false end as res FROM pg_database pg_db; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": { + "definition": " SELECT\n CASE\n WHEN ((pg_db.datistemplate = false) AND (pg_db.datallowconn = true) AND ((pg_db.datconnlimit = '-1'::integer) OR (pg_db.datacl IS NULL))) THEN true\n ELSE false\n END AS res\n FROM pg_database pg_db;" + } + }, + "is_list": false + }, + { + "name": "Get views list: With existing views.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": true + }, + { + "name": "Get Mview: With existing non-default privileges Mview.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s; GRANT SELECT ON TABLE %s.%s TO PUBLIC; GRANT ALL ON TABLE %s.%s TO %s;\" % (schema_name, view_name, schema_name, view_name, server['username'], schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get Mview: With existing Mview with index.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin'::text AS text WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s; CREATE INDEX mview_index ON %s.%s USING btree (text COLLATE pg_catalog.default) TABLESPACE pg_default; \" % (schema_name, view_name, schema_name, view_name, server['username'], schema_name, view_name)" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With non-existing view.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With existing view while server is down.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get views: With existing views while server is down.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": true + }, + { + "name": "Get Mview: With non-existing Mview.", + "url": "/browser/mview/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get Mview: With existing Mview while server is down.", + "url": "/browser/mview/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + } + ], + "view_delete": [ + { + "name": "Delete view: With existing view.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Delete views list: With existing views.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": true + }, + { + "name": "Delete Mview: With existing Mview.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Delete view: With non-existing view.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": "Error: Object not found.", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Delete view: With existing view while server is down.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Delete view: With existing view while server is down-2.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + } + ], + "view_get_nodes": [ + { + "name": "Get view: With existing view.", + "url": "/browser/view/nodes/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With existing view having brackets.", + "url": "/browser/view/nodes/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT CASE WHEN (pg_db.datistemplate = false AND pg_db.datallowconn = true AND (pg_db.datconnlimit = -1 OR pg_db.datacl is null)) then true else false end as res FROM pg_database pg_db; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": { + "definition": " SELECT\n CASE\n WHEN ((pg_db.datistemplate = false) AND (pg_db.datallowconn = true) AND ((pg_db.datconnlimit = '-1'::integer) OR (pg_db.datacl IS NULL))) THEN true\n ELSE false\n END AS res\n FROM pg_database pg_db;" + } + }, + "is_list": false + }, + { + "name": "Get views list: With existing views.", + "url": "/browser/view/nodes/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": true + }, + { + "name": "Get Mview: With existing Mview.", + "url": "/browser/mview/nodes/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With non-existing view.", + "url": "/browser/view/nodes/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view: With existing view while server is down.", + "url": "/browser/view/nodes/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get Mview: With non-existing Mview.", + "url": "/browser/mview/nodes/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + }, + "is_list": false + } + ], + "view_dependecies_dependents": [ + { + "name": "Get view dependents: With existing view.", + "url": "/browser/view/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_dependent": true + }, + { + "name": "Get view dependency: With existing view having brackets.", + "url": "/browser/view/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT CASE WHEN (pg_db.datistemplate = false AND pg_db.datallowconn = true AND (pg_db.datconnlimit = -1 OR pg_db.datacl is null)) then true else false end as res FROM pg_database pg_db; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": { + "definition": " SELECT\n CASE\n WHEN ((pg_db.datistemplate = false) AND (pg_db.datallowconn = true) AND ((pg_db.datconnlimit = '-1'::integer) OR (pg_db.datacl IS NULL))) THEN true\n ELSE false\n END AS res\n FROM pg_database pg_db;" + } + }, + "is_dependent": false + }, + { + "name": "Get Mview dependents : With existing Mview.", + "url": "/browser/mview/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_dependent": true + }, + { + "name": "Get Mview dependency : With existing Mview.", + "url": "/browser/mview/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_dependent": false + } + ], + "view_sql": [ + { + "name": "Get view sql: With existing view.", + "url": "/browser/view/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get view sql: With existing view having brackets.", + "url": "/browser/view/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT CASE WHEN (pg_db.datistemplate = false AND pg_db.datallowconn = true AND (pg_db.datconnlimit = -1 OR pg_db.datacl is null)) then true else false end as res FROM pg_database pg_db; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": { + "definition": " SELECT\n CASE\n WHEN ((pg_db.datistemplate = false) AND (pg_db.datallowconn = true) AND ((pg_db.datconnlimit = '-1'::integer) OR (pg_db.datacl IS NULL))) THEN true\n ELSE false\n END AS res\n FROM pg_database pg_db;" + } + } + }, + { + "name": "Get view sql: With existing view with rule.", + "url": "/browser/view/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s; GRANT ALL ON TABLE %s.%s TO %s; GRANT INSERT ON TABLE %s.%s TO PUBLIC; CREATE OR REPLACE RULE view_rule AS ON DELETE TO %s.%s DO NOTHING;\" % (schema_name, view_name, schema_name, view_name, server['username'],schema_name, view_name,server['username'],schema_name, view_name, schema_name, view_name)" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get view sql: With existing view having compound trigger.", + "url": "/browser/view/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s; CREATE OR REPLACE TRIGGER compound_trig FOR DELETE ON %s.%s COMPOUND TRIGGER var character varying(20) DEFAULT 'Global_var'; BEFORE STATEMENT IS BEGIN DBMS_OUTPUT.PUT_LINE('Before Statement: ' || var); var := 'BEFORE STATEMENT'; END; END compound_trig;\" % (schema_name, view_name, schema_name, view_name, server['username'], schema_name, view_name)" + }, + "test_data": { + "server_min_version": 120000, + "skip_msg": "Compound Triggers are not supported by EPAS server less than 12" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get Mview sql: With existing Mview.", + "url": "/browser/mview/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get Mview sql: With existing Mview with index.", + "url": "/browser/mview/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin'::text AS text WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s; CREATE INDEX %s ON %s.%s USING btree (text COLLATE pg_catalog.default) TABLESPACE pg_default; \" % (schema_name, view_name, schema_name, view_name, server['username'], mview_index, schema_name, view_name)" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get Mview sql : With existing non-default privileges Mview.", + "url": "/browser/mview/sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s; GRANT SELECT ON TABLE %s.%s TO PUBLIC; GRANT ALL ON TABLE %s.%s TO %s;\" % (schema_name, view_name, schema_name, view_name, server['username'], schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Get view sql: With non-existing view.", + "url": "/browser/view/sql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + } + }, + { + "name": "Get view sql: With existing view while server is down.", + "url": "/browser/view/sql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + } + }, + { + "name": "Get Mview sql: With non-existing Mview.", + "url": "/browser/mview/sql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + } + }, + { + "name": "Get Mview sql: With existing Mview while server is down.", + "url": "/browser/mview/sql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + } + }, + { + "name": "Get select view sql: With existing view.", + "url": "/browser/view/select_sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get select Mview sql: With existing Mview.", + "url": "/browser/mview/select_sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get select view sql: With Non-existing view.", + "url": "/browser/view/select_sql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + } + }, + { + "name": "Get insert view sql: With existing view.", + "url": "/browser/view/insert_sql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get insert view sql: With Non-existing view.", + "url": "/browser/view/insert_sql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999 + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + } + }, + { + "name": "Get view: With existing view & trigger on it.", + "url": "/browser/view/sql/", + "is_positive_test": true, + "trigger_fun_required": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get view children: With existing view & trigger on it.", + "url": "/browser/view/children/", + "is_positive_test": true, + "trigger_fun_required": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + } + ], + "view_put": [ + { + "name": "Update view: With existing view.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update view: With existing view & change definition.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 1; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment", + "definition": " SELECT 3;" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update view: With existing view changing privilages.", + "url": "/browser/view/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "Changing privilages.", + "datacl": { + "added": [ + { + "grantee": "PUBLIC", + "grantor": "postgres", + "privileges": [ + { + "privilege_type": "a", + "privilege": true, + "with_grant": false + } + ] + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: With existing Mview.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: With existing Mview by changing definition.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment", + "definition": "select 1" + + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update view: With existing view while server is down.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment" + }, + "mocking_required": true, + "mock_data": { + "function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_void", + "return_value": "(False,'Mocked Internal Server Error')" + }, + "expected_data": { + "status_code": 500, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Update view: With existing view while server is down.", + "url": "/browser/view/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment" + }, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Update: With existing Mview while server is down.", + "url": "/browser/mview/obj/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment" + }, + "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, + "error_msg": "Mocked Internal Server Error", + "test_result_data": {} + }, + "is_list": false + }, + { + "name": "Update Mview: Enable custom auto vacuum and set the parameters for table without autovacuum_enabled.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment", + "autovacuum_custom": true, + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_vacuum_cost_delay", + "value": 20 + }, + { + "name": "autovacuum_vacuum_threshold", + "value": 20 + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Change a parameter to zero value without autovacuum_enabled.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_vacuum_cost_delay", + "value": 0 + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Enable autovacuum_enabled", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "autovacuum_enabled": "t" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Reset individual parameters for table.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "autovacuum_enabled": "x", + "vacuum_table": { + "changed": [ + { + "name": "autovacuum_vacuum_cost_delay", + "value": null + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Reset custom auto vacuum.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "autovacuum_custom": false + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Enable toast custom auto vacuum and set the parameters for table without autovacuum_enabled.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "toast_autovacuum": true, + "vacuum_toast": { + "changed": [ + { + "name": "autovacuum_vacuum_cost_delay", + "value": 20 + }, + { + "name": "autovacuum_vacuum_threshold", + "value": 20 + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Change a toast parameter to zero value without autovacuum_enabled.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "vacuum_toast": { + "changed": [ + { + "name": "autovacuum_vacuum_cost_delay", + "value": 0 + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Enable toast.autovacuum_enabled.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "toast_autovacuum_enabled": "t" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Reset individual toast parameters for table.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "toast_autovacuum_enabled": "x", + "vacuum_toast": { + "changed": [ + { + "name": "autovacuum_vacuum_cost_delay", + "value": null + } + ] + } + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Update Mview: Reset auto vacuum.", + "url": "/browser/mview/obj/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "toast_autovacuum": false + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + } + ], + "mview_refresh": [ + { + "name": "Refresh Mview: Check utility route .", + "url": "browser/mview/check_utility_exists/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": {}, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_put_request": false + }, + { + "name": "Refresh Mview: With data.", + "url": "browser/mview/refresh_data/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "concurrent": "false", + "with_data": "true" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_put_request": true + }, + { + "name": "Refresh Mview: With no data.", + "url": "browser/mview/refresh_data/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "concurrent": "false", + "with_data": "false" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_put_request": true + }, + { + "name": "Refresh Mview: With data (concurrently).", + "url": "browser/mview/refresh_data/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "concurrent": "true", + "with_data": "true" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_put_request": true + }, + { + "name": "Refresh Mview: With no data (concurrently).", + "url": "browser/mview/refresh_data/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "concurrent": "true", + "with_data": "false" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + }, + "is_put_request": true + }, + { + "name": "Refresh Mview: With invalid oid.", + "url": "browser/mview/refresh_data/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "m_view_id": 999999, + "concurrent": "false", + "with_data": "false" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + }, + "is_put_request": true + } + ], + "view_get_msql": [ + { + "name": "Get view msql: With existing view.", + "url": "/browser/view/msql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "Testing msql api" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + }, + { + "name": "Get view msql: With Non-existing view.", + "url": "/browser/view/msql/", + "is_positive_test": false, + "inventory_data": { + "query": "\"CREATE OR REPLACE VIEW %s.%s AS SELECT 'Hello World'; ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "view_id": 9999, + "comment": "Testing msql api" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 410, + "error_msg": "could not find the specified none.", + "test_result_data": {} + } + }, + { + "name": "Get Mview msql: With existing Mview by changing definition.", + "url": "/browser/mview/msql/", + "is_positive_test": true, + "inventory_data": { + "query": "\"CREATE MATERIALIZED VIEW %s.%s TABLESPACE pg_default AS SELECT 'test_pgadmin' WITH NO DATA;ALTER TABLE %s.%s OWNER TO %s\" % (schema_name, view_name, schema_name, view_name, server['username'])" + }, + "test_data": { + "comment": "This is test comment", + "definition": "select 1" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200, + "error_msg": null, + "test_result_data": {} + } + } + ] +}