feat(admin): expand exchange admin and unify admin UX
Some checks failed
CI/CD Pipeline / Code Quality Checks (pull_request) Failing after 2m39s
CI/CD Pipeline / Run Tests (pull_request) Successful in 3m0s
CI/CD Pipeline / Run API Inventory E2E Tests (pull_request) Successful in 35s
CI/CD Pipeline / Telegram Notify Success (pull_request) Has been skipped
Some checks failed
CI/CD Pipeline / Code Quality Checks (pull_request) Failing after 2m39s
CI/CD Pipeline / Run Tests (pull_request) Successful in 3m0s
CI/CD Pipeline / Run API Inventory E2E Tests (pull_request) Successful in 35s
CI/CD Pipeline / Telegram Notify Success (pull_request) Has been skipped
This commit is contained in:
@@ -54,6 +54,9 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
"test_connection",
|
||||
return_value="target_alias",
|
||||
) as test_connection_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"prepare_target_structure",
|
||||
) as prepare_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"validate_target_structure",
|
||||
) as validate_mock:
|
||||
@@ -70,13 +73,22 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
self.assertIsNotNone(connection.last_checked_at)
|
||||
self.assertEqual(connection.last_error, "")
|
||||
test_connection_mock.assert_called_once_with(connection)
|
||||
prepare_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name="public",
|
||||
models_to_copy=None,
|
||||
)
|
||||
validate_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name="public",
|
||||
models_to_copy=None,
|
||||
)
|
||||
|
||||
def test_test_connection_payload_does_not_persist_connection(self):
|
||||
def test_validate_saved_connection_updates_timestamp_and_cleans_alias(self):
|
||||
connection = ExchangeConnectionFactory(last_error="old error")
|
||||
|
||||
with patch.object(
|
||||
ExchangeConnectionService,
|
||||
"test_connection",
|
||||
@@ -84,10 +96,85 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
) as test_connection_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"validate_target_structure",
|
||||
) as validate_mock, patch(
|
||||
"apps.exchange.services.connections"
|
||||
) as connections_mock:
|
||||
connections_mock.databases = {"target_alias": {}}
|
||||
) as validate_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"_cleanup_alias",
|
||||
) as cleanup_mock:
|
||||
result = ExchangeConnectionService.validate_saved_connection(connection)
|
||||
|
||||
self.assertEqual(result, connection)
|
||||
connection.refresh_from_db()
|
||||
self.assertEqual(connection.last_error, "")
|
||||
self.assertIsNotNone(connection.last_checked_at)
|
||||
test_connection_mock.assert_called_once_with(connection)
|
||||
validate_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name=connection.schema_name,
|
||||
models_to_copy=None,
|
||||
)
|
||||
cleanup_mock.assert_called_once_with("target_alias")
|
||||
|
||||
def test_validate_saved_connection_prepares_target_when_requested(self):
|
||||
connection = ExchangeConnectionFactory(last_error="old error")
|
||||
|
||||
with patch.object(
|
||||
ExchangeConnectionService,
|
||||
"test_connection",
|
||||
return_value="target_alias",
|
||||
) as test_connection_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"prepare_target_structure",
|
||||
) as prepare_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"validate_target_structure",
|
||||
) as validate_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"_cleanup_alias",
|
||||
) as cleanup_mock:
|
||||
ExchangeConnectionService.validate_saved_connection(
|
||||
connection,
|
||||
prepare_target=True,
|
||||
)
|
||||
|
||||
test_connection_mock.assert_called_once_with(connection)
|
||||
prepare_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name=connection.schema_name,
|
||||
models_to_copy=None,
|
||||
)
|
||||
validate_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name=connection.schema_name,
|
||||
models_to_copy=None,
|
||||
)
|
||||
cleanup_mock.assert_called_once_with("target_alias")
|
||||
|
||||
def test_activate_connection_validates_and_switches_active_flag(self):
|
||||
old_active = ExchangeConnectionFactory(is_active=True)
|
||||
new_connection = ExchangeConnectionFactory(is_active=False)
|
||||
|
||||
with patch.object(
|
||||
ExchangeConnectionService,
|
||||
"validate_saved_connection",
|
||||
return_value=new_connection,
|
||||
) as validate_mock:
|
||||
result = ExchangeConnectionService.activate_connection(new_connection)
|
||||
|
||||
self.assertEqual(result, new_connection)
|
||||
validate_mock.assert_called_once_with(new_connection, prepare_target=True)
|
||||
old_active.refresh_from_db()
|
||||
new_connection.refresh_from_db()
|
||||
self.assertFalse(old_active.is_active)
|
||||
self.assertTrue(new_connection.is_active)
|
||||
|
||||
def test_test_connection_payload_does_not_persist_connection(self):
|
||||
with patch.object(
|
||||
ExchangeConnectionService,
|
||||
"validate_saved_connection",
|
||||
) as validate_mock:
|
||||
result = ExchangeConnectionService.test_connection_payload(
|
||||
server="127.0.0.1",
|
||||
port=5432,
|
||||
@@ -103,7 +190,6 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
"Подключение проверено. Соединение и структура БД валидны.",
|
||||
)
|
||||
self.assertEqual(ExchangeConnection.objects.count(), 0)
|
||||
test_connection_mock.assert_called_once()
|
||||
validate_mock.assert_called_once()
|
||||
|
||||
def test_get_active_connection_raises_when_missing(self):
|
||||
@@ -272,6 +358,30 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
connection.refresh_from_db()
|
||||
self.assertEqual(connection.last_error, "unexpected")
|
||||
|
||||
def test_prepare_target_structure_creates_schema_and_missing_tables(self):
|
||||
connection = ExchangeConnectionFactory(schema_name="target_schema")
|
||||
db_connection = MagicMock()
|
||||
db_connection.ops.quote_name.return_value = '"target_schema"'
|
||||
cursor = MagicMock()
|
||||
cursor.fetchall.return_value = [("fake_table",)]
|
||||
db_connection.cursor.return_value.__enter__.return_value = cursor
|
||||
schema_editor = MagicMock()
|
||||
db_connection.schema_editor.return_value.__enter__.return_value = schema_editor
|
||||
connections_mock = MagicMock()
|
||||
connections_mock.__getitem__.return_value = db_connection
|
||||
|
||||
with patch("apps.exchange.services.connections", connections_mock):
|
||||
ExchangeConnectionService.prepare_target_structure(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name="target_schema",
|
||||
models_to_copy=[_FakeModel, _AnotherFakeModel],
|
||||
)
|
||||
|
||||
db_connection.ensure_connection.assert_called_once_with()
|
||||
cursor.execute.assert_any_call('CREATE SCHEMA IF NOT EXISTS "target_schema"')
|
||||
schema_editor.create_model.assert_called_once_with(_AnotherFakeModel)
|
||||
|
||||
def test_copy_parsers_data_success(self):
|
||||
connection = ExchangeConnectionFactory(schema_name="target_schema")
|
||||
db_connection = MagicMock()
|
||||
@@ -293,6 +403,9 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
"_extend_models_with_dependencies",
|
||||
return_value=[_FakeModel, _AnotherFakeModel],
|
||||
), patch.object(
|
||||
ExchangeConnectionService,
|
||||
"prepare_target_structure",
|
||||
) as prepare_mock, patch.object(
|
||||
ExchangeConnectionService,
|
||||
"validate_target_structure",
|
||||
) as validate_mock, patch.object(
|
||||
@@ -312,6 +425,12 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
self.assertEqual(result["rows_by_table"], {"fake_table": 2, "another_table": 3})
|
||||
self.assertEqual(result["total_rows"], 5)
|
||||
self.assertFalse(result["truncate_before_copy"])
|
||||
prepare_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
schema_name="target_schema",
|
||||
models_to_copy=[_FakeModel, _AnotherFakeModel],
|
||||
)
|
||||
validate_mock.assert_called_once_with(
|
||||
connection=connection,
|
||||
alias="target_alias",
|
||||
|
||||
Reference in New Issue
Block a user