Switch control and schedules to JSON payloads
This commit is contained in:
@@ -77,25 +77,25 @@ class ScheduleApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
first = await self.client.post(
|
||||
"/schedules/cron",
|
||||
headers=self._headers(),
|
||||
params={
|
||||
json={
|
||||
"target_id": "grp-1",
|
||||
"hour": "22",
|
||||
"minute": "00",
|
||||
"day_of_week": "1",
|
||||
"is_group": "true",
|
||||
"state": "true",
|
||||
"is_group": True,
|
||||
"state": True,
|
||||
},
|
||||
)
|
||||
second = await self.client.post(
|
||||
"/schedules/cron",
|
||||
headers=self._headers(),
|
||||
params={
|
||||
json={
|
||||
"target_id": "grp-1",
|
||||
"hour": "22",
|
||||
"minute": "00",
|
||||
"day_of_week": "5",
|
||||
"is_group": "true",
|
||||
"state": "false",
|
||||
"is_group": True,
|
||||
"state": False,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -126,11 +126,11 @@ class ScheduleApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/schedules/once",
|
||||
headers=self._headers(),
|
||||
params={
|
||||
json={
|
||||
"target_id": "grp-1",
|
||||
"run_at": run_at.isoformat(),
|
||||
"is_group": "true",
|
||||
"temp": "3200",
|
||||
"is_group": True,
|
||||
"temp": 3200,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -162,12 +162,12 @@ class ScheduleApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
create_response = await self.client.post(
|
||||
"/schedules/cron",
|
||||
headers=self._headers(),
|
||||
params={
|
||||
json={
|
||||
"target_id": "grp-1",
|
||||
"hour": "21",
|
||||
"minute": "15",
|
||||
"is_group": "true",
|
||||
"state": "true",
|
||||
"is_group": True,
|
||||
"state": True,
|
||||
},
|
||||
)
|
||||
job_id = create_response.json()["job_id"]
|
||||
@@ -220,12 +220,12 @@ class ScheduleApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/schedules/cron",
|
||||
headers=self._headers(),
|
||||
params={
|
||||
json={
|
||||
"target_id": "grp-1",
|
||||
"hour": "99",
|
||||
"minute": "99",
|
||||
"is_group": "true",
|
||||
"temp": "3200",
|
||||
"is_group": True,
|
||||
"temp": 3200,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -237,3 +237,38 @@ class ScheduleApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
rows = result.scalars().all()
|
||||
|
||||
self.assertEqual(rows, [])
|
||||
|
||||
async def test_once_schedule_requires_exactly_one_time_selector(self):
|
||||
run_at = datetime.now(app_tz) + timedelta(hours=2)
|
||||
response = await self.client.post(
|
||||
"/schedules/once",
|
||||
headers=self._headers(),
|
||||
json={
|
||||
"target_id": "grp-1",
|
||||
"run_at": run_at.isoformat(),
|
||||
"hours_from_now": 2,
|
||||
"is_group": True,
|
||||
"state": False,
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 422)
|
||||
self.assertIn(
|
||||
"Передайте ровно одно из полей run_at или hours_from_now",
|
||||
str(response.json()),
|
||||
)
|
||||
|
||||
async def test_schedule_rejects_legacy_query_only_contract(self):
|
||||
response = await self.client.post(
|
||||
"/schedules/cron",
|
||||
headers=self._headers(),
|
||||
params={
|
||||
"target_id": "grp-1",
|
||||
"hour": "7",
|
||||
"minute": "30",
|
||||
"is_group": "true",
|
||||
"state": "true",
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 422)
|
||||
|
||||
@@ -229,7 +229,7 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/control/device/dev-1",
|
||||
headers=self._master_headers(),
|
||||
params={"state": "true"},
|
||||
json={"state": True},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 504)
|
||||
@@ -263,7 +263,7 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/control/group/grp-1",
|
||||
headers=self._master_headers(),
|
||||
params={"state": "true"},
|
||||
json={"state": True},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -299,7 +299,7 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/control/group/grp-1",
|
||||
headers=self._master_headers(),
|
||||
params={"state": "true"},
|
||||
json={"state": True},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 504)
|
||||
@@ -368,13 +368,51 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/control/device/dev-1",
|
||||
headers=self._master_headers(),
|
||||
params={"scene": "not_a_scene"},
|
||||
json={"scene": "not_a_scene"},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
self.assertEqual(response.json()["detail"], "Неизвестная сцена")
|
||||
self.assertEqual(await self._event_actions(), [])
|
||||
|
||||
async def test_device_control_rejects_conflicting_scene_and_temp_in_body(self):
|
||||
self._set_single_device_state()
|
||||
|
||||
response = await self.client.post(
|
||||
"/control/device/dev-1",
|
||||
headers=self._master_headers(),
|
||||
json={"scene": "party", "temp": 3200},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 422)
|
||||
self.assertIn(
|
||||
"Можно передать только один режим из scene, temp или rgb",
|
||||
str(response.json()),
|
||||
)
|
||||
|
||||
async def test_device_control_rejects_partial_rgb_triplet(self):
|
||||
self._set_single_device_state()
|
||||
|
||||
response = await self.client.post(
|
||||
"/control/device/dev-1",
|
||||
headers=self._master_headers(),
|
||||
json={"r": 255, "g": 128},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 422)
|
||||
self.assertIn("Поля r, g и b нужно передавать вместе", str(response.json()))
|
||||
|
||||
async def test_device_control_rejects_legacy_query_only_contract(self):
|
||||
self._set_single_device_state()
|
||||
|
||||
response = await self.client.post(
|
||||
"/control/device/dev-1",
|
||||
headers=self._master_headers(),
|
||||
params={"state": "true"},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 422)
|
||||
|
||||
async def test_stats_summary_counts_real_commands_without_requested_duplicates(self):
|
||||
self._set_single_device_state()
|
||||
|
||||
@@ -393,7 +431,7 @@ class SecurityAndControlApiTests(unittest.IsolatedAsyncioTestCase):
|
||||
response = await self.client.post(
|
||||
"/control/device/dev-1",
|
||||
headers=self._master_headers(),
|
||||
params={"temp": "4200"},
|
||||
json={"temp": 4200},
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
Reference in New Issue
Block a user