feat: preview image task inputs in admin
This commit is contained in:
+107
-1
@@ -14,9 +14,10 @@ from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.core.cache import cache
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase, override_settings
|
||||
from django.urls import path
|
||||
from django.urls import path, reverse
|
||||
from django.utils import timezone
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.test import APIClient
|
||||
@@ -696,6 +697,111 @@ class ClientLatestReleaseApiTests(TestCase):
|
||||
self.assertIn("size_bytes", download_fields)
|
||||
|
||||
|
||||
class ImageGenerationTaskAdminTests(TestCase):
|
||||
def setUp(self):
|
||||
self.media_dir = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.media_dir.cleanup)
|
||||
self.media_override = override_settings(MEDIA_ROOT=self.media_dir.name)
|
||||
self.media_override.enable()
|
||||
self.addCleanup(self.media_override.disable)
|
||||
|
||||
suffix = uuid.uuid4().hex[:8]
|
||||
user_model = get_user_model()
|
||||
self.admin_user = user_model.objects.create_superuser(
|
||||
username=f"image-task-admin-{suffix}",
|
||||
email=f"image-task-admin-{suffix}@example.com",
|
||||
password="test-password",
|
||||
)
|
||||
self.user = user_model.objects.create_user(
|
||||
username=f"image-task-user-{suffix}",
|
||||
email=f"image-task-user-{suffix}@example.com",
|
||||
password="test-password",
|
||||
)
|
||||
self.api_key, _raw_key = ApiKey.create_for_user(self.user, name="image-task-admin-test")
|
||||
self.client.force_login(self.admin_user)
|
||||
|
||||
def create_task(self, *, status=ImageGenerationTask.Status.SUCCEEDED, result_url=""):
|
||||
call_record = CallRecord.objects.create(
|
||||
user=self.user,
|
||||
api_key=self.api_key,
|
||||
operation_type=CallRecord.OperationType.IMAGE,
|
||||
alias="image-standard",
|
||||
model_used="test-image-model",
|
||||
resolution="1K",
|
||||
prompt="生成商品主图",
|
||||
points_cost=10,
|
||||
status=CallRecord.Status.SUCCESS,
|
||||
)
|
||||
return ImageGenerationTask.objects.create(
|
||||
user=self.user,
|
||||
api_key=self.api_key,
|
||||
call_record=call_record,
|
||||
status=status,
|
||||
request_hash=uuid.uuid4().hex + uuid.uuid4().hex,
|
||||
result_url=result_url,
|
||||
points_balance_after_charge=90,
|
||||
)
|
||||
|
||||
def change_url(self, task):
|
||||
return reverse("admin:api_imagegenerationtask_change", args=(task.pk,))
|
||||
|
||||
def add_input_image(self, task, *, ordinal, filename):
|
||||
task_input = ImageGenerationTaskInput(
|
||||
task=task,
|
||||
ordinal=ordinal,
|
||||
mime_type="image/png",
|
||||
filename=filename,
|
||||
)
|
||||
task_input.image.save(filename, ContentFile(b"test-image"), save=True)
|
||||
return task_input
|
||||
|
||||
def test_change_view_shows_ordered_input_and_result_thumbnails_with_modal_preview(self):
|
||||
task = self.create_task(result_url="https://images.example.test/generated.png")
|
||||
main = self.add_input_image(task, ordinal=0, filename="main.png")
|
||||
reference = self.add_input_image(task, ordinal=1, filename="reference.png")
|
||||
|
||||
response = self.client.get(self.change_url(task))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "图片预览")
|
||||
self.assertContains(response, "主图")
|
||||
self.assertContains(response, "参考图 1")
|
||||
self.assertContains(response, "生成结果")
|
||||
self.assertContains(response, main.image.url)
|
||||
self.assertContains(response, reference.image.url)
|
||||
self.assertContains(response, task.result_url)
|
||||
self.assertContains(response, "data-image-preview-dialog")
|
||||
self.assertContains(response, "image-task-gallery.js")
|
||||
self.assertContains(response, "双击查看大图")
|
||||
|
||||
def test_change_view_uses_legacy_single_input_image_as_main_image(self):
|
||||
task = self.create_task()
|
||||
task.input_image.save("legacy-main.png", ContentFile(b"legacy-image"), save=True)
|
||||
|
||||
response = self.client.get(self.change_url(task))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "主图")
|
||||
self.assertContains(response, task.input_image.url)
|
||||
self.assertNotContains(response, "参考图 1")
|
||||
|
||||
def test_change_view_handles_task_without_images_or_result(self):
|
||||
task = self.create_task(status=ImageGenerationTask.Status.QUEUED)
|
||||
|
||||
response = self.client.get(self.change_url(task))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotContains(response, 'id="image-task-gallery-title"')
|
||||
|
||||
def test_change_view_requires_staff_access(self):
|
||||
task = self.create_task()
|
||||
self.client.force_login(self.user)
|
||||
|
||||
response = self.client.get(self.change_url(task))
|
||||
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
|
||||
@override_settings(
|
||||
PAYMENT_CALLBACK_MODE="mock",
|
||||
PAYMENT_MOCK_CALLBACK_SECRET="test-payment-callback-secret",
|
||||
|
||||
Reference in New Issue
Block a user