@@ -0,0 +1,139 @@
|
||||
"""Dual sync: dispenser period_recipes — unlink, transfer, reorder, offline."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from tests.helpers.sync_dual_harness import SyncDualInstanceHarness
|
||||
|
||||
SCENARIO_DUAL_UNLINK_BOTH_TERMINALS = "DUAL_UNLINK_BOTH_TERMINALS"
|
||||
SCENARIO_DUAL_TRANSFER_BOTH_TERMINALS = "DUAL_TRANSFER_BOTH_TERMINALS"
|
||||
SCENARIO_DUAL_TRANSFER_THEN_REORDER = "DUAL_TRANSFER_THEN_REORDER"
|
||||
SCENARIO_DUAL_OFFLINE_CATCHUP_TRANSFER = "DUAL_OFFLINE_CATCHUP_TRANSFER"
|
||||
SCENARIO_DUAL_LATE_JOIN_AFTER_TRANSFER = "DUAL_LATE_JOIN_AFTER_TRANSFER"
|
||||
|
||||
|
||||
class SyncDualRecipesDispenserTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.harness = SyncDualInstanceHarness()
|
||||
self.harness.start()
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.harness.stop()
|
||||
|
||||
def test_unlink_reaches_both_terminals(self) -> None:
|
||||
SCENARIO_DUAL_UNLINK_BOTH_TERMINALS # noqa: F841
|
||||
disp_id, pa, _, r1, _ = self.harness.seed_dispenser_two_periods_two_recipes()
|
||||
client = self.harness.server_test_client()
|
||||
resp = client.delete(f"/api/feed_dispensers/{disp_id}/periods/{pa}/recipes/{r1}")
|
||||
self.assertEqual(resp.status_code, 200, resp.get_json())
|
||||
self.harness.drain_sync()
|
||||
|
||||
for term in ("a", "b"):
|
||||
self.assertTrue(
|
||||
self.harness.period_recipe_link_deleted(term, pa, r1),
|
||||
msg=f"terminal {term}",
|
||||
)
|
||||
recipe = self.harness.recipe_on_terminal(term, r1)
|
||||
self.assertIsNotNone(recipe)
|
||||
self.assertFalse(recipe.is_deleted)
|
||||
|
||||
def test_transfer_reaches_both_terminals(self) -> None:
|
||||
SCENARIO_DUAL_TRANSFER_BOTH_TERMINALS # noqa: F841
|
||||
disp_id, pa, pb, r1, _ = self.harness.seed_dispenser_two_periods_two_recipes()
|
||||
client = self.harness.server_test_client()
|
||||
resp = client.post(
|
||||
f"/api/feed_dispensers/{disp_id}/periods/{pb}/recipes/{r1}/transfer",
|
||||
json={
|
||||
"from_dispenser_id": disp_id,
|
||||
"from_period_id": pa,
|
||||
"to_index": 0,
|
||||
},
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200, resp.get_json())
|
||||
self.harness.drain_sync()
|
||||
|
||||
for term in ("a", "b"):
|
||||
self.assertEqual(self.harness.period_recipe_order(term, pa), ["dual-r2"])
|
||||
self.assertEqual(self.harness.period_recipe_order(term, pb), ["dual-r1"])
|
||||
self.assertTrue(self.harness.period_recipe_link_deleted(term, pa, r1))
|
||||
|
||||
def test_transfer_then_reorder_on_target_both_terminals(self) -> None:
|
||||
SCENARIO_DUAL_TRANSFER_THEN_REORDER # noqa: F841
|
||||
disp_id, pa, pb, r1, r2 = self.harness.seed_dispenser_two_periods_two_recipes()
|
||||
client = self.harness.server_test_client()
|
||||
client.post(
|
||||
f"/api/feed_dispensers/{disp_id}/periods/{pb}/recipes/{r1}/transfer",
|
||||
json={
|
||||
"from_dispenser_id": disp_id,
|
||||
"from_period_id": pa,
|
||||
"to_index": 0,
|
||||
},
|
||||
)
|
||||
client.post(
|
||||
f"/api/feed_dispensers/{disp_id}/periods/{pb}/recipes/{r2}/transfer",
|
||||
json={
|
||||
"from_dispenser_id": disp_id,
|
||||
"from_period_id": pa,
|
||||
"to_index": 1,
|
||||
},
|
||||
)
|
||||
self.harness.drain_sync()
|
||||
|
||||
move = client.put(
|
||||
f"/api/recipes/{r2}/move",
|
||||
json={"period_id": pb, "from_index": 1, "to_index": 0},
|
||||
)
|
||||
self.assertEqual(move.status_code, 200, move.get_json())
|
||||
time.sleep(0.25) # deferred reorder sync enqueue (recipes.py)
|
||||
self.harness.drain_sync()
|
||||
|
||||
for term in ("a", "b"):
|
||||
self.assertEqual(self.harness.period_recipe_order(term, pb), [r2, r1])
|
||||
|
||||
def test_offline_terminal_catches_up_after_transfer(self) -> None:
|
||||
SCENARIO_DUAL_OFFLINE_CATCHUP_TRANSFER # noqa: F841
|
||||
disp_id, pa, pb, r1, _ = self.harness.seed_dispenser_two_periods_two_recipes()
|
||||
self.harness.sync_terminal("a")
|
||||
client = self.harness.server_test_client()
|
||||
client.post(
|
||||
f"/api/feed_dispensers/{disp_id}/periods/{pb}/recipes/{r1}/transfer",
|
||||
json={
|
||||
"from_dispenser_id": disp_id,
|
||||
"from_period_id": pa,
|
||||
"to_index": 0,
|
||||
},
|
||||
)
|
||||
self.harness.sync_terminal("a")
|
||||
self.harness.drain_sync()
|
||||
|
||||
self.assertEqual(self.harness.period_recipe_order("a", pb), [r1])
|
||||
self.assertEqual(self.harness.period_recipe_order("b", pb), [r1])
|
||||
|
||||
def test_late_join_after_transfer(self) -> None:
|
||||
SCENARIO_DUAL_LATE_JOIN_AFTER_TRANSFER # noqa: F841
|
||||
disp_id, pa, pb, r1, _ = self.harness.seed_dispenser_two_periods_two_recipes()
|
||||
client = self.harness.server_test_client()
|
||||
client.post(
|
||||
f"/api/feed_dispensers/{disp_id}/periods/{pb}/recipes/{r1}/transfer",
|
||||
json={
|
||||
"from_dispenser_id": disp_id,
|
||||
"from_period_id": pa,
|
||||
"to_index": 0,
|
||||
},
|
||||
)
|
||||
self.harness.sync_terminal("a")
|
||||
self.harness.sync_terminal("a")
|
||||
|
||||
self.assertEqual(self.harness.period_recipe_order("b", pb), [])
|
||||
|
||||
self.harness.sync_terminal("b")
|
||||
self.harness.sync_terminal("b")
|
||||
self.harness.drain_sync()
|
||||
|
||||
self.assertEqual(self.harness.period_recipe_order("b", pb), [r1])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user