/
nekstep
/
gvcli
Обзор
Документация
Войти
/
nekstep
/
gvcli
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
internal/api/client_test.go
378 строк
10 KB
kst
feat: implement PR management (view, files, comments, diff, merge --check, list filters)
26 июл 2026, 19:43
26 июл 2026, 19:43
35a5ed9
Код
Авторство
О чём код?
package api import ( "encoding/json" "fmt" "net/http" "net/http/httptest" "strings" "testing" "gitverse-cli/internal/auth" "gitverse-cli/internal/config" "gitverse-cli/internal/debug" generated_api "gitverse-cli/internal/generated-api" ) func setupTestClient(handler http.Handler) *Client { server := httptest.NewServer(handler) cfg := &config.Config{} openapiClient, _ := generated_api.NewClientWithResponses(server.URL) return &Client{ config: cfg, auth: &auth.Service{}, debug: debug.NewLogger(false, false, false), openapiClient: openapiClient, } } func writeJSON(w http.ResponseWriter, status int, v interface{}) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) json.NewEncoder(w).Encode(v) } func TestGetUserByUsername_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, map[string]interface{}{ "id": 1.0, "login": "testuser", "name": "Test User", }) })) res, err := cl.GetUserByUsername("testuser") if err != nil { t.Fatalf("unexpected error: %v", err) } if res["login"] != "testuser" { t.Errorf("expected login 'testuser', got %v", res["login"]) } } func TestGetUserByUsername_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })) _, err := cl.GetUserByUsername("noone") if err == nil { t.Fatal("expected error, got nil") } } func TestGetUserByUsername_EmptyJSON(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) w.Write([]byte("")) })) _, err := cl.GetUserByUsername("testuser") if err == nil { t.Fatal("expected error for empty JSON, got nil") } } func TestListBranches_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, []map[string]interface{}{ {"name": "main", "protected": false}, {"name": "dev", "protected": true}, }) })) res, err := cl.ListBranches("owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(res) != 2 { t.Errorf("expected 2 branches, got %d", len(res)) } } func TestListBranches_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) _, err := cl.ListBranches("owner", "repo") if err == nil { t.Fatal("expected error, got nil") } } func TestStarRepo_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) })) err := cl.StarRepo("owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } } func TestStarRepo_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(403) })) err := cl.StarRepo("owner", "repo") if err == nil { t.Fatal("expected error, got nil") } } func TestForkRepo_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, map[string]interface{}{ "id": 2.0, "name": "repo", "fork": true, }) })) res, err := cl.ForkRepo("owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } if res["fork"] != true { t.Errorf("expected fork=true, got %v", res["fork"]) } } func TestForkRepo_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(409) })) _, err := cl.ForkRepo("owner", "repo") if err == nil { t.Fatal("expected error, got nil") } } func TestGetLanguages_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, map[string]int{"Go": 5000, "Python": 200}) })) res, err := cl.GetLanguages("owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } if res == nil { t.Fatal("expected non-nil result") } } func TestGetPullRequest_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, map[string]interface{}{ "number": 42.0, "title": "Fix bug", "state": "open", "body": "Description", "user": map[string]interface{}{"login": "alice"}, "head": map[string]interface{}{"ref": "feature", "sha": "abc123"}, "base": map[string]interface{}{"ref": "main", "sha": "def456"}, }) })) res, err := cl.GetPullRequest("owner", "repo", 42) if err != nil { t.Fatalf("unexpected error: %v", err) } if res["title"] != "Fix bug" { t.Errorf("expected title 'Fix bug', got %v", res["title"]) } if user, ok := res["user"].(map[string]interface{}); ok { if user["login"] != "alice" { t.Errorf("expected user login 'alice', got %v", user["login"]) } } else { t.Error("expected user object in response") } } func TestGetPullRequest_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })) _, err := cl.GetPullRequest("owner", "repo", 999) if err == nil { t.Fatal("expected error, got nil") } } func TestListPullRequestFiles_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, []map[string]interface{}{ {"filename": "main.go", "status": "modified", "additions": 10.0, "deletions": 2.0}, {"filename": "README.md", "status": "added", "additions": 5.0, "deletions": 0.0}, }) })) res, err := cl.ListPullRequestFiles("owner", "repo", 42) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(res) != 2 { t.Errorf("expected 2 files, got %d", len(res)) } } func TestListPullRequestFiles_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) _, err := cl.ListPullRequestFiles("owner", "repo", 42) if err == nil { t.Fatal("expected error, got nil") } } func TestListIssueComments_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, []map[string]interface{}{ {"id": 1.0, "body": "Looks good", "user": map[string]interface{}{"login": "bob"}}, {"id": 2.0, "body": "Needs work", "user": map[string]interface{}{"login": "carol"}}, }) })) res, err := cl.ListIssueComments("owner", "repo", 42) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(res) != 2 { t.Errorf("expected 2 comments, got %d", len(res)) } } func TestListIssueComments_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(403) })) _, err := cl.ListIssueComments("owner", "repo", 42) if err == nil { t.Fatal("expected error, got nil") } } func TestCompareCommits_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, map[string]interface{}{ "status": "ahead", "ahead_by": 3.0, "behind_by": 0.0, "total_commits": 3.0, }) })) res, err := cl.CompareCommits("owner", "repo", "main...feature") if err != nil { t.Fatalf("unexpected error: %v", err) } if res["status"] != "ahead" { t.Errorf("expected status 'ahead', got %v", res["status"]) } } func TestCompareCommits_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) })) _, err := cl.CompareCommits("owner", "repo", "main...feature") if err == nil { t.Fatal("expected error, got nil") } } func TestGetMergeStatus_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, map[string]interface{}{ "merged": false, "mergeable": true, "message": "PR can be merged", }) })) res, err := cl.GetMergeStatus("owner", "repo", 42) if err != nil { t.Fatalf("unexpected error: %v", err) } if res["merged"] != false { t.Errorf("expected merged=false, got %v", res["merged"]) } } func TestGetMergeStatus_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(409) })) _, err := cl.GetMergeStatus("owner", "repo", 42) if err == nil { t.Fatal("expected error, got nil") } } func TestListPulls_Success(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { writeJSON(w, 200, []map[string]interface{}{ {"number": 1.0, "title": "PR 1", "state": "open"}, {"number": 2.0, "title": "PR 2", "state": "closed"}, }) })) res, err := cl.ListPulls("owner", "repo") if err != nil { t.Fatalf("unexpected error: %v", err) } if len(res) != 2 { t.Errorf("expected 2 PRs, got %d", len(res)) } } func TestListPulls_Error(t *testing.T) { cl := setupTestClient(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) })) _, err := cl.ListPulls("owner", "repo") if err == nil { t.Fatal("expected error, got nil") } } func TestAuthTransport_TokenMessageSuggestsGvLogin(t *testing.T) { transport := &authTransport{ base: http.DefaultTransport, auth: auth.NewService(&mockKeyringNotFound{}, &config.Config{}), debug: debug.NewLogger(false, false, false), cfg: &config.Config{}, } req, _ := http.NewRequest("GET", "http://localhost/test", nil) _, err := transport.RoundTrip(req) if err == nil { t.Fatal("expected error for missing token, got nil") } if !strings.Contains(err.Error(), "gv login") { t.Errorf("expected error message to contain 'gv login', got: %s", err.Error()) } } type mockKeyringNotFound struct{} func (m *mockKeyringNotFound) Set(service, user, password string) error { return nil } func (m *mockKeyringNotFound) Get(service, user string) (string, error) { return "", fmt.Errorf("not found") } func (m *mockKeyringNotFound) Delete(service, user string) error { return nil }