diff --git a/pkg/diunwebhook/diunwebhook_test.go b/pkg/diunwebhook/diunwebhook_test.go index ba635cc..54e220e 100644 --- a/pkg/diunwebhook/diunwebhook_test.go +++ b/pkg/diunwebhook/diunwebhook_test.go @@ -612,3 +612,56 @@ func TestGetUpdates_IncludesTag(t *testing.T) { t.Errorf("expected tag id %d, got %d", id, entry.Tag.ID) } } + +func TestUpdateEvent_PreservesTagOnUpsert(t *testing.T) { + diun.UpdatesReset() + + // Insert image + if err := diun.UpdateEvent(diun.DiunEvent{Image: "nginx:latest", Status: "new"}); err != nil { + t.Fatalf("first UpdateEvent failed: %v", err) + } + + // Assign tag + tagID := postTagAndGetID(t, "webservers") + body, _ := json.Marshal(map[string]interface{}{"image": "nginx:latest", "tag_id": tagID}) + req := httptest.NewRequest(http.MethodPut, "/api/tag-assignments", bytes.NewReader(body)) + rec := httptest.NewRecorder() + diun.TagAssignmentHandler(rec, req) + if rec.Code != http.StatusNoContent { + t.Fatalf("tag assignment failed: got %d", rec.Code) + } + + // Dismiss (acknowledge) the image — second event must reset this + req = httptest.NewRequest(http.MethodPatch, "/api/updates/nginx:latest", nil) + rec = httptest.NewRecorder() + diun.DismissHandler(rec, req) + if rec.Code != http.StatusNoContent { + t.Fatalf("dismiss failed: got %d", rec.Code) + } + + // Receive a second event for the same image + if err := diun.UpdateEvent(diun.DiunEvent{Image: "nginx:latest", Status: "update"}); err != nil { + t.Fatalf("second UpdateEvent failed: %v", err) + } + + // Tag must survive the second event + m := diun.GetUpdatesMap() + entry, ok := m["nginx:latest"] + if !ok { + t.Fatal("nginx:latest missing from updates after second event") + } + if entry.Tag == nil { + t.Error("tag was lost after second UpdateEvent — UPSERT bug not fixed") + } + if entry.Tag != nil && entry.Tag.ID != tagID { + t.Errorf("tag ID changed: expected %d, got %d", tagID, entry.Tag.ID) + } + // Acknowledged state must be reset by the new event + if entry.Acknowledged { + t.Error("acknowledged state must be reset by new event") + } + // Status must reflect the new event + if entry.Event.Status != "update" { + t.Errorf("expected status 'update', got %q", entry.Event.Status) + } +}