chore: snapshot workflow migration progress
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import uuid
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import select, text
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.domains.auth.models import User, UserRole
|
||||
from app.domains.media.models import MediaAsset, MediaAssetType
|
||||
from app.domains.orders.models import Order, OrderLine, OrderStatus
|
||||
from app.domains.products.models import CadFile, Product
|
||||
from app.domains.rendering.models import OutputType
|
||||
|
||||
from tests.db_test_utils import sync_test_session as sync_test_session_ctx
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sync_session():
|
||||
with sync_test_session_ctx() as session:
|
||||
yield session
|
||||
|
||||
|
||||
def _seed_order_line(session: Session, tmp_path: Path) -> OrderLine:
|
||||
step_path = tmp_path / "parts" / "bearing.step"
|
||||
step_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
step_path.write_text("STEP", encoding="utf-8")
|
||||
|
||||
user = User(
|
||||
id=uuid.uuid4(),
|
||||
email=f"publish-{uuid.uuid4().hex[:8]}@test.local",
|
||||
password_hash="hash",
|
||||
full_name="Publish Tester",
|
||||
role=UserRole.admin,
|
||||
is_active=True,
|
||||
)
|
||||
cad_file = CadFile(
|
||||
id=uuid.uuid4(),
|
||||
original_name="bearing.step",
|
||||
stored_path=str(step_path),
|
||||
file_hash=f"hash-{uuid.uuid4().hex}",
|
||||
)
|
||||
product = Product(
|
||||
id=uuid.uuid4(),
|
||||
pim_id="P-2000",
|
||||
name="Bearing Publish",
|
||||
category_key="bearings",
|
||||
cad_file_id=cad_file.id,
|
||||
cad_file=cad_file,
|
||||
)
|
||||
output_type = OutputType(
|
||||
id=uuid.uuid4(),
|
||||
name="HQ Still",
|
||||
renderer="blender",
|
||||
output_format="png",
|
||||
render_settings={"width": 1600, "height": 900},
|
||||
)
|
||||
order = Order(
|
||||
id=uuid.uuid4(),
|
||||
order_number=f"ORD-{uuid.uuid4().hex[:8]}",
|
||||
status=OrderStatus.processing,
|
||||
created_by=user.id,
|
||||
)
|
||||
line = OrderLine(
|
||||
id=uuid.uuid4(),
|
||||
order_id=order.id,
|
||||
product_id=product.id,
|
||||
product=product,
|
||||
output_type_id=output_type.id,
|
||||
output_type=output_type,
|
||||
render_status="processing",
|
||||
)
|
||||
|
||||
session.add_all([user, cad_file, product, output_type, order, line])
|
||||
session.commit()
|
||||
return line
|
||||
|
||||
|
||||
def test_publish_asset_canonicalizes_still_outputs(sync_session, tmp_path, monkeypatch):
|
||||
from app.config import settings
|
||||
from app.domains.rendering.tasks import publish_asset
|
||||
|
||||
upload_dir = tmp_path / "uploads"
|
||||
monkeypatch.setattr(settings, "upload_dir", str(upload_dir))
|
||||
|
||||
line = _seed_order_line(sync_session, tmp_path)
|
||||
source_output = tmp_path / "parts" / "renders" / "line.png"
|
||||
source_output.parent.mkdir(parents=True, exist_ok=True)
|
||||
source_output.write_bytes(b"png")
|
||||
|
||||
@contextmanager
|
||||
def _session_ctx():
|
||||
yield sync_session
|
||||
|
||||
monkeypatch.setattr("app.core.db_utils.get_sync_session", _session_ctx)
|
||||
|
||||
asset_id = publish_asset.run(
|
||||
str(line.id),
|
||||
"still",
|
||||
str(source_output),
|
||||
render_config={"renderer": "blender", "engine_used": "cycles"},
|
||||
)
|
||||
|
||||
sync_session.expire_all()
|
||||
stored_line = sync_session.get(OrderLine, line.id)
|
||||
stored_asset = sync_session.execute(
|
||||
select(MediaAsset).where(MediaAsset.id == uuid.UUID(asset_id))
|
||||
).scalar_one()
|
||||
|
||||
assert stored_line.result_path == f"{upload_dir}/renders/{line.id}/Bearing_Publish_HQ_Still.png"
|
||||
assert Path(stored_line.result_path).is_file()
|
||||
assert stored_asset.storage_key == f"renders/{line.id}/Bearing_Publish_HQ_Still.png"
|
||||
assert stored_asset.asset_type == MediaAssetType.still
|
||||
|
||||
|
||||
def test_publish_asset_canonicalizes_blend_storage_key_without_touching_order_line(sync_session, tmp_path, monkeypatch):
|
||||
from app.config import settings
|
||||
from app.domains.rendering.tasks import publish_asset
|
||||
|
||||
upload_dir = tmp_path / "uploads"
|
||||
monkeypatch.setattr(settings, "upload_dir", str(upload_dir))
|
||||
|
||||
line = _seed_order_line(sync_session, tmp_path)
|
||||
source_output = tmp_path / "parts" / "bearing_production.blend"
|
||||
source_output.parent.mkdir(parents=True, exist_ok=True)
|
||||
source_output.write_bytes(b"blend")
|
||||
|
||||
@contextmanager
|
||||
def _session_ctx():
|
||||
yield sync_session
|
||||
|
||||
monkeypatch.setattr("app.core.db_utils.get_sync_session", _session_ctx)
|
||||
|
||||
asset_id = publish_asset.run(
|
||||
str(line.id),
|
||||
"blend_production",
|
||||
str(source_output),
|
||||
render_config={"artifact_type": "blend_production"},
|
||||
)
|
||||
|
||||
sync_session.expire_all()
|
||||
stored_line = sync_session.get(OrderLine, line.id)
|
||||
stored_asset = sync_session.execute(
|
||||
select(MediaAsset).where(MediaAsset.id == uuid.UUID(asset_id))
|
||||
).scalar_one()
|
||||
|
||||
assert stored_line.result_path is None
|
||||
assert stored_asset.storage_key == str(source_output)
|
||||
assert stored_asset.asset_type == MediaAssetType.blend_production
|
||||
Reference in New Issue
Block a user