feat(product-suite): add original image batch management
This commit is contained in:
@@ -335,6 +335,139 @@ class ImageStudioTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_remove_original_assets_is_atomic_and_reorders_remaining_assets(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
db_path = os.path.join(temp_dir, "cmshopee.db")
|
||||
db.init_db(db_path)
|
||||
project = image_studio.create_or_get_project(
|
||||
account_alias="alias",
|
||||
account_slug="alias_slug",
|
||||
item_id="51100639510",
|
||||
path=db_path,
|
||||
)
|
||||
local_paths = []
|
||||
assets = []
|
||||
for index in range(1, 5):
|
||||
local_path = os.path.join(temp_dir, "original-%d.png" % index)
|
||||
with open(local_path, "wb") as fh:
|
||||
fh.write(b"image-%d" % index)
|
||||
local_paths.append(local_path)
|
||||
assets.append(
|
||||
image_studio.add_asset(
|
||||
project.id,
|
||||
image_studio.ASSET_KIND_ORIGINAL,
|
||||
local_path=local_path,
|
||||
source_order=index * 10,
|
||||
path=db_path,
|
||||
)
|
||||
)
|
||||
|
||||
removed = image_studio.remove_original_assets_if_unused(
|
||||
project.id,
|
||||
[assets[0].id, assets[2].id, assets[0].id],
|
||||
path=db_path,
|
||||
)
|
||||
|
||||
self.assertEqual([assets[0].id, assets[2].id], [asset.id for asset in removed])
|
||||
remaining = image_studio.list_assets(
|
||||
project.id,
|
||||
kind=image_studio.ASSET_KIND_ORIGINAL,
|
||||
path=db_path,
|
||||
)
|
||||
self.assertEqual([assets[1].id, assets[3].id], [asset.id for asset in remaining])
|
||||
self.assertEqual([1, 2], [asset.source_order for asset in remaining])
|
||||
self.assertTrue(all(os.path.isfile(path) for path in local_paths))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_remove_original_assets_rejects_invalid_or_referenced_batch_without_partial_delete(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
db_path = os.path.join(temp_dir, "cmshopee.db")
|
||||
db.init_db(db_path)
|
||||
project = image_studio.create_or_get_project(
|
||||
account_alias="alias",
|
||||
account_slug="alias_slug",
|
||||
item_id="51100639510",
|
||||
path=db_path,
|
||||
)
|
||||
other_project = image_studio.create_or_get_project(
|
||||
account_alias="alias",
|
||||
account_slug="alias_slug",
|
||||
item_id="51100639511",
|
||||
path=db_path,
|
||||
)
|
||||
free_asset = image_studio.add_asset(
|
||||
project.id,
|
||||
image_studio.ASSET_KIND_ORIGINAL,
|
||||
source_order=1,
|
||||
path=db_path,
|
||||
)
|
||||
referenced_asset = image_studio.add_asset(
|
||||
project.id,
|
||||
image_studio.ASSET_KIND_ORIGINAL,
|
||||
source_order=2,
|
||||
path=db_path,
|
||||
)
|
||||
selected_asset = image_studio.add_asset(
|
||||
project.id,
|
||||
image_studio.ASSET_KIND_ORIGINAL,
|
||||
source_order=3,
|
||||
path=db_path,
|
||||
)
|
||||
generated_asset = image_studio.add_asset(
|
||||
project.id,
|
||||
"generated",
|
||||
path=db_path,
|
||||
)
|
||||
foreign_asset = image_studio.add_asset(
|
||||
other_project.id,
|
||||
image_studio.ASSET_KIND_ORIGINAL,
|
||||
path=db_path,
|
||||
)
|
||||
image_studio.create_job(
|
||||
project.id,
|
||||
source_asset_id=referenced_asset.id,
|
||||
path=db_path,
|
||||
)
|
||||
image_studio.replace_selections(
|
||||
project.id,
|
||||
"main",
|
||||
[selected_asset.id],
|
||||
path=db_path,
|
||||
)
|
||||
|
||||
with self.assertRaisesRegex(db.DbError, "引用"):
|
||||
image_studio.remove_original_assets_if_unused(
|
||||
project.id,
|
||||
[free_asset.id, referenced_asset.id],
|
||||
path=db_path,
|
||||
)
|
||||
self.assertIsNotNone(image_studio.get_asset(free_asset.id, path=db_path))
|
||||
self.assertIsNotNone(image_studio.get_asset(referenced_asset.id, path=db_path))
|
||||
|
||||
with self.assertRaisesRegex(db.DbError, "引用"):
|
||||
image_studio.remove_original_assets_if_unused(
|
||||
project.id,
|
||||
[free_asset.id, selected_asset.id],
|
||||
path=db_path,
|
||||
)
|
||||
self.assertIsNotNone(image_studio.get_asset(free_asset.id, path=db_path))
|
||||
self.assertIsNotNone(image_studio.get_asset(selected_asset.id, path=db_path))
|
||||
|
||||
for invalid_id in (generated_asset.id, foreign_asset.id, 999999):
|
||||
with self.assertRaisesRegex(db.DbError, "不属于当前项目"):
|
||||
image_studio.remove_original_assets_if_unused(
|
||||
project.id,
|
||||
[free_asset.id, invalid_id],
|
||||
path=db_path,
|
||||
)
|
||||
self.assertIsNotNone(image_studio.get_asset(free_asset.id, path=db_path))
|
||||
|
||||
with self.assertRaisesRegex(db.DbError, "请选择"):
|
||||
image_studio.remove_original_assets_if_unused(project.id, [], path=db_path)
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_sync_original_asset_urls_is_idempotent_and_marks_missing(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
db_path = os.path.join(temp_dir, "cmshopee.db")
|
||||
|
||||
Reference in New Issue
Block a user