Ctrl K
ComunidadGuías…

internal/api/server_devin_oauth_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package api

import (
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"strings"
	"testing"

	management "github.com/router-for-me/CLIProxyAPI/v8/internal/api/handlers/management"
)

func TestDevinOAuthRoutes(t *testing.T) {
	t.Setenv("MANAGEMENT_PASSWORD", "test-management-key")
	server := newTestServer(t)

	w := httptest.NewRecorder()
	server.engine.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/v0/management/devin-auth-url", nil))
	if w.Code != http.StatusUnauthorized {
		t.Fatalf("unprotected login route: %d", w.Code)
	}
	registered := false
	for _, route := range server.engine.Routes() {
		if route.Method == http.MethodGet && route.Path == "/v0/management/devin-auth-url" {
			registered = true
		}
	}
	if !registered {
		t.Fatal("Devin login route not registered")
	}

	for _, test := range []struct {
		name, provider, query, callbackPath string
		want                                int
	}{
		{name: "success", provider: "devin", query: "code=test-code", callbackPath: "/callback", want: http.StatusOK},
		{name: "success legacy path", provider: "devin", query: "code=test-code", callbackPath: "/devin/callback", want: http.StatusOK},
		{name: "denied", provider: "devin", query: "error=access_denied", callbackPath: "/callback", want: http.StatusOK},
		{name: "wrong provider", provider: "codex", query: "code=test-code", callbackPath: "/callback", want: http.StatusBadRequest},
		{name: "missing code", provider: "devin", callbackPath: "/callback", want: http.StatusBadRequest},
		{name: "unknown state", query: "code=test-code", callbackPath: "/callback", want: http.StatusBadRequest},
	} {
		t.Run(test.name, func(t *testing.T) {
			state := "devin-route-" + strings.ReplaceAll(test.name, " ", "-")
			if test.provider != "" {
				management.RegisterOAuthSession(state, test.provider)
				defer management.CompleteOAuthSession(state)
			}
			w := httptest.NewRecorder()
			path := test.callbackPath
			if path == "" {
				path = "/callback"
			}
			server.engine.ServeHTTP(w, httptest.NewRequest(http.MethodGet, path+"?state="+state+"&"+test.query, nil))
			if w.Code != test.want {
				t.Fatalf("callback: %d %s", w.Code, w.Body.String())
			}
			filePath := filepath.Join(server.cfg.AuthDir, ".oauth-devin-"+state+".oauth")
			data, errRead := os.ReadFile(filePath)
			if test.want == http.StatusOK {
				if errRead != nil {
					t.Fatal(errRead)
				}
				var payload map[string]string
				if errDecode := json.Unmarshal(data, &payload); errDecode != nil {
					t.Fatal(errDecode)
				}
				if payload["state"] != state || (payload["code"] == "" && payload["error"] == "") {
					t.Fatalf("callback payload: %v", payload)
				}
				if w.Header().Get("Cache-Control") != "no-store" {
					t.Fatal("callback response is cacheable")
				}
			} else if !os.IsNotExist(errRead) {
				t.Fatalf("invalid callback persisted: %v", errRead)
			}
		})
	}
}