package handlers import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "time" "ai-media-hub/backend/services" "github.com/gin-gonic/gin" ) func TestSearchGiphyEndpointReturnsExpandedQueriesAndItems(t *testing.T) { gin.SetMode(gin.TestMode) mux := http.NewServeMux() mux.HandleFunc("/generate", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"candidates":[{"content":{"parts":[{"text":"{\"queries\":[\"happy dog\",\"happy dog gif\",\"dog reaction\",\"dog meme gif\",\"animated dog sticker\"]}"}]}}]}`)) }) mux.HandleFunc("/v1/gifs/search", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"data":[{"id":"dog-1","title":"Happy Dog","slug":"happy-dog","rating":"g","url":"https://giphy.com/gifs/dog-1","images":{"original":{"url":"https://media.giphy.com/media/dog-1/giphy.gif","width":"480","height":"270"},"fixed_width":{"url":"https://media.giphy.com/media/dog-1/200w.gif","width":"200","height":"113"},"fixed_width_still":{"url":"https://media.giphy.com/media/dog-1/200w_s.gif"}}}]}`)) }) server := httptest.NewServer(mux) defer server.Close() gemini := services.NewGeminiService("dummy-key", "gemini-2.5-flash") gemini.Client = &http.Client{Timeout: 2 * time.Second} gemini.GenerateEndpoint = server.URL + "/generate" giphy := services.NewGiphyService(services.GiphyConfig{ Enabled: true, APIKey: "test-key", MaxResults: 100, BaseURL: server.URL, }, gemini) giphy.Client = &http.Client{Timeout: 2 * time.Second} app := &App{GiphyService: giphy, Hub: NewHub()} router := gin.New() RegisterRoutes(router, app) body := bytes.NewBufferString(`{"query":"행복한 강아지","maxResults":100}`) req := httptest.NewRequest(http.MethodPost, "/api/giphy/search", body) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String()) } var payload struct { ExpandedQueries []string `json:"expandedQueries"` Items []services.GiphyResult `json:"items"` } if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil { t.Fatalf("failed to decode response: %v", err) } if len(payload.ExpandedQueries) != 5 || len(payload.Items) == 0 { t.Fatalf("unexpected payload: %#v", payload) } } func TestDownloadGiphyEndpointRejectsNonGiphyHost(t *testing.T) { gin.SetMode(gin.TestMode) app := &App{ GiphyService: services.NewGiphyService(services.GiphyConfig{ Enabled: true, APIKey: "test-key", DownloadDir: t.TempDir(), }, nil), Hub: NewHub(), } router := gin.New() RegisterRoutes(router, app) body := bytes.NewBufferString(`{"providerId":"x","title":"bad","downloadUrl":"https://example.com/file.gif"}`) req := httptest.NewRequest(http.MethodPost, "/api/giphy/download", body) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) if rec.Code != http.StatusBadRequest { t.Fatalf("expected 400, got %d: %s", rec.Code, rec.Body.String()) } if !strings.Contains(rec.Body.String(), "INVALID_DOWNLOAD_URL") { t.Fatalf("expected invalid host error, got %s", rec.Body.String()) } }