@@ -0,0 +1,116 @@
|
||||
"""Dual sync: offline catch-up — reorder рейсов и группы выгрузки."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
import uuid
|
||||
|
||||
from sqlalchemy import func, select
|
||||
|
||||
from app import db
|
||||
from app.models import Ingredient, Recipe, UnloadingGroup
|
||||
from app.services.recipe_update_service import update_recipe_from_payload
|
||||
from app.services.sync_manager import enqueue_sync_queue_task
|
||||
from tests.helpers.mill_recipe_fixtures import (
|
||||
create_recipe_with_children,
|
||||
group_payload_from_row,
|
||||
ingredient_payload_from_row,
|
||||
recipe_update_payload,
|
||||
)
|
||||
from tests.helpers.sync_dual_harness import SyncDualInstanceHarness
|
||||
|
||||
SCENARIO_DUAL_OFFLINE_CATCHUP_GROUPS = "DUAL_OFFLINE_CATCHUP_GROUPS"
|
||||
|
||||
|
||||
class SyncDualOfflineCatchupTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.harness = SyncDualInstanceHarness()
|
||||
self.harness.start()
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.harness.stop()
|
||||
|
||||
def test_offline_terminal_catches_reorder_and_new_group(self) -> None:
|
||||
with self.harness.server_ctx():
|
||||
recipe_id, ing_ids, grp_ids = create_recipe_with_children(with_groups=True)
|
||||
recipe = db.session.get(Recipe, recipe_id)
|
||||
for ing_id in ing_ids:
|
||||
enqueue_sync_queue_task("ingredient", ing_id, "create", priority=2)
|
||||
for gid in grp_ids:
|
||||
enqueue_sync_queue_task("unloading_group", gid, "create", priority=2)
|
||||
enqueue_sync_queue_task("recipe", recipe_id, "create", priority=2)
|
||||
db.session.commit()
|
||||
|
||||
self.harness.sync_terminal("a")
|
||||
|
||||
with self.harness.server_ctx():
|
||||
recipe = db.session.get(Recipe, recipe_id)
|
||||
assert recipe is not None
|
||||
ings = list(
|
||||
db.session.execute(
|
||||
select(Ingredient).where(
|
||||
Ingredient.recipe_id == recipe_id,
|
||||
Ingredient.is_deleted.is_(False),
|
||||
).order_by(Ingredient.order.asc())
|
||||
).scalars().all()
|
||||
)
|
||||
groups = list(
|
||||
db.session.execute(
|
||||
select(UnloadingGroup).where(
|
||||
UnloadingGroup.recipe_id == recipe_id,
|
||||
UnloadingGroup.is_deleted.is_(False),
|
||||
).order_by(UnloadingGroup.order.asc())
|
||||
).scalars().all()
|
||||
)
|
||||
swapped = [
|
||||
ingredient_payload_from_row(ings[1], order=1),
|
||||
ingredient_payload_from_row(ings[0], order=2),
|
||||
]
|
||||
new_grp = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"name": "Новая",
|
||||
"distribution_type": "percent",
|
||||
"value": 20.0,
|
||||
"weight": 0.0,
|
||||
"order": len(groups) + 1,
|
||||
}
|
||||
update_recipe_from_payload(
|
||||
recipe_id,
|
||||
recipe_update_payload(
|
||||
recipe,
|
||||
ingredients=swapped,
|
||||
groups=[group_payload_from_row(g) for g in groups] + [new_grp],
|
||||
),
|
||||
)
|
||||
db.session.commit()
|
||||
|
||||
self.harness.drain_sync()
|
||||
|
||||
for term in ("a", "b"):
|
||||
with self.harness.terminal_ctx(term):
|
||||
ing_rows = db.session.execute(
|
||||
select(Ingredient.id, Ingredient.order)
|
||||
.where(
|
||||
Ingredient.recipe_id == recipe_id,
|
||||
Ingredient.is_deleted.is_(False),
|
||||
)
|
||||
.order_by(Ingredient.order.asc())
|
||||
).all()
|
||||
self.assertEqual(
|
||||
[str(rid) for rid, _ in ing_rows],
|
||||
[ing_ids[1], ing_ids[0]],
|
||||
msg=f"reorder terminal {term}",
|
||||
)
|
||||
grp_count = db.session.scalar(
|
||||
select(func.count())
|
||||
.select_from(UnloadingGroup)
|
||||
.where(
|
||||
UnloadingGroup.recipe_id == recipe_id,
|
||||
UnloadingGroup.is_deleted.is_(False),
|
||||
)
|
||||
)
|
||||
self.assertEqual(int(grp_count or 0), 3, msg=f"groups terminal {term}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user