Files
git-automation-cli/internal/github/client_test.go
Dev 15bbfdcda2 feat: initial commit of Git Automation CLI
- Add comprehensive Git workflow automation tools
- Include branch management utilities
- Add commit helpers with conventional commit support
- Implement GitHub integration for PR management
- Add configuration management system
- Include comprehensive test coverage
- Add professional documentation and examples
2025-09-11 17:02:12 +03:00

970 lines
27 KiB
Go

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)
}
}