package github import ( "context" "net/http" "net/http/httptest" "testing" ) func setupTestServer(t *testing.T, handler http.HandlerFunc) (*httptest.Server, *Client) { t.Helper() // Create a test server server := httptest.NewServer(handler) // Create a client with the test server URL client := &Client{ baseURL: server.URL, httpClient: server.Client(), token: "test-token", } return server, client } func TestNewClient(t *testing.T) { // We can't easily test the config path without modifying global state, // so we'll just test that it doesn't fail with a valid config // This would require setting up the config package first } func TestIsGitHubURL(t *testing.T) { tests := []struct { name string url string want bool }{ { name: "GitHub HTTPS URL", url: "https://github.com/user/repo.git", want: true, }, { name: "GitHub SSH URL", url: "git@github.com:user/repo.git", want: true, }, { name: "Non-GitHub HTTPS URL", url: "https://example.com/user/repo.git", want: false, }, { name: "Non-GitHub SSH URL", url: "git@example.com:user/repo.git", want: false, }, { name: "Invalid URL", url: "not-a-url", want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsGitHubURL(tt.url); got != tt.want { t.Errorf("IsGitHubURL(%q) = %v, want %v", tt.url, got, tt.want) } }) } } func TestParseGitHubURL(t *testing.T) { tests := []struct { name string url string owner string repo string wantErr bool }{ { name: "GitHub HTTPS URL", url: "https://github.com/user/repo.git", owner: "user", repo: "repo", }, { name: "GitHub HTTPS URL without .git", url: "https://github.com/user/repo", owner: "user", repo: "repo", }, { name: "GitHub SSH URL", url: "git@github.com:user/repo.git", owner: "user", repo: "repo", }, { name: "Invalid URL", url: "not-a-url", wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { owner, repo, err := ParseGitHubURL(tt.url) if (err != nil) != tt.wantErr { t.Errorf("ParseGitHubURL(%q) error = %v, wantErr %v", tt.url, err, tt.wantErr) return } if !tt.wantErr { if owner != tt.owner { t.Errorf("ParseGitHubURL(%q) owner = %v, want %v", tt.url, owner, tt.owner) } if repo != tt.repo { t.Errorf("ParseGitHubURL(%q) repo = %v, want %v", tt.url, repo, tt.repo) } } }) } } func TestCreatePullRequest(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodPost { t.Errorf("Expected POST request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/pulls" { t.Errorf("Expected path to be '/repos/owner/repo/pulls', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) w.Write([]byte(`{ "id": 1, "number": 123, "state": "open", "title": "Test PR", "body": "Test PR body", "html_url": "https://github.com/owner/repo/pull/123", "user": { "login": "testuser", "id": 1 }, "head": { "label": "owner:feature", "ref": "feature", "sha": "abc123" }, "base": { "label": "owner:main", "ref": "main", "sha": "def456" } }`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Create a pull request pr := &PullRequestRequest{ Title: "Test PR", Body: "Test PR body", Head: "feature", Base: "main", } pullRequest, err := client.CreatePullRequest(context.Background(), pr) if err != nil { t.Fatalf("CreatePullRequest failed: %v", err) } // Check response if pullRequest.ID != 1 { t.Errorf("Expected ID to be 1, got %d", pullRequest.ID) } if pullRequest.Number != 123 { t.Errorf("Expected Number to be 123, got %d", pullRequest.Number) } if pullRequest.Title != "Test PR" { t.Errorf("Expected Title to be 'Test PR', got '%s'", pullRequest.Title) } if pullRequest.Body != "Test PR body" { t.Errorf("Expected Body to be 'Test PR body', got '%s'", pullRequest.Body) } if pullRequest.HTMLURL != "https://github.com/owner/repo/pull/123" { t.Errorf("Expected HTMLURL to be 'https://github.com/owner/repo/pull/123', got '%s'", pullRequest.HTMLURL) } } func TestGetPullRequests(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodGet { t.Errorf("Expected GET request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/pulls" { t.Errorf("Expected path to be '/repos/owner/repo/pulls', got '%s'", r.URL.Path) } // Check request query if r.URL.Query().Get("state") != "open" { t.Errorf("Expected state query to be 'open', got '%s'", r.URL.Query().Get("state")) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`[ { "id": 1, "number": 123, "state": "open", "title": "Test PR 1", "body": "Test PR body 1", "html_url": "https://github.com/owner/repo/pull/123", "user": { "login": "testuser", "id": 1 }, "head": { "label": "owner:feature1", "ref": "feature1", "sha": "abc123" }, "base": { "label": "owner:main", "ref": "main", "sha": "def456" } }, { "id": 2, "number": 124, "state": "open", "title": "Test PR 2", "body": "Test PR body 2", "html_url": "https://github.com/owner/repo/pull/124", "user": { "login": "testuser", "id": 1 }, "head": { "label": "owner:feature2", "ref": "feature2", "sha": "ghi789" }, "base": { "label": "owner:main", "ref": "main", "sha": "def456" } } ]`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Get pull requests pullRequests, err := client.GetPullRequests(context.Background(), "open") if err != nil { t.Fatalf("GetPullRequests failed: %v", err) } // Check response if len(pullRequests) != 2 { t.Errorf("Expected 2 pull requests, got %d", len(pullRequests)) } if pullRequests[0].ID != 1 { t.Errorf("Expected first PR ID to be 1, got %d", pullRequests[0].ID) } if pullRequests[0].Number != 123 { t.Errorf("Expected first PR Number to be 123, got %d", pullRequests[0].Number) } if pullRequests[0].Title != "Test PR 1" { t.Errorf("Expected first PR Title to be 'Test PR 1', got '%s'", pullRequests[0].Title) } if pullRequests[1].ID != 2 { t.Errorf("Expected second PR ID to be 2, got %d", pullRequests[1].ID) } if pullRequests[1].Number != 124 { t.Errorf("Expected second PR Number to be 124, got %d", pullRequests[1].Number) } if pullRequests[1].Title != "Test PR 2" { t.Errorf("Expected second PR Title to be 'Test PR 2', got '%s'", pullRequests[1].Title) } } func TestMergePullRequest(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodPut { t.Errorf("Expected PUT request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/pulls/123/merge" { t.Errorf("Expected path to be '/repos/owner/repo/pulls/123/merge', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{ "sha": "merged123", "merged": true, "message": "Pull Request successfully merged" }`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Merge a pull request mergeRequest := &MergePullRequestRequest{ MergeMethod: "merge", } mergeResponse, err := client.MergePullRequest(context.Background(), 123, mergeRequest) if err != nil { t.Fatalf("MergePullRequest failed: %v", err) } // Check response if mergeResponse.SHA != "merged123" { t.Errorf("Expected SHA to be 'merged123', got '%s'", mergeResponse.SHA) } if !mergeResponse.Merged { t.Errorf("Expected Merged to be true, got false") } if mergeResponse.Message != "Pull Request successfully merged" { t.Errorf("Expected Message to be 'Pull Request successfully merged', got '%s'", mergeResponse.Message) } } func TestGetUser(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodGet { t.Errorf("Expected GET request, got %s", r.Method) } // Check request path if r.URL.Path != "/user" { t.Errorf("Expected path to be '/user', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{ "login": "testuser", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/testuser", "html_url": "https://github.com/testuser", "followers_url": "https://api.github.com/users/testuser/followers", "following_url": "https://api.github.com/users/testuser/following{/other_user}", "gists_url": "https://api.github.com/users/testuser/gists{/gist_id}", "starred_url": "https://api.github.com/users/testuser/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/testuser/subscriptions", "organizations_url": "https://api.github.com/users/testuser/orgs", "repos_url": "https://api.github.com/users/testuser/repos", "events_url": "https://api.github.com/users/testuser/events{/privacy}", "received_events_url": "https://api.github.com/users/testuser/received_events", "type": "User", "site_admin": false, "name": "Test User", "company": null, "blog": "", "location": "San Francisco", "email": "testuser@example.com", "hireable": null, "bio": null, "twitter_username": null, "public_repos": 2, "public_gists": 1, "followers": 1, "following": 0, "created_at": "2023-01-01T00:00:00Z", "updated_at": "2023-01-01T00:00:00Z" }`)) }) defer server.Close() // Get user user, err := client.GetUser(context.Background()) if err != nil { t.Fatalf("GetUser failed: %v", err) } // Check response if user.Login != "testuser" { t.Errorf("Expected Login to be 'testuser', got '%s'", user.Login) } if user.ID != 1 { t.Errorf("Expected ID to be 1, got %d", user.ID) } if user.Name != "Test User" { t.Errorf("Expected Name to be 'Test User', got '%s'", user.Name) } if user.Email != "testuser@example.com" { t.Errorf("Expected Email to be 'testuser@example.com', got '%s'", user.Email) } } func TestGetRepository(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodGet { t.Errorf("Expected GET request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo" { t.Errorf("Expected path to be '/repos/owner/repo', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{ "id": 1, "node_id": "MDEwOlJlcG9zaXRvcnkx", "name": "repo", "full_name": "owner/repo", "private": false, "owner": { "login": "owner", "id": 1, "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/owner", "html_url": "https://github.com/owner", "followers_url": "https://api.github.com/users/owner/followers", "following_url": "https://api.github.com/users/owner/following{/other_user}", "gists_url": "https://api.github.com/users/owner/gists{/gist_id}", "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/owner/subscriptions", "organizations_url": "https://api.github.com/users/owner/orgs", "repos_url": "https://api.github.com/users/owner/repos", "events_url": "https://api.github.com/users/owner/events{/privacy}", "received_events_url": "https://api.github.com/users/owner/received_events", "type": "User", "site_admin": false }, "html_url": "https://github.com/owner/repo", "description": "Test repository", "fork": false, "url": "https://api.github.com/repos/owner/repo", "forks_url": "https://api.github.com/repos/owner/repo/forks", "keys_url": "https://api.github.com/repos/owner/repo/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/owner/repo/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/owner/repo/teams", "hooks_url": "https://api.github.com/repos/owner/repo/hooks", "issue_events_url": "https://api.github.com/repos/owner/repo/issues/events{/number}", "events_url": "https://api.github.com/repos/owner/repo/events", "assignees_url": "https://api.github.com/repos/owner/repo/assignees{/user}", "branches_url": "https://api.github.com/repos/owner/repo/branches{/branch}", "tags_url": "https://api.github.com/repos/owner/repo/tags", "blobs_url": "https://api.github.com/repos/owner/repo/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/owner/repo/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/owner/repo/git/refs{/sha}", "trees_url": "https://api.github.com/repos/owner/repo/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/owner/repo/statuses/{sha}", "languages_url": "https://api.github.com/repos/owner/repo/languages", "stargazers_url": "https://api.github.com/repos/owner/repo/stargazers", "contributors_url": "https://api.github.com/repos/owner/repo/contributors", "subscribers_url": "https://api.github.com/repos/owner/repo/subscribers", "subscription_url": "https://api.github.com/repos/owner/repo/subscription", "commits_url": "https://api.github.com/repos/owner/repo/commits{/sha}", "git_commits_url": "https://api.github.com/repos/owner/repo/git/commits{/sha}", "comments_url": "https://api.github.com/repos/owner/repo/comments{/number}", "issue_comment_url": "https://api.github.com/repos/owner/repo/issues/comments{/number}", "contents_url": "https://api.github.com/repos/owner/repo/contents/{+path}", "compare_url": "https://api.github.com/repos/owner/repo/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/owner/repo/merges", "archive_url": "https://api.github.com/repos/owner/repo/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/owner/repo/downloads", "issues_url": "https://api.github.com/repos/owner/repo/issues{/number}", "pulls_url": "https://api.github.com/repos/owner/repo/pulls{/number}", "milestones_url": "https://api.github.com/repos/owner/repo/milestones{/number}", "notifications_url": "https://api.github.com/repos/owner/repo/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/owner/repo/labels{/name}", "releases_url": "https://api.github.com/repos/owner/repo/releases{/id}", "deployments_url": "https://api.github.com/repos/owner/repo/deployments", "created_at": "2023-01-01T00:00:00Z", "updated_at": "2023-01-01T00:00:00Z", "pushed_at": "2023-01-01T00:00:00Z", "git_url": "git://github.com/owner/repo.git", "ssh_url": "git@github.com:owner/repo.git", "clone_url": "https://github.com/owner/repo.git", "svn_url": "https://github.com/owner/repo", "homepage": null, "size": 108, "stargazers_count": 0, "watchers_count": 0, "language": "Go", "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "open_issues_count": 0, "license": null, "forks_count": 0, "open_issues": 0, "watchers": 0, "default_branch": "main" }`)) }) defer server.Close() // Get repository repo, err := client.GetRepository(context.Background(), "owner", "repo") if err != nil { t.Fatalf("GetRepository failed: %v", err) } // Check response if repo.Name != "repo" { t.Errorf("Expected Name to be 'repo', got '%s'", repo.Name) } if repo.FullName != "owner/repo" { t.Errorf("Expected FullName to be 'owner/repo', got '%s'", repo.FullName) } if repo.Description != "Test repository" { t.Errorf("Expected Description to be 'Test repository', got '%s'", repo.Description) } if repo.Language != "Go" { t.Errorf("Expected Language to be 'Go', got '%s'", repo.Language) } } func TestGetPullRequest(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodGet { t.Errorf("Expected GET request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/pulls/123" { t.Errorf("Expected path to be '/repos/owner/repo/pulls/123', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{ "id": 1, "number": 123, "state": "open", "title": "Test PR", "body": "Test PR body", "html_url": "https://github.com/owner/repo/pull/123", "user": { "login": "testuser", "id": 1 }, "head": { "label": "owner:feature", "ref": "feature", "sha": "abc123" }, "base": { "label": "owner:main", "ref": "main", "sha": "def456" } }`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Get pull request pullRequest, err := client.GetPullRequest(context.Background(), 123) if err != nil { t.Fatalf("GetPullRequest failed: %v", err) } // Check response if pullRequest.ID != 1 { t.Errorf("Expected ID to be 1, got %d", pullRequest.ID) } if pullRequest.Number != 123 { t.Errorf("Expected Number to be 123, got %d", pullRequest.Number) } if pullRequest.Title != "Test PR" { t.Errorf("Expected Title to be 'Test PR', got '%s'", pullRequest.Title) } if pullRequest.Body != "Test PR body" { t.Errorf("Expected Body to be 'Test PR body', got '%s'", pullRequest.Body) } } func TestUpdatePullRequest(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodPatch { t.Errorf("Expected PATCH request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/pulls/123" { t.Errorf("Expected path to be '/repos/owner/repo/pulls/123', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{ "id": 1, "number": 123, "state": "open", "title": "Updated Test PR", "body": "Updated Test PR body", "html_url": "https://github.com/owner/repo/pull/123", "user": { "login": "testuser", "id": 1 }, "head": { "label": "owner:feature", "ref": "feature", "sha": "abc123" }, "base": { "label": "owner:main", "ref": "main", "sha": "def456" } }`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Update pull request pr := &PullRequestRequest{ Title: "Updated Test PR", Body: "Updated Test PR body", } pullRequest, err := client.UpdatePullRequest(context.Background(), 123, pr) if err != nil { t.Fatalf("UpdatePullRequest failed: %v", err) } // Check response if pullRequest.ID != 1 { t.Errorf("Expected ID to be 1, got %d", pullRequest.ID) } if pullRequest.Number != 123 { t.Errorf("Expected Number to be 123, got %d", pullRequest.Number) } if pullRequest.Title != "Updated Test PR" { t.Errorf("Expected Title to be 'Updated Test PR', got '%s'", pullRequest.Title) } if pullRequest.Body != "Updated Test PR body" { t.Errorf("Expected Body to be 'Updated Test PR body', got '%s'", pullRequest.Body) } } func TestCreateIssue(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodPost { t.Errorf("Expected POST request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/issues" { t.Errorf("Expected path to be '/repos/owner/repo/issues', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) w.Write([]byte(`{ "id": 1, "number": 123, "state": "open", "title": "Test Issue", "body": "Test Issue body", "html_url": "https://github.com/owner/repo/issues/123", "user": { "login": "testuser", "id": 1 } }`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Create issue issue := &IssueRequest{ Title: "Test Issue", Body: "Test Issue body", } createdIssue, err := client.CreateIssue(context.Background(), issue) if err != nil { t.Fatalf("CreateIssue failed: %v", err) } // Check response if createdIssue.ID != 1 { t.Errorf("Expected ID to be 1, got %d", createdIssue.ID) } if createdIssue.Number != 123 { t.Errorf("Expected Number to be 123, got %d", createdIssue.Number) } if createdIssue.Title != "Test Issue" { t.Errorf("Expected Title to be 'Test Issue', got '%s'", createdIssue.Title) } if createdIssue.Body != "Test Issue body" { t.Errorf("Expected Body to be 'Test Issue body', got '%s'", createdIssue.Body) } } func TestGetIssues(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodGet { t.Errorf("Expected GET request, got %s", r.Method) } // Check request path if r.URL.Path != "/repos/owner/repo/issues" { t.Errorf("Expected path to be '/repos/owner/repo/issues', got '%s'", r.URL.Path) } // Check request query if r.URL.Query().Get("state") != "open" { t.Errorf("Expected state query to be 'open', got '%s'", r.URL.Query().Get("state")) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`[ { "id": 1, "number": 123, "state": "open", "title": "Test Issue 1", "body": "Test Issue body 1", "html_url": "https://github.com/owner/repo/issues/123", "user": { "login": "testuser", "id": 1 } }, { "id": 2, "number": 124, "state": "open", "title": "Test Issue 2", "body": "Test Issue body 2", "html_url": "https://github.com/owner/repo/issues/124", "user": { "login": "testuser", "id": 1 } } ]`)) }) defer server.Close() // Set repository on client client.SetRepository("owner", "repo") // Get issues issues, err := client.GetIssues(context.Background(), "open") if err != nil { t.Fatalf("GetIssues failed: %v", err) } // Check response if len(issues) != 2 { t.Errorf("Expected 2 issues, got %d", len(issues)) } if issues[0].ID != 1 { t.Errorf("Expected first issue ID to be 1, got %d", issues[0].ID) } if issues[0].Number != 123 { t.Errorf("Expected first issue Number to be 123, got %d", issues[0].Number) } if issues[0].Title != "Test Issue 1" { t.Errorf("Expected first issue Title to be 'Test Issue 1', got '%s'", issues[0].Title) } if issues[1].ID != 2 { t.Errorf("Expected second issue ID to be 2, got %d", issues[1].ID) } if issues[1].Number != 124 { t.Errorf("Expected second issue Number to be 124, got %d", issues[1].Number) } if issues[1].Title != "Test Issue 2" { t.Errorf("Expected second issue Title to be 'Test Issue 2', got '%s'", issues[1].Title) } } func TestValidateToken(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // Check request method if r.Method != http.MethodGet { t.Errorf("Expected GET request, got %s", r.Method) } // Check request path if r.URL.Path != "/user" { t.Errorf("Expected path to be '/user', got '%s'", r.URL.Path) } // Check authorization header if r.Header.Get("Authorization") != "token test-token" { t.Errorf("Expected Authorization header to be 'token test-token', got '%s'", r.Header.Get("Authorization")) } // Write response w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write([]byte(`{ "login": "testuser", "id": 1 }`)) }) defer server.Close() // Validate token err := client.ValidateToken(context.Background()) if err != nil { t.Fatalf("ValidateToken failed: %v", err) } } func TestGetRepositoryFromRemote(t *testing.T) { // Create a test server server, client := setupTestServer(t, func(w http.ResponseWriter, r *http.Request) { // This function doesn't make HTTP requests, so we don't need to check anything w.WriteHeader(http.StatusOK) }) defer server.Close() // Get repository from remote owner, repo, err := client.GetRepositoryFromRemote(context.Background(), "origin") if err == nil { t.Error("Expected GetRepositoryFromRemote to return an error, got nil") } if owner != "" { t.Errorf("Expected owner to be empty, got '%s'", owner) } if repo != "" { t.Errorf("Expected repo to be empty, got '%s'", repo) } }