fix(photos): убрать мигание предпросмотра и задержку сброса правок
- фото и photo.updated несут edit_pending: рендер сохранённых правок ещё идёт - клиент держит предпросмотр, пока серверная версия не загружена и не декодирована, поэтому оригинал не мелькает при подмене - сброс возвратом контролов в значения по умолчанию виден сразу, не через 10 с - Viewer берёт URL из актуального объекта (SSE), fresh остаётся фолбэком - попутно исправлен порядок чтения tags и album_title в ListTrash
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"galo/internal/albums"
|
||||
"galo/internal/photos"
|
||||
)
|
||||
|
||||
// TestEditPendingLifecycle covers the render-state flag clients use to decide
|
||||
// whether the edit_* URLs can be shown: saving edits reports a pending render,
|
||||
// the worker clears it and publishes the fresh URLs, a second edit keeps the
|
||||
// previous render (still pending), and a reset clears both the flag and the
|
||||
// edited version.
|
||||
func TestEditPendingLifecycle(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
st, closeDB := openStack(t, filepath.Join(t.TempDir(), "galo.db"), t.TempDir())
|
||||
defer closeDB()
|
||||
|
||||
user, _, err := st.auth.Register(ctx, "editpending@test.local", "", "password123", "E")
|
||||
if err != nil {
|
||||
t.Fatalf("register: %v", err)
|
||||
}
|
||||
album, err := st.albums.Create(ctx, user.ID, albums.CreateInput{Title: "Pending"})
|
||||
if err != nil {
|
||||
t.Fatalf("create album: %v", err)
|
||||
}
|
||||
p, err := st.photos.Upload(ctx, photos.UploadInput{
|
||||
AlbumID: album.ID, UserID: user.ID, Filename: "p.png", Data: makePNG(t),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("upload: %v", err)
|
||||
}
|
||||
|
||||
w := photos.NewWorker(st.photos, time.Second, 10, time.Minute, 2)
|
||||
w.ProcessOnce(ctx)
|
||||
|
||||
first, err := st.photos.EditPhoto(ctx, p.ID, user.ID, photos.EditParams{
|
||||
Light: photos.LightParams{Exposure: 0.5},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("edit: %v", err)
|
||||
}
|
||||
if !first.EditPending {
|
||||
t.Fatalf("edit response does not report a pending render: %+v", first)
|
||||
}
|
||||
if first.EditPreviewURL != "" {
|
||||
t.Fatalf("first render already exposes edit_preview_url: %q", first.EditPreviewURL)
|
||||
}
|
||||
|
||||
w.ProcessOnce(ctx)
|
||||
rendered, err := st.photos.Get(ctx, p.ID, user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get rendered photo: %v", err)
|
||||
}
|
||||
if rendered.EditPending {
|
||||
t.Fatalf("rendered photo still reports edit_pending: %+v", rendered)
|
||||
}
|
||||
if rendered.EditPreviewURL == "" {
|
||||
t.Fatalf("rendered photo has no edit_preview_url: %+v", rendered)
|
||||
}
|
||||
firstPreview := rendered.EditPreviewURL
|
||||
|
||||
// A second edit is queued while the previous render is still bound: the
|
||||
// photo stays pending and the old URLs must not be treated as current.
|
||||
second, err := st.photos.EditPhoto(ctx, p.ID, user.ID, photos.EditParams{
|
||||
Light: photos.LightParams{Exposure: 1.25},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("second edit: %v", err)
|
||||
}
|
||||
if !second.EditPending {
|
||||
t.Fatalf("second edit does not report a pending render: %+v", second)
|
||||
}
|
||||
if second.EditPreviewURL != firstPreview {
|
||||
t.Fatalf("second edit should keep the previous render while pending: %q want %q",
|
||||
second.EditPreviewURL, firstPreview)
|
||||
}
|
||||
|
||||
w.ProcessOnce(ctx)
|
||||
after, err := st.photos.Get(ctx, p.ID, user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get after second render: %v", err)
|
||||
}
|
||||
if after.EditPending {
|
||||
t.Fatalf("second render still reports edit_pending: %+v", after)
|
||||
}
|
||||
if after.EditPreviewURL == "" || after.EditPreviewURL == firstPreview {
|
||||
t.Fatalf("second render preview url = %q, want a fresh one (old %q)",
|
||||
after.EditPreviewURL, firstPreview)
|
||||
}
|
||||
|
||||
reset, err := st.photos.ResetEdit(ctx, p.ID, user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("reset: %v", err)
|
||||
}
|
||||
if reset.EditPending {
|
||||
t.Fatalf("reset photo reports edit_pending: %+v", reset)
|
||||
}
|
||||
if reset.EditPreviewURL != "" || reset.EditURL != "" {
|
||||
t.Fatalf("reset photo still exposes edit urls: %+v", reset)
|
||||
}
|
||||
if reset.EditParams != nil && len(reset.EditParams) > 0 {
|
||||
t.Fatalf("reset photo still exposes edit params: %+v", reset.EditParams)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user