package diunwebhook_test import ( "bytes" "encoding/json" "errors" "net/http" "net/http/httptest" "testing" "time" diun "awesomeProject/pkg/diunwebhook" ) func TestUpdateEventAndGetUpdates(t *testing.T) { diun.UpdatesReset() // helper to reset global state event := diun.DiunEvent{ DiunVersion: "1.0", Hostname: "host", Status: "new", Provider: "docker", Image: "nginx:latest", HubLink: "https://hub.docker.com/nginx", MimeType: "application/json", Digest: "sha256:abc", Created: time.Now(), Platform: "linux/amd64", } diun.UpdateEvent(event) got := diun.GetUpdates() if len(got) != 1 { t.Fatalf("expected 1 update, got %d", len(got)) } if got["nginx:latest"].DiunVersion != "1.0" { t.Errorf("unexpected DiunVersion: %s", got["nginx:latest"].DiunVersion) } } func TestWebhookHandler(t *testing.T) { diun.UpdatesReset() // reset global state event := diun.DiunEvent{ DiunVersion: "2.0", Hostname: "host2", Status: "updated", Provider: "docker", Image: "alpine:latest", HubLink: "https://hub.docker.com/alpine", MimeType: "application/json", Digest: "sha256:def", Created: time.Now(), Platform: "linux/amd64", } body, _ := json.Marshal(event) req := httptest.NewRequest(http.MethodPost, "/webhook", bytes.NewReader(body)) rec := httptest.NewRecorder() diun.WebhookHandler(rec, req) if rec.Code != http.StatusOK { t.Errorf("expected status 200, got %d", rec.Code) } if len(diun.GetUpdatesMap()) != 1 { t.Errorf("expected 1 update, got %d", len(diun.GetUpdatesMap())) } } func TestWebhookHandler_BadRequest(t *testing.T) { req := httptest.NewRequest(http.MethodPost, "/webhook", bytes.NewReader([]byte("not-json"))) rec := httptest.NewRecorder() diun.WebhookHandler(rec, req) if rec.Code != http.StatusBadRequest { t.Errorf("expected 400 for bad JSON, got %d", rec.Code) } } func TestUpdatesHandler(t *testing.T) { diun.UpdatesReset() // reset global state event := diun.DiunEvent{Image: "busybox:latest"} diun.UpdateEvent(event) req := httptest.NewRequest(http.MethodGet, "/api/updates", nil) rec := httptest.NewRecorder() diun.UpdatesHandler(rec, req) if rec.Code != http.StatusOK { t.Errorf("expected status 200, got %d", rec.Code) } var got map[string]diun.DiunEvent if err := json.NewDecoder(rec.Body).Decode(&got); err != nil { t.Fatalf("failed to decode response: %v", err) } if _, ok := got["busybox:latest"]; !ok { t.Errorf("expected busybox:latest in updates") } } // Helper for simulating a broken ResponseWriter // Used in TestUpdatesHandler_EncodeError type failWriter struct{ http.ResponseWriter } func (f failWriter) Header() http.Header { return http.Header{} } func (f failWriter) Write([]byte) (int, error) { return 0, errors.New("forced error") } func (f failWriter) WriteHeader(_ int) {} func TestUpdatesHandler_EncodeError(t *testing.T) { rec := failWriter{httptest.NewRecorder()} diun.UpdatesHandler(rec, httptest.NewRequest(http.MethodGet, "/api/updates", nil)) // No panic = pass } func TestMainHandlerIntegration(t *testing.T) { diun.UpdatesReset() // reset global state // Start test server ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/webhook" { diun.WebhookHandler(w, r) } else if r.URL.Path == "/api/updates" { diun.UpdatesHandler(w, r) } else { w.WriteHeader(http.StatusNotFound) } })) defer ts.Close() // Post event event := diun.DiunEvent{Image: "integration:latest"} body, _ := json.Marshal(event) resp, err := http.Post(ts.URL+"/webhook", "application/json", bytes.NewReader(body)) if err != nil { t.Fatalf("webhook POST failed: %v", err) } if resp.StatusCode != http.StatusOK { t.Fatalf("webhook POST returned status: %d", resp.StatusCode) } if cerr := resp.Body.Close(); cerr != nil { t.Errorf("failed to close response body: %v", cerr) } // Get updates resp, err = http.Get(ts.URL + "/api/updates") if err != nil { t.Fatalf("GET /api/updates failed: %v", err) } defer func() { if cerr := resp.Body.Close(); cerr != nil { t.Errorf("failed to close response body: %v", cerr) } }() var got map[string]diun.DiunEvent if err := json.NewDecoder(resp.Body).Decode(&got); err != nil { t.Fatalf("decode failed: %v", err) } if _, ok := got["integration:latest"]; !ok { t.Errorf("expected integration:latest in updates") } }