Fix admin API gaps for users, exchange checks, and parser logs
This commit is contained in:
@@ -4,6 +4,7 @@ from contextlib import suppress
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from apps.exchange.models import ExchangeConnection
|
||||
from apps.exchange.services import ExchangeConnectionService, ExchangeServiceError
|
||||
from apps.parsers.models import (
|
||||
ManufacturerRecord,
|
||||
@@ -75,6 +76,35 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
schema_name="public",
|
||||
)
|
||||
|
||||
def test_test_connection_payload_does_not_persist_connection(self):
|
||||
with patch.object(
|
||||
ExchangeConnectionService,
|
||||
"test_connection",
|
||||
return_value="target_alias",
|
||||
) 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": {}}
|
||||
result = ExchangeConnectionService.test_connection_payload(
|
||||
server="127.0.0.1",
|
||||
port=5432,
|
||||
username="postgres",
|
||||
password=_db_secret(),
|
||||
database_name="target_db",
|
||||
schema_name="public",
|
||||
)
|
||||
|
||||
self.assertEqual(result["status"], "success")
|
||||
self.assertEqual(
|
||||
result["message"], "Подключение и структура целевой БД валидны."
|
||||
)
|
||||
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):
|
||||
with self.assertRaisesMessage(
|
||||
ExchangeServiceError,
|
||||
@@ -124,6 +154,28 @@ class ExchangeConnectionServiceUnitTest(TestCase):
|
||||
self.assertEqual(connection.last_error, "boom")
|
||||
self.assertIsNotNone(connection.last_checked_at)
|
||||
|
||||
def test_test_connection_failure_for_unsaved_connection_does_not_try_to_save(self):
|
||||
connection = ExchangeConnectionFactory.build(last_error="")
|
||||
db_connection = MagicMock()
|
||||
db_connection.ensure_connection.side_effect = RuntimeError("boom")
|
||||
connections_mock = MagicMock()
|
||||
connections_mock.__getitem__.return_value = db_connection
|
||||
|
||||
with patch.object(
|
||||
ExchangeConnectionService,
|
||||
"_configure_alias",
|
||||
return_value="exchange_target_unsaved",
|
||||
), patch(
|
||||
"apps.exchange.services.connections", connections_mock
|
||||
), self.assertRaisesMessage(
|
||||
ExchangeServiceError,
|
||||
"Ошибка подключения к целевой БД: boom",
|
||||
):
|
||||
ExchangeConnectionService.test_connection(connection)
|
||||
|
||||
self.assertEqual(connection.last_error, "boom")
|
||||
self.assertIsNotNone(connection.last_checked_at)
|
||||
|
||||
def test_validate_target_structure_calls_all_validation_steps(self):
|
||||
connection = ExchangeConnectionFactory()
|
||||
db_connection = MagicMock()
|
||||
|
||||
@@ -18,6 +18,7 @@ class ExchangeViewsTest(APITestCase):
|
||||
self.user = UserFactory.create_user()
|
||||
self.admin = UserFactory.create_superuser()
|
||||
self.connections_url = reverse("api_v1:exchange:connections")
|
||||
self.test_connection_url = reverse("api_v1:exchange:connections-test")
|
||||
self.copy_url = reverse("api_v1:exchange:copy")
|
||||
|
||||
def test_connections_endpoint_admin_only(self):
|
||||
@@ -65,6 +66,47 @@ class ExchangeViewsTest(APITestCase):
|
||||
connection_mock.assert_called_once()
|
||||
validate_mock.assert_called_once()
|
||||
|
||||
@patch("apps.exchange.services.ExchangeConnectionService.test_connection_payload")
|
||||
def test_test_connection_success(self, test_connection_mock):
|
||||
payload = {
|
||||
"server": "127.0.0.1",
|
||||
"port": 5432,
|
||||
"username": "postgres",
|
||||
"password": "secret",
|
||||
"database_name": "target_db",
|
||||
"schema_name": "public",
|
||||
}
|
||||
test_connection_mock.return_value = {
|
||||
"status": "success",
|
||||
"message": "ok",
|
||||
}
|
||||
|
||||
self.client.force_authenticate(self.admin)
|
||||
response = self.client.post(self.test_connection_url, payload, format="json")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data["data"]["status"], "success")
|
||||
self.assertEqual(ExchangeConnection.objects.count(), 0)
|
||||
test_connection_mock.assert_called_once_with(**payload)
|
||||
|
||||
@patch("apps.exchange.services.ExchangeConnectionService.test_connection_payload")
|
||||
def test_test_connection_failure_returns_400(self, test_connection_mock):
|
||||
payload = {
|
||||
"server": "127.0.0.1",
|
||||
"port": 5432,
|
||||
"username": "postgres",
|
||||
"password": "secret",
|
||||
"database_name": "target_db",
|
||||
"schema_name": "public",
|
||||
}
|
||||
test_connection_mock.side_effect = ExchangeServiceError("Connection refused")
|
||||
|
||||
self.client.force_authenticate(self.admin)
|
||||
response = self.client.post(self.test_connection_url, payload, format="json")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
|
||||
self.assertEqual(ExchangeConnection.objects.count(), 0)
|
||||
|
||||
@patch("apps.exchange.services.ExchangeConnectionService.test_connection")
|
||||
def test_create_connection_fail_rolls_back_active(self, connection_mock):
|
||||
connection_mock.side_effect = ExchangeServiceError("Connection refused")
|
||||
|
||||
Reference in New Issue
Block a user