From f0c86741a4efacc300bdb7d5c85a07e7ad0933a3 Mon Sep 17 00:00:00 2001 From: Rahul Shirsat Date: Tue, 30 Mar 2021 11:12:33 +0530 Subject: [PATCH] Improve code coverage and API test cases for Server module. Fixes #5319 --- docs/en_US/release_notes_5_2.rst | 1 + .../browser/server_groups/servers/__init__.py | 9 +- .../servers/tests/servers_test_data.json | 384 +++++++++++++++++- .../servers/tests/test_add_server.py | 24 ++ .../servers/tests/test_check_connect.py | 88 +++- .../servers/tests/test_check_recovery_code.py | 63 +++ .../tests/test_check_ssh_mock_connect.py | 99 +++++ .../servers/tests/test_password_change.py | 104 +++++ .../tests/servers_group_test_data.json | 45 ++ .../tests/test_servers_groups_childrens.py | 84 ++++ .../server_groups/tests/test_sg_get.py | 8 +- .../browser/server_groups/tests/utils.py | 16 + 12 files changed, 893 insertions(+), 32 deletions(-) create mode 100644 web/pgadmin/browser/server_groups/servers/tests/test_check_recovery_code.py create mode 100644 web/pgadmin/browser/server_groups/servers/tests/test_check_ssh_mock_connect.py create mode 100644 web/pgadmin/browser/server_groups/servers/tests/test_password_change.py create mode 100644 web/pgadmin/browser/server_groups/tests/servers_group_test_data.json create mode 100644 web/pgadmin/browser/server_groups/tests/test_servers_groups_childrens.py create mode 100644 web/pgadmin/browser/server_groups/tests/utils.py diff --git a/docs/en_US/release_notes_5_2.rst b/docs/en_US/release_notes_5_2.rst index 1f25157f1..d9162831a 100644 --- a/docs/en_US/release_notes_5_2.rst +++ b/docs/en_US/release_notes_5_2.rst @@ -13,6 +13,7 @@ New features Housekeeping ************ +| `Issue #5319 `_ - Improve code coverage and API test cases for Server module. Bug fixes ********* diff --git a/web/pgadmin/browser/server_groups/servers/__init__.py b/web/pgadmin/browser/server_groups/servers/__init__.py index 13a7e06b9..bc0bd4611 100644 --- a/web/pgadmin/browser/server_groups/servers/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/__init__.py @@ -1069,7 +1069,8 @@ class ServerNode(PGChildNodeView): tunnel_username=data.get('tunnel_username', None), tunnel_authentication=data.get('tunnel_authentication', 0), tunnel_identity_file=data.get('tunnel_identity_file', None), - shared=data.get('shared', None) + shared=data.get('shared', None), + passfile=data.get('passfile', None) ) db.session.add(server) db.session.commit() @@ -1572,7 +1573,11 @@ class ServerNode(PGChildNodeView): sid: Server id """ try: - data = json.loads(request.form['data'], encoding='utf-8') + if request.form and request.form['data']: + data = json.loads(request.form['data'], encoding='utf-8') + else: + data = json.loads(request.data, encoding='utf-8') + crypt_key = get_crypt_key()[1] # Fetch Server Details diff --git a/web/pgadmin/browser/server_groups/servers/tests/servers_test_data.json b/web/pgadmin/browser/server_groups/servers/tests/servers_test_data.json index 855fba055..9a1262d34 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/servers_test_data.json +++ b/web/pgadmin/browser/server_groups/servers/tests/servers_test_data.json @@ -186,6 +186,56 @@ "expected_data": { "status_code": 200 } + }, + { + "name": "Add server with ssl", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "sslcert": "postgres.crt", + "sslkey": "postgres.key", + "sslrootcert": "root.crt", + "sslmode": "prefer", + "sslcompression": true, + "sslcrl": "postgres.crl" + + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Add server with advanced properties", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "passfile": "test.pgpass", + "hostaddr": "127.0.0.1" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Add server with background/foreground color", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "fgcolor":"#FF9900", + "bgcolor": "#00FF00" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } } ], "is_password_saved": [ @@ -422,6 +472,56 @@ "status_code": 200 } }, + { + "name": "connect to a server using password (invalid user)", + "url": "/browser/server/connect/", + "is_positive_test": true, + "connect": true, + "invalid_user": true, + "mocking_required": true, + "mock_data": { + "function_name": "pgadmin.browser.server_groups.servers.User", + "return_value": "None" + }, + "expected_data": { + "status_code": 401 + } + }, + { + "name": "connect to a server using password (invalid server username)", + "url": "/browser/server/connect/", + "is_positive_test": true, + "connect": true, + "invalid_server_username": true, + "mocking_required": true, + "mock_data": { + "id": 1, + "name": "test_mock_server", + "username": "None", + "shared": true, + "service": false, + "user_id": "", + "function_name": "pgadmin.browser.server_groups.servers.Server", + "return_value": "None" + }, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Fail check recovery state on connected server", + "url": "/browser/server/connect/", + "is_positive_test": true, + "mocking_required": false, + "recovery_state": true, + "mock_data": { + "function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict", + "return_value": "(False, 'Mocked Internal Server Error while get recovery_state for server.')" + }, + "expected_data": { + "status_code": 200 + } + }, { "name": "Disconnect server test", "url": "/browser/server/connect/", @@ -470,6 +570,152 @@ } } ], + "connect_ssh_mock": [ + { + "name": "Try to connect server using ssh tunnel password", + "url": "/browser/server/connect/", + "is_positive_test": true, + "connect": true, + "ssh_tunnel_connect": true, + "mocking_required": false, + "mock_data": { + "id": 1, + "name": "test_mock_server", + "username": "postgre1", + "use_ssh_tunnel": 1, + "tunnel_host": "127.0.0.1", + "tunnel_port": 22, + "tunnel_username": "user", + "tunnel_authentication": 1, + "tunnel_password": "user123", + "tunnel_identity_file": "pkey_rsa", + "service": null, + "server_info": { + "id": 1, + "name": "test_mock_server", + "username": "postgres", + "passfile": false + }, + "user_info": { + "id": 1, + "username": "postgres", + "password": "1234" + }, + "manager": { + "server_type": "pg", + "password": "my_postgres", + "sversion": 100000, + "connection_connect_return_value": "psycopg2.OperationalError()" + } + }, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Try to connect server without ssh tunnel password", + "url": "/browser/server/connect/", + "is_positive_test": true, + "connect": true, + "ssh_tunnel_connect": true, + "mocking_required": false, + "mock_data": { + "id": 1, + "name": "test_mock_server", + "username": "postgre1", + "use_ssh_tunnel": 1, + "tunnel_host": "127.0.0.1", + "tunnel_port": 22, + "tunnel_username": "user", + "tunnel_authentication": 1, + "tunnel_password": "", + "tunnel_identity_file": "pkey_rsa", + "service": null, + "server_info": { + "id": 1, + "name": "test_mock_server", + "username": "postgres", + "passfile": false + }, + "user_info": { + "id": 1, + "username": "postgres", + "password": "1234" + }, + "manager": { + "server_type": "pg", + "password": "my_postgres", + "sversion": 100000, + "connection_connect_return_value": "OperationalError()" + } + }, + "expected_data": { + "status_code": 200 + } + } + ], + "wal_replay_server": [ + { + "name": "Pause the wal replay recovery control", + "url": "/browser/server/wal_replay/", + "is_positive_test": true, + "mocking_required": true, + "pause": true, + "mock_data": { + "function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar", + "return_value": "(True, {'rows': []})" + }, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Resume the wal replay recovery control", + "url": "/browser/server/wal_replay/", + "is_positive_test": true, + "mocking_required": true, + "pause": false, + "mock_data": { + "function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar", + "return_value": "(True, {'rows': []})" + }, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Error while wal replay pause", + "url": "/browser/server/wal_replay/", + "is_positive_test": false, + "pause": true, + "test_data": { + "comment": "PLACE_HOLDER", + "id": "PLACE_HOLDER", + "is_password_saved": false + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 500 + } + }, + { + "name": "Error while wal replay resume", + "url": "/browser/server/wal_replay/", + "is_positive_test": false, + "pause": false, + "test_data": { + "comment": "PLACE_HOLDER", + "id": "PLACE_HOLDER", + "is_password_saved": false + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 500 + } + } + ], "delete_server": [ { "name": "Delete a server URL", @@ -624,21 +870,6 @@ "status_code": 200 } }, - { - "name": "wal replay", - "url": "/browser/server/wal_replay/", - "is_positive_test": true, - "test_data": { - "comment": "PLACE_HOLDER", - "id": "PLACE_HOLDER", - "is_password_saved": false - }, - "mocking_required": false, - "mock_data": {}, - "expected_data": { - "status_code": 410 - } - }, { "name": "Clear ssh tunnel password", "url": "/browser/server/clear_sshtunnel_password/", @@ -687,6 +918,89 @@ "expected_data": { "status_code": 200 } + }, + { + "name": "update ssl properties of server", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "sslcert": "postgres_01.crt", + "sslkey": "postgres_01.key", + "sslrootcert": "root_01.crt", + "sslmode": "allow", + "sslcompression": false, + "sslcrl": "postgres.crl" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "update advanced properties of server", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "passfile": "test_01.pgpass", + "hostaddr": "127.0.0.1" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "remove ssl properties from server", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "sslcert": "", + "sslkey": "", + "sslrootcert": "", + "sslmode": "prefer", + "sslcompression": false, + "sslcrl": "" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "remove advanced properties from server", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "passfile": "", + "hostaddr": "" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } + }, + { + "name": "Update server with background/foreground color", + "url": "/browser/server/obj/", + "is_positive_test": true, + "owner_server": true, + "test_data": { + "fgcolor":"#B6D7A8", + "bgcolor": "#0C343D" + }, + "mocking_required": false, + "mock_data": {}, + "expected_data": { + "status_code": 200 + } } ], "update_shared_server": [ @@ -858,5 +1172,45 @@ "status_code": 200 } } + ], + "change_password": [ + { + "name": "Change password", + "url": "/browser/server/change_password/", + "is_positive_test": true, + "mocking_required": true, + "mock_data": { + "server_info": { + "sid": 1, + "name": "test_mock_server", + "username": "postgres", + "password": "post123", + "passfile": false + }, + "user_info": { + "id": 1, + "username": "postgres", + "password": "1234" + }, + "manager": { + "server_type": "pg", + "password": "my_postgres", + "sversion": 100000, + "connection_execute_scalar_return_value": "(True, {'rows': []})" + } + }, + "test_data": { + "form_data" : { + "user_name": "my_postgres", + "password": "my_postgres", + "newPassword": "my_postgres1", + "confirmPassword": "my_postgres1" + } + }, + "expected_data": { + "status_code": 200, + "update_session": true + } + } ] } diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_add_server.py b/web/pgadmin/browser/server_groups/servers/tests/test_add_server.py index ee6bf9f92..6f6165e37 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/test_add_server.py +++ b/web/pgadmin/browser/server_groups/servers/tests/test_add_server.py @@ -62,6 +62,30 @@ class AddServerTest(BaseTestGenerator): self.server['connect_now'] = self.test_data['connect_now'] self.server['password'] = self.server['db_password'] + # SSL properties + if 'sslcert' in self.test_data: + self.server['sslcert'] = self.test_data['sslcert'] + if 'sslkey' in self.test_data: + self.server['sslkey'] = self.test_data['sslkey'] + if 'sslrootcert' in self.test_data: + self.server['sslrootcert'] = self.test_data['sslrootcert'] + if 'sslmode' in self.test_data: + self.server['sslmode'] = self.test_data['sslmode'] + if 'sslcompression' in self.test_data: + self.server['sslcompression'] = self.test_data['sslcompression'] + + # Advanced tab properties + if 'passfile' in self.test_data: + self.server['passfile'] = self.test_data['passfile'] + if 'hostaddr' in self.test_data: + self.server['hostaddr'] = self.test_data['hostaddr'] + + # Background/Foreground color + if 'fgcolor' in self.test_data: + self.server['fgcolor'] = self.test_data['fgcolor'] + if 'bgcolor' in self.test_data: + self.server['bgcolor'] = self.test_data['bgcolor'] + if self.is_positive_test: if hasattr(self, 'with_save'): self.server['save_password'] = self.with_save diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_check_connect.py b/web/pgadmin/browser/server_groups/servers/tests/test_check_connect.py index d1e2ddf66..86485c0c7 100644 --- a/web/pgadmin/browser/server_groups/servers/tests/test_check_connect.py +++ b/web/pgadmin/browser/server_groups/servers/tests/test_check_connect.py @@ -12,6 +12,7 @@ from regression import parent_node_dict from regression.python_test_utils import test_utils as utils from . import utils as servers_utils import json +from unittest.mock import patch, MagicMock class ServersConnectTestCase(BaseTestGenerator): @@ -25,18 +26,18 @@ class ServersConnectTestCase(BaseTestGenerator): def get_ssh_tunnel(self): print("in_get_ssh") - self.server['use_ssh_tunnel'] = 1 - self.server['tunnel_host'] = '127.0.0.1' - self.server['tunnel_port'] = 22 - self.server['tunnel_username'] = 'user' - if self.with_password: - self.server['tunnel_authentication'] = 0 + self.server.use_ssh_tunnel = 1 + self.server.tunnel_host = '127.0.0.1' + self.server.tunnel_port = 22 + self.server.tunnel_username = 'user' + if hasattr(self, 'with_password') and self.with_password: + self.server.tunnel_authentication = 0 else: - self.server['tunnel_authentication'] = 1 - self.server['tunnel_identity_file'] = 'pkey_rsa' + self.server.tunnel_authentication = 1 + self.server.tunnel_identity_file = 'pkey_rsa' - if self.save_password: - self.server['tunnel_password'] = '123456' + if hasattr(self, 'save_password') and self.save_password: + self.server.tunnel_password = '123456' def setUp(self): """This function add the server to test the GET API""" @@ -84,7 +85,49 @@ class ServersConnectTestCase(BaseTestGenerator): utils.SERVER_GROUP, self.server_id) self.server['password'] = self.server['db_password'] - response = self.connect_to_server(url) + + if self.mocking_required: + if hasattr(self, "invalid_user"): + with patch(self.mock_data['function_name'], + side_effect=[eval(self.mock_data[ + "return_value"])]) as user_mock: + + user_mock_result = user_mock.query.filter_by.\ + return_value + user_mock_result.first.return_value = None + response = self.connect_to_server(url) + + elif hasattr(self, "invalid_server_username"): + with patch(self.mock_data['function_name'], + side_effect=[eval(self.mock_data[ + "return_value"])]) as server_mock: + + class TestMockServer(): + def __init__(self, name, id, username, shared, + service): + self.name = name + self.id = id + self.username = username + self.shared = shared + self.service = service + self.user_id = id + + mock_server_obj = TestMockServer( + self.mock_data['name'], + self.mock_data['id'], + eval(self.mock_data['username']), + self.mock_data['shared'], + self.mock_data['service'] + ) + + server_mock_result = server_mock.query.filter_by.\ + return_value + server_mock_result.first.return_value = \ + mock_server_obj + + response = self.connect_to_server(url) + else: + response = self.connect_to_server(url) elif hasattr(self, 'restore_point') or hasattr(self, 'change_password'): connect_url = '/browser/server/connect/{0}/{1}'.format( @@ -96,6 +139,29 @@ class ServersConnectTestCase(BaseTestGenerator): self.connect_to_server(connect_url) response = self.add_server_details(url) + elif hasattr(self, "recovery_state") and self.recovery_state: + with patch('pgadmin.browser.server_groups.' + 'servers.get_driver') as get_driver_mock: + + self.manager = MagicMock() + get_driver_mock.return_value = MagicMock( + connection_manager=MagicMock( + execute_dict=MagicMock( + return_value=self.manager.connection), + return_value=self.manager) + ) + self.manager.version = 10 + + connection_mock_result = \ + self.manager.connection.return_value + self.manager.connection.connected.side_effect = True + + connection_mock_result.execute_dict.side_effect = \ + [eval(self.mock_data["return_value"])] + + response = self.get_server_connection(server_id) + self.assertEquals(response.status_code, + self.expected_data["status_code"]) else: response = self.get_server_connection(server_id) diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_check_recovery_code.py b/web/pgadmin/browser/server_groups/servers/tests/test_check_recovery_code.py new file mode 100644 index 000000000..1583ca15f --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/tests/test_check_recovery_code.py @@ -0,0 +1,63 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2021, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from . import utils as servers_utils +from regression import parent_node_dict +from unittest.mock import patch +import json + + +class CheckRecoveryCodeTestCase(BaseTestGenerator): + """ + This class will try to test cover the wal_reply code. + """ + + scenarios = utils.generate_scenarios('wal_replay_server', + servers_utils.test_cases) + + def resume_wal_replay(self): + return self.tester.put( + self.url + str(utils.SERVER_GROUP) + '/' + str(self.server_id)) + + def pause_wal_replay(self): + return self.tester.delete( + self.url + str(utils.SERVER_GROUP) + '/' + str(self.server_id)) + + def runTest(self): + + server_id = parent_node_dict["server"][-1]["server_id"] + if not server_id: + raise Exception("Server not found to test GET API") + + if self.mocking_required: + + with patch(self.mock_data['function_name'], + side_effect=[eval(self.mock_data['return_value'])]): + response = self.run_test_cases() + + res = json.loads(response.data.decode('utf-8')) + self.assertEqual(res['data']['in_recovery'], True) + self.assertEqual(res['data']['wal_pause'], self.pause) + self.assertEquals(response.status_code, + self.expected_data["status_code"]) + else: + response = self.run_test_cases() + self.assertEquals(response.status_code, + self.expected_data["status_code"]) + + def run_test_cases(self): + + if hasattr(self, 'pause') and self.pause: + response = self.pause_wal_replay() + else: + response = self.resume_wal_replay() + + return response diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_check_ssh_mock_connect.py b/web/pgadmin/browser/server_groups/servers/tests/test_check_ssh_mock_connect.py new file mode 100644 index 000000000..4bed4d357 --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/tests/test_check_ssh_mock_connect.py @@ -0,0 +1,99 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2021, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from . import utils as servers_utils +from unittest.mock import patch, MagicMock +import json +from psycopg2 import OperationalError + + +class ServersSSHConnectTestCase(BaseTestGenerator): + """ + This class will try to mock connect server with ssh credentials. + """ + + scenarios = utils.generate_scenarios('connect_ssh_mock', + servers_utils.test_cases) + + def connect_to_server(self, url, server): + return self.tester.post( + url, + data=json.dumps(server), + content_type='html/json' + ) + + @patch('pgadmin.browser.server_groups.servers.get_driver') + @patch('pgadmin.browser.server_groups.servers.Server') + def runTest(self, server_mock, get_driver_mock): + + if self.mock_data is not None and \ + self.mock_data['use_ssh_tunnel'] == 1: + + self.manager = MagicMock() + get_driver_mock.return_value = MagicMock( + connection_manager=MagicMock( + execute_scalar=MagicMock( + return_value=self.manager.connection), + return_value=self.manager) + ) + self.manager.password = self.mock_data['manager']['password'] + self.manager.server_type = self.mock_data['manager']['server_type'] + self.manager.sversion = self.mock_data['manager']['sversion'] + + self.manager.connection().connect.side_effect = \ + MagicMock(side_effect=OperationalError()) + + url = self.url + '{0}/{1}'.format(utils.SERVER_GROUP, 1) + + class TestMockServer(): + def __init__(self, name, id, username, use_ssh_tunnel, + tunnel_host, tunnel_port, + tunnel_username, tunnel_authentication, + tunnel_identity_file, tunnel_password, service): + self.name = name + self.id = id + self.username = username + + self.use_ssh_tunnel = use_ssh_tunnel + self.tunnel_host = tunnel_host + self.tunnel_port = tunnel_port + self.tunnel_username = tunnel_username + self.tunnel_authentication = \ + tunnel_authentication + self.tunnel_identity_file = \ + tunnel_identity_file + self.tunnel_password = tunnel_password + self.service = service + self.shared = None + + mock_server_obj = TestMockServer( + self.mock_data['name'], + self.mock_data['id'], + self.mock_data['username'], + self.mock_data['use_ssh_tunnel'], + self.mock_data['tunnel_host'], + self.mock_data['tunnel_port'], + self.mock_data['tunnel_username'], + self.mock_data['tunnel_authentication'], + self.mock_data['tunnel_identity_file'], + self.mock_data['tunnel_password'], + self.mock_data['service'], + ) + + server_mock_result = server_mock.query.filter_by.return_value + server_mock_result.first.return_value = mock_server_obj + + if self.mock_data['tunnel_password'] == '': + del self.server['tunnel_password'] + + response = self.connect_to_server(url, self.server) + + self.assertEqual(response.status_code, 500) diff --git a/web/pgadmin/browser/server_groups/servers/tests/test_password_change.py b/web/pgadmin/browser/server_groups/servers/tests/test_password_change.py new file mode 100644 index 000000000..f5ff7d14d --- /dev/null +++ b/web/pgadmin/browser/server_groups/servers/tests/test_password_change.py @@ -0,0 +1,104 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2021, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from . import utils as servers_utils +from unittest.mock import patch, MagicMock + + +class DBPasswordChange(BaseTestGenerator): + """ This class will test the change password functionality. """ + + scenarios = utils.generate_scenarios('change_password', + servers_utils.test_cases) + + def setUp(self): + self.server_id = utils.create_server(self.server) + server_dict = {"server_id": self.server_id} + utils.write_node_info("sid", server_dict) + + @patch('pgadmin.browser.server_groups.servers.render_template') + @patch('pgadmin.browser.server_groups.servers.pqencryptpassword') + @patch('pgadmin.browser.server_groups.servers.decrypt') + @patch('pgadmin.browser.server_groups.servers.get_driver') + @patch('pgadmin.browser.server_groups.servers.db') + @patch('pgadmin.browser.server_groups.servers.Server') + @patch('pgadmin.browser.server_groups.servers.User') + @patch('pgadmin.browser.server_groups.servers.current_user') + def runTest(self, current_user_mock, user_mock, server_mock, db_mock, + get_driver_mock, decrypt_mock, pqencryptpassword_mock, + render_template_mock): + + current_user_mock.id = 1 + + self.manager = MagicMock() + get_driver_mock.return_value = MagicMock( + connection_manager=MagicMock(execute_scalar=MagicMock( + return_value=self.manager.connection), + return_value=self.manager) + ) + self.manager.password = self.mock_data['manager']['password'] + self.manager.server_type = self.mock_data['manager']['server_type'] + self.manager.sversion = self.mock_data['manager']['sversion'] + self.manager.connection().execute_scalar.return_value = \ + eval(self.mock_data['manager'] + ['connection_execute_scalar_return_value']) + + decrypt_mock.return_value = self.manager.password + pqencryptpassword_mock.return_value = self.manager.password + + class TestMockServer(): + def __init__(self, name, sid, password, passfile): + self.name = name + self.sid = sid + self.password = password + self.passfile = passfile + + class TestUser(): + def __init__(self, id, username, password): + self.id = id + self.username = username + self.password = password + + db_mock.session.commit = MagicMock(return_value=True) + + mock_server_obj = TestMockServer( + self.mock_data['server_info']['username'], + self.mock_data['server_info']['sid'], + self.mock_data['server_info']['password'], + self.mock_data['server_info']['passfile'] + ) + server_mock_result = server_mock.query.filter_by.return_value + server_mock_result.first.return_value = mock_server_obj + + mock_user_obj = TestUser(self.mock_data['user_info']['id'], + self.mock_data['user_info']['username'], + self.mock_data['user_info']['password']) + + user_mock_result = user_mock.query.filter_by.return_value + user_mock_result.first.return_value = mock_user_obj + + """This function will execute the connect server APIs""" + response = self.tester.post( + self.url + str(1) + '/' + str(mock_server_obj.sid), + data=json.dumps(self.test_data['form_data']), + follow_redirects=True + ) + + self.assertEqual(response.status_code, + self.expected_data['status_code']) + + self.assertEquals(render_template_mock.called, True) + self.assertEquals(self.manager.update_session.called, + self.expected_data['update_session']) + self.assertEqual( + self.manager.connection().pq_encrypt_password_conn.called, True) diff --git a/web/pgadmin/browser/server_groups/tests/servers_group_test_data.json b/web/pgadmin/browser/server_groups/tests/servers_group_test_data.json new file mode 100644 index 000000000..f0c35b7fb --- /dev/null +++ b/web/pgadmin/browser/server_groups/tests/servers_group_test_data.json @@ -0,0 +1,45 @@ +{ + "get_server_group_children": [ + { + "name": "Get the all children of server group", + "url": "/browser/server_group/children/", + "is_positive_test": true, + "children": true, + "mocking_required": true, + "mock_data": { + "id": 1, + "name": "test_mock_server", + "username": "postgre1", + "use_ssh_tunnel": 1, + "tunnel_host": "127.0.0.1", + "tunnel_port": 22, + "tunnel_username": "user", + "tunnel_authentication": 1, + "tunnel_password": "user123", + "tunnel_identity_file": "pkey_rsa", + "service": null, + "fgcolor":"#B6D7A8", + "bgcolor": "#0C343D", + "servergroup_id": 5, + "server_owner": "admin" + }, + "expected_data": { + "status_code": 200 + } + } + ], + "get_server_group": [ + { + "name": "Check Server Group Node", + "url": "/browser/server_group/obj/", + "is_positive_test": true, + "children": true, + "mocking_required": false, + "mock_data": { + }, + "expected_data": { + "status_code": 200 + } + } + ] +} diff --git a/web/pgadmin/browser/server_groups/tests/test_servers_groups_childrens.py b/web/pgadmin/browser/server_groups/tests/test_servers_groups_childrens.py new file mode 100644 index 000000000..4f4d439c6 --- /dev/null +++ b/web/pgadmin/browser/server_groups/tests/test_servers_groups_childrens.py @@ -0,0 +1,84 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2021, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from . import utils as cast_utils +from regression.test_setup import config_data +import json +import config +from unittest.mock import patch +from regression.python_test_utils.test_utils import \ + create_user_wise_test_client + +test_user_details = None +if config.SERVER_MODE: + test_user_details = config_data['pgAdmin4_test_non_admin_credentials'] + + +class ServerGroupsChildren(BaseTestGenerator): + """ + This class will fetch all children of server group by response code. + """ + + scenarios = utils.generate_scenarios('get_server_group_children', + cast_utils.test_cases) + + def get_server(self, server_id): + return self.tester.get(self.url + str(utils.SERVER_GROUP) + '/' + + str(server_id), + follow_redirects=True) + + def setUp(self): + + if config.SERVER_MODE is True: + self.server['shared'] = True + url = "/browser/server/obj/{0}/".format(utils.SERVER_GROUP) + response = self.tester.post( + url, + data=json.dumps(self.server), + content_type='html/json' + ) + response_data = json.loads(response.data.decode('utf-8')) + self.server_id = response_data['node']['_id'] + + server_dict = {"server_id": response_data['node']['_id']} + utils.write_node_info("sid", server_dict) + + def runTest(self): + + if config.SERVER_MODE is True: + self.testServerGroupsForServerMode() + else: + self.testServerGroupsForDesktopMode() + + @patch('pgadmin.browser.server_groups.servers.current_user') + @create_user_wise_test_client(test_user_details) + def testServerGroupsForServerMode(self, current_user_mock): + + current_user_mock.id = 103040 + self.server_group_id = config_data['server_group'] + + response = self.tester.get(self.url + str(self.server_group_id), + content_type='html/json') + self.assertTrue(response.status_code, 200) + response_data = json.loads(response.data.decode('utf8')) + self.assertTrue(response_data['success'], 1) + + @patch('pgadmin.browser.server_groups.servers.current_user') + def testServerGroupsForDesktopMode(self, current_user_mock): + + current_user_mock.id = 1 + self.server_group_id = config_data['server_group'] + + response = self.tester.get(self.url + str(self.server_group_id), + content_type='html/json') + self.assertTrue(response.status_code, 200) + response_data = json.loads(response.data.decode('utf8')) + self.assertTrue(response_data['success'], 1) diff --git a/web/pgadmin/browser/server_groups/tests/test_sg_get.py b/web/pgadmin/browser/server_groups/tests/test_sg_get.py index cdfd3d76e..e5c680133 100644 --- a/web/pgadmin/browser/server_groups/tests/test_sg_get.py +++ b/web/pgadmin/browser/server_groups/tests/test_sg_get.py @@ -11,6 +11,8 @@ import json from pgadmin.utils.route import BaseTestGenerator from regression.test_setup import config_data +from regression.python_test_utils import test_utils as utils +from . import utils as cast_utils class SgNodeTestCase(BaseTestGenerator): @@ -18,10 +20,8 @@ class SgNodeTestCase(BaseTestGenerator): This class will check available server groups in pgAdmin. """ - scenarios = [ - # Fetching the default url for server group node - ('Check Server Group Node', dict(url='/browser/server_group/obj/')) - ] + scenarios = utils.generate_scenarios('get_server_group', + cast_utils.test_cases) def runTest(self): """This function will check available server groups.""" diff --git a/web/pgadmin/browser/server_groups/tests/utils.py b/web/pgadmin/browser/server_groups/tests/utils.py new file mode 100644 index 000000000..1a59cca4c --- /dev/null +++ b/web/pgadmin/browser/server_groups/tests/utils.py @@ -0,0 +1,16 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2021, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""Server Group helper utilities""" +import os +import json + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +with open(CURRENT_PATH + "/servers_group_test_data.json") as data_file: + test_cases = json.load(data_file)