Align frontend API contracts

This commit is contained in:
2026-03-22 13:21:02 +01:00
parent 0da5b4abe2
commit e639b3c792
35 changed files with 1362 additions and 205 deletions

View File

@@ -74,6 +74,7 @@ class ExchangePeriodicTaskUpsertSerializerTest(SimpleTestCase):
"table": None,
"tables": None,
"truncate_before_copy": True,
"notify_on_error": False,
},
)
@@ -90,3 +91,18 @@ class ExchangePeriodicTaskUpsertSerializerTest(SimpleTestCase):
self.assertFalse(serializer.is_valid())
self.assertIn("table", serializer.errors)
def test_notify_on_error_is_added_to_payload(self):
serializer = ExchangePeriodicTaskUpsertSerializer(
data={
"name": "copy-job",
"schedule_type": "interval",
"interval_every": 1,
"interval_period": "hours",
"mode": "all",
"notify_on_error": True,
}
)
self.assertTrue(serializer.is_valid(), serializer.errors)
self.assertTrue(serializer.validated_data["payload"]["notify_on_error"])

View File

@@ -99,7 +99,8 @@ class ExchangeConnectionServiceUnitTest(TestCase):
self.assertEqual(result["status"], "success")
self.assertEqual(
result["message"], "Подключение и структура целевой БД валидны."
result["message"],
"Подключение проверено. Соединение и структура БД валидны.",
)
self.assertEqual(ExchangeConnection.objects.count(), 0)
test_connection_mock.assert_called_once()

View File

@@ -36,8 +36,7 @@ class ExchangeViewsTest(APITestCase):
self.client.force_authenticate(self.admin)
response = self.client.get(self.connections_url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(response.data["success"])
self.assertIsInstance(response.data["data"], list)
self.assertIsInstance(response.data["results"], list)
@patch("apps.exchange.services.ExchangeConnectionService.validate_target_structure")
@patch("apps.exchange.services.ExchangeConnectionService.test_connection")
@@ -58,8 +57,20 @@ class ExchangeViewsTest(APITestCase):
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(ExchangeConnection.objects.filter(is_active=True).count(), 1)
self.assertEqual(
set(response.data.keys()),
{
"id",
"server",
"port",
"username",
"database_name",
"schema_name",
"is_active",
},
)
new_connection = ExchangeConnection.objects.get(id=response.data["data"]["id"])
new_connection = ExchangeConnection.objects.get(id=response.data["id"])
self.assertTrue(new_connection.is_active)
self.assertNotEqual(new_connection.password, payload["password"])
self.assertEqual(new_connection.get_decrypted_password(), payload["password"])
@@ -89,7 +100,8 @@ class ExchangeViewsTest(APITestCase):
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.assertTrue(response.data["success"])
self.assertEqual(response.data["message"], "ok")
self.assertEqual(ExchangeConnection.objects.count(), 0)
test_connection_mock.assert_called_once_with(**payload)
@@ -180,8 +192,7 @@ class ExchangeViewsTest(APITestCase):
self.client.force_authenticate(self.admin)
response = self.client.get(self.periodic_tasks_url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(response.data["success"])
self.assertEqual(response.data["data"], [])
self.assertEqual(response.data["results"], [])
def test_create_periodic_interval_task_success(self):
payload = {
@@ -192,17 +203,34 @@ class ExchangeViewsTest(APITestCase):
"interval_every": 1,
"interval_period": "hours",
"mode": "all",
"notify_on_error": True,
}
self.client.force_authenticate(self.admin)
response = self.client.post(self.periodic_tasks_url, payload, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
task = PeriodicTask.objects.get(id=response.data["data"]["id"])
task = PeriodicTask.objects.get(id=response.data["id"])
self.assertEqual(task.task, ExchangePeriodicTaskService.TASK_NAME)
self.assertEqual(response.data["data"]["schedule_type"], "interval")
self.assertEqual(response.data["data"]["interval_every"], 1)
self.assertEqual(response.data["data"]["interval_period"], "hours")
self.assertEqual(
set(response.data.keys()),
{
"id",
"schedule_type",
"interval_every",
"interval_period",
"crontab_minute",
"crontab_hour",
"crontab_day_of_week",
"crontab_day_of_month",
"crontab_month_of_year",
"notify_on_error",
},
)
self.assertEqual(response.data["schedule_type"], "interval")
self.assertEqual(response.data["interval_every"], 1)
self.assertEqual(response.data["interval_period"], "hours")
self.assertTrue(response.data["notify_on_error"])
self.assertEqual(
json.loads(task.kwargs),
{
@@ -211,6 +239,7 @@ class ExchangeViewsTest(APITestCase):
"table": None,
"tables": None,
"truncate_before_copy": True,
"notify_on_error": True,
}
},
)
@@ -236,8 +265,8 @@ class ExchangeViewsTest(APITestCase):
response = self.client.get(self.periodic_tasks_url)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(len(response.data["data"]), 1)
self.assertEqual(response.data["data"][0]["name"], "exchange-copy-hourly")
self.assertEqual(len(response.data["results"]), 1)
self.assertEqual(response.data["results"][0]["schedule_type"], "interval")
def test_update_periodic_task_switches_to_crontab(self):
interval = IntervalSchedule.objects.create(every=1, period="hours")
@@ -272,6 +301,7 @@ class ExchangeViewsTest(APITestCase):
"mode": "single",
"table": "parsers_proxy",
"enabled": False,
"notify_on_error": True,
}
self.client.force_authenticate(self.admin)
@@ -283,10 +313,9 @@ class ExchangeViewsTest(APITestCase):
self.assertIsNotNone(task.crontab)
self.assertEqual(str(task.crontab.timezone), settings.TIME_ZONE)
self.assertFalse(task.enabled)
self.assertEqual(response.data["data"]["schedule_type"], "crontab")
self.assertEqual(response.data["data"]["crontab_hour"], "4")
self.assertEqual(response.data["data"]["mode"], "single")
self.assertEqual(response.data["data"]["table"], "parsers_proxy")
self.assertEqual(response.data["schedule_type"], "crontab")
self.assertEqual(response.data["crontab_hour"], "4")
self.assertTrue(response.data["notify_on_error"])
self.assertFalse(IntervalSchedule.objects.filter(id=interval.id).exists())
def test_periodic_task_detail_returns_404_for_non_exchange_task(self):