diff --git a/github/github-accessors.go b/github/github-accessors.go index db42c7f3970..60d95dbae7d 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -22422,6 +22422,174 @@ func (r *RepositoryActiveCommitters) GetName() string { return *r.Name } +// GetActor returns the Actor field. +func (r *RepositoryActivity) GetActor() *RepositoryActor { + if r == nil { + return nil + } + return r.Actor +} + +// GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise. +func (r *RepositoryActivity) GetTimestamp() Timestamp { + if r == nil || r.Timestamp == nil { + return Timestamp{} + } + return *r.Timestamp +} + +// GetAvatarURL returns the AvatarURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetAvatarURL() string { + if r == nil || r.AvatarURL == nil { + return "" + } + return *r.AvatarURL +} + +// GetEventsURL returns the EventsURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetEventsURL() string { + if r == nil || r.EventsURL == nil { + return "" + } + return *r.EventsURL +} + +// GetFollowersURL returns the FollowersURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetFollowersURL() string { + if r == nil || r.FollowersURL == nil { + return "" + } + return *r.FollowersURL +} + +// GetFollowingURL returns the FollowingURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetFollowingURL() string { + if r == nil || r.FollowingURL == nil { + return "" + } + return *r.FollowingURL +} + +// GetGistsURL returns the GistsURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetGistsURL() string { + if r == nil || r.GistsURL == nil { + return "" + } + return *r.GistsURL +} + +// GetGravatarID returns the GravatarID field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetGravatarID() string { + if r == nil || r.GravatarID == nil { + return "" + } + return *r.GravatarID +} + +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetHTMLURL() string { + if r == nil || r.HTMLURL == nil { + return "" + } + return *r.HTMLURL +} + +// GetID returns the ID field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetID() int64 { + if r == nil || r.ID == nil { + return 0 + } + return *r.ID +} + +// GetLogin returns the Login field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetLogin() string { + if r == nil || r.Login == nil { + return "" + } + return *r.Login +} + +// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetNodeID() string { + if r == nil || r.NodeID == nil { + return "" + } + return *r.NodeID +} + +// GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetOrganizationsURL() string { + if r == nil || r.OrganizationsURL == nil { + return "" + } + return *r.OrganizationsURL +} + +// GetReceivedEventsURL returns the ReceivedEventsURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetReceivedEventsURL() string { + if r == nil || r.ReceivedEventsURL == nil { + return "" + } + return *r.ReceivedEventsURL +} + +// GetReposURL returns the ReposURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetReposURL() string { + if r == nil || r.ReposURL == nil { + return "" + } + return *r.ReposURL +} + +// GetSiteAdmin returns the SiteAdmin field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetSiteAdmin() bool { + if r == nil || r.SiteAdmin == nil { + return false + } + return *r.SiteAdmin +} + +// GetStarredURL returns the StarredURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetStarredURL() string { + if r == nil || r.StarredURL == nil { + return "" + } + return *r.StarredURL +} + +// GetSubscriptionsURL returns the SubscriptionsURL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetSubscriptionsURL() string { + if r == nil || r.SubscriptionsURL == nil { + return "" + } + return *r.SubscriptionsURL +} + +// GetType returns the Type field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetType() string { + if r == nil || r.Type == nil { + return "" + } + return *r.Type +} + +// GetURL returns the URL field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetURL() string { + if r == nil || r.URL == nil { + return "" + } + return *r.URL +} + +// GetUserViewType returns the UserViewType field if it's non-nil, zero value otherwise. +func (r *RepositoryActor) GetUserViewType() string { + if r == nil || r.UserViewType == nil { + return "" + } + return *r.UserViewType +} + // GetConfiguration returns the Configuration field. func (r *RepositoryCodeSecurityConfiguration) GetConfiguration() *CodeSecurityConfiguration { if r == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index b41098b1b47..199b237172c 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -28960,6 +28960,234 @@ func TestRepositoryActiveCommitters_GetName(tt *testing.T) { r.GetName() } +func TestRepositoryActivity_GetActor(tt *testing.T) { + tt.Parallel() + r := &RepositoryActivity{} + r.GetActor() + r = nil + r.GetActor() +} + +func TestRepositoryActivity_GetTimestamp(tt *testing.T) { + tt.Parallel() + var zeroValue Timestamp + r := &RepositoryActivity{Timestamp: &zeroValue} + r.GetTimestamp() + r = &RepositoryActivity{} + r.GetTimestamp() + r = nil + r.GetTimestamp() +} + +func TestRepositoryActor_GetAvatarURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{AvatarURL: &zeroValue} + r.GetAvatarURL() + r = &RepositoryActor{} + r.GetAvatarURL() + r = nil + r.GetAvatarURL() +} + +func TestRepositoryActor_GetEventsURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{EventsURL: &zeroValue} + r.GetEventsURL() + r = &RepositoryActor{} + r.GetEventsURL() + r = nil + r.GetEventsURL() +} + +func TestRepositoryActor_GetFollowersURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{FollowersURL: &zeroValue} + r.GetFollowersURL() + r = &RepositoryActor{} + r.GetFollowersURL() + r = nil + r.GetFollowersURL() +} + +func TestRepositoryActor_GetFollowingURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{FollowingURL: &zeroValue} + r.GetFollowingURL() + r = &RepositoryActor{} + r.GetFollowingURL() + r = nil + r.GetFollowingURL() +} + +func TestRepositoryActor_GetGistsURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{GistsURL: &zeroValue} + r.GetGistsURL() + r = &RepositoryActor{} + r.GetGistsURL() + r = nil + r.GetGistsURL() +} + +func TestRepositoryActor_GetGravatarID(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{GravatarID: &zeroValue} + r.GetGravatarID() + r = &RepositoryActor{} + r.GetGravatarID() + r = nil + r.GetGravatarID() +} + +func TestRepositoryActor_GetHTMLURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{HTMLURL: &zeroValue} + r.GetHTMLURL() + r = &RepositoryActor{} + r.GetHTMLURL() + r = nil + r.GetHTMLURL() +} + +func TestRepositoryActor_GetID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + r := &RepositoryActor{ID: &zeroValue} + r.GetID() + r = &RepositoryActor{} + r.GetID() + r = nil + r.GetID() +} + +func TestRepositoryActor_GetLogin(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{Login: &zeroValue} + r.GetLogin() + r = &RepositoryActor{} + r.GetLogin() + r = nil + r.GetLogin() +} + +func TestRepositoryActor_GetNodeID(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{NodeID: &zeroValue} + r.GetNodeID() + r = &RepositoryActor{} + r.GetNodeID() + r = nil + r.GetNodeID() +} + +func TestRepositoryActor_GetOrganizationsURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{OrganizationsURL: &zeroValue} + r.GetOrganizationsURL() + r = &RepositoryActor{} + r.GetOrganizationsURL() + r = nil + r.GetOrganizationsURL() +} + +func TestRepositoryActor_GetReceivedEventsURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{ReceivedEventsURL: &zeroValue} + r.GetReceivedEventsURL() + r = &RepositoryActor{} + r.GetReceivedEventsURL() + r = nil + r.GetReceivedEventsURL() +} + +func TestRepositoryActor_GetReposURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{ReposURL: &zeroValue} + r.GetReposURL() + r = &RepositoryActor{} + r.GetReposURL() + r = nil + r.GetReposURL() +} + +func TestRepositoryActor_GetSiteAdmin(tt *testing.T) { + tt.Parallel() + var zeroValue bool + r := &RepositoryActor{SiteAdmin: &zeroValue} + r.GetSiteAdmin() + r = &RepositoryActor{} + r.GetSiteAdmin() + r = nil + r.GetSiteAdmin() +} + +func TestRepositoryActor_GetStarredURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{StarredURL: &zeroValue} + r.GetStarredURL() + r = &RepositoryActor{} + r.GetStarredURL() + r = nil + r.GetStarredURL() +} + +func TestRepositoryActor_GetSubscriptionsURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{SubscriptionsURL: &zeroValue} + r.GetSubscriptionsURL() + r = &RepositoryActor{} + r.GetSubscriptionsURL() + r = nil + r.GetSubscriptionsURL() +} + +func TestRepositoryActor_GetType(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{Type: &zeroValue} + r.GetType() + r = &RepositoryActor{} + r.GetType() + r = nil + r.GetType() +} + +func TestRepositoryActor_GetURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{URL: &zeroValue} + r.GetURL() + r = &RepositoryActor{} + r.GetURL() + r = nil + r.GetURL() +} + +func TestRepositoryActor_GetUserViewType(tt *testing.T) { + tt.Parallel() + var zeroValue string + r := &RepositoryActor{UserViewType: &zeroValue} + r.GetUserViewType() + r = &RepositoryActor{} + r.GetUserViewType() + r = nil + r.GetUserViewType() +} + func TestRepositoryCodeSecurityConfiguration_GetConfiguration(tt *testing.T) { tt.Parallel() r := &RepositoryCodeSecurityConfiguration{} diff --git a/github/repos.go b/github/repos.go index 402f8b1586c..26dc657f086 100644 --- a/github/repos.go +++ b/github/repos.go @@ -2438,3 +2438,99 @@ func (s *RepositoriesService) IsPrivateReportingEnabled(ctx context.Context, own resp, err := s.client.Do(ctx, req, privateReporting) return privateReporting.Enabled, resp, err } + +// ListRepositoryActivityOptions specifies the optional parameters to the +// RepositoriesService.ListRepositoryActivities method. +type ListRepositoryActivityOptions struct { + // The direction to sort the results by. + // Default: desc + // Can be one of: asc, desc + Direction string `url:"direction,omitempty"` + + // For paginated result sets, The number of results per page (max 100). + PerPage int `url:"per_page,omitempty"` + + // A cursor, as given in the Link header. If specified, the query only searches for events before this cursor. + Before string `url:"before,omitempty"` + + // A cursor, as given in the Link header. If specified, the query only searches for events after this cursor. + After string `url:"after,omitempty"` + + // The Git reference for the activities you want to list. + // The ref for a branch can be formatted either as refs/heads/BRANCH_NAME or BRANCH_NAME, where BRANCH_NAME is the name of your branch. + Ref string `url:"ref,omitempty"` + + // The GitHub username to use to filter by the actor who performed the activity. + Actor string `url:"actor,omitempty"` + + // The time period to filter by. + // For example, day will filter for activity that occurred in the past 24 hours, and week will filter for activity that occurred in the past 7 days (168 hours). + // Can be one of: day, week, month, quarter, year + TimePeriod string `url:"time_period,omitempty"` + + // The activity type to filter by. + // For example, you can choose to filter by "force_push", to see all force pushes to the repository. + // Can be one of: push, force_push, branch_creation, branch_deletion, pr_merge, merge_queue_merge + ActivityType string `url:"activity_type,omitempty"` +} + +// RepositoryActor represents a repository actor. +type RepositoryActor struct { + Login *string `json:"login,omitempty"` + ID *int64 `json:"id,omitempty"` + NodeID *string `json:"node_id,omitempty"` + AvatarURL *string `json:"avatar_url,omitempty"` + GravatarID *string `json:"gravatar_id,omitempty"` + URL *string `json:"url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` + FollowersURL *string `json:"followers_url,omitempty"` + FollowingURL *string `json:"following_url,omitempty"` + GistsURL *string `json:"gists_url,omitempty"` + StarredURL *string `json:"starred_url,omitempty"` + SubscriptionsURL *string `json:"subscriptions_url,omitempty"` + OrganizationsURL *string `json:"organizations_url,omitempty"` + ReposURL *string `json:"repos_url,omitempty"` + EventsURL *string `json:"events_url,omitempty"` + ReceivedEventsURL *string `json:"received_events_url,omitempty"` + Type *string `json:"type,omitempty"` + UserViewType *string `json:"user_view_type,omitempty"` + SiteAdmin *bool `json:"site_admin,omitempty"` +} + +// RepositoryActivity represents a repository activity. +type RepositoryActivity struct { + ID int64 `json:"id"` + NodeID string `json:"node_id"` + Before string `json:"before"` + After string `json:"after"` + Ref string `json:"ref"` + Timestamp *Timestamp `json:"timestamp"` + ActivityType string `json:"activity_type"` + Actor *RepositoryActor `json:"actor,omitempty"` +} + +// ListRepositoryActivities lists the activities for a repository. +// +// GitHub API docs: https://docs.github.com/rest/repos/repos#list-repository-activities +// +//meta:operation GET /repos/{owner}/{repo}/activity +func (s *RepositoriesService) ListRepositoryActivities(ctx context.Context, owner, repo string, opts *ListRepositoryActivityOptions) ([]*RepositoryActivity, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/activity", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var activities []*RepositoryActivity + resp, err := s.client.Do(ctx, req, &activities) + if err != nil { + return nil, resp, err + } + + return activities, resp, nil +} diff --git a/github/repos_test.go b/github/repos_test.go index 1384fb40ca7..91b20dcb5f2 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -4567,3 +4567,312 @@ func TestRepository_UnmarshalJSON(t *testing.T) { }) } } + +func TestRepositoriesService_ListRepositoryActivities(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/activity", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "per_page": "100", + }) + fmt.Fprint(w, `[ + { + "id": 123456789, + "node_id": "PSH_test123", + "before": "abc123def456", + "after": "def456ghi789", + "ref": "refs/heads/main", + "timestamp": "2023-01-01T12:00:00Z", + "activity_type": "push", + "actor": { + "login": "testuser1", + "id": 111111, + "node_id": "MDQ6VXNlcjExMTExMQ==", + "avatar_url": "https://avatars.githubusercontent.com/u/111111?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/testuser1", + "html_url": "https://github.com/testuser1", + "followers_url": "https://api.github.com/users/testuser1/followers", + "following_url": "https://api.github.com/users/testuser1/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser1/gists{/gist_id}", + "starred_url": "https://api.github.com/users/testuser1/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser1/subscriptions", + "organizations_url": "https://api.github.com/users/testuser1/orgs", + "repos_url": "https://api.github.com/users/testuser1/repos", + "events_url": "https://api.github.com/users/testuser1/events{/privacy}", + "received_events_url": "https://api.github.com/users/testuser1/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + } + }, + { + "id": 123456788, + "node_id": "PSH_test124", + "before": "def456ghi789", + "after": "ghi789jkl012", + "ref": "refs/heads/feature", + "timestamp": "2023-01-01T11:30:00Z", + "activity_type": "branch_deletion", + "actor": { + "login": "testuser2", + "id": 222222, + "node_id": "MDQ6VXNlcjIyMjIyMg==", + "avatar_url": "https://avatars.githubusercontent.com/u/222222?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/testuser2", + "html_url": "https://github.com/testuser2", + "followers_url": "https://api.github.com/users/testuser2/followers", + "following_url": "https://api.github.com/users/testuser2/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser2/gists{/gist_id}", + "starred_url": "https://api.github.com/users/testuser2/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser2/subscriptions", + "organizations_url": "https://api.github.com/users/testuser2/orgs", + "repos_url": "https://api.github.com/users/testuser2/repos", + "events_url": "https://api.github.com/users/testuser2/events{/privacy}", + "received_events_url": "https://api.github.com/users/testuser2/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + } + } + ]`) + }) + + opts := &ListRepositoryActivityOptions{PerPage: 100} + ctx := context.Background() + activities, _, err := client.Repositories.ListRepositoryActivities(ctx, "o", "r", opts) + if err != nil { + t.Errorf("Repositories.ListRepositoryActivities returned error: %v", err) + } + + want := []*RepositoryActivity{ + { + ID: 123456789, + NodeID: "PSH_test123", + Before: "abc123def456", + After: "def456ghi789", + Ref: "refs/heads/main", + Timestamp: &Timestamp{Time: time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)}, + ActivityType: "push", + Actor: &RepositoryActor{ + Login: Ptr("testuser1"), + ID: Ptr(int64(111111)), + NodeID: Ptr("MDQ6VXNlcjExMTExMQ=="), + AvatarURL: Ptr("https://avatars.githubusercontent.com/u/111111?v=4"), + GravatarID: Ptr(""), + URL: Ptr("https://api.github.com/users/testuser1"), + HTMLURL: Ptr("https://github.com/testuser1"), + FollowersURL: Ptr("https://api.github.com/users/testuser1/followers"), + FollowingURL: Ptr("https://api.github.com/users/testuser1/following{/other_user}"), + GistsURL: Ptr("https://api.github.com/users/testuser1/gists{/gist_id}"), + StarredURL: Ptr("https://api.github.com/users/testuser1/starred{/owner}{/repo}"), + SubscriptionsURL: Ptr("https://api.github.com/users/testuser1/subscriptions"), + OrganizationsURL: Ptr("https://api.github.com/users/testuser1/orgs"), + ReposURL: Ptr("https://api.github.com/users/testuser1/repos"), + EventsURL: Ptr("https://api.github.com/users/testuser1/events{/privacy}"), + ReceivedEventsURL: Ptr("https://api.github.com/users/testuser1/received_events"), + Type: Ptr("User"), + UserViewType: Ptr("public"), + SiteAdmin: Ptr(false), + }, + }, + { + ID: 123456788, + NodeID: "PSH_test124", + Before: "def456ghi789", + After: "ghi789jkl012", + Ref: "refs/heads/feature", + Timestamp: &Timestamp{Time: time.Date(2023, 1, 1, 11, 30, 0, 0, time.UTC)}, + ActivityType: "branch_deletion", + Actor: &RepositoryActor{ + Login: Ptr("testuser2"), + ID: Ptr(int64(222222)), + NodeID: Ptr("MDQ6VXNlcjIyMjIyMg=="), + AvatarURL: Ptr("https://avatars.githubusercontent.com/u/222222?v=4"), + GravatarID: Ptr(""), + URL: Ptr("https://api.github.com/users/testuser2"), + HTMLURL: Ptr("https://github.com/testuser2"), + FollowersURL: Ptr("https://api.github.com/users/testuser2/followers"), + FollowingURL: Ptr("https://api.github.com/users/testuser2/following{/other_user}"), + GistsURL: Ptr("https://api.github.com/users/testuser2/gists{/gist_id}"), + StarredURL: Ptr("https://api.github.com/users/testuser2/starred{/owner}{/repo}"), + SubscriptionsURL: Ptr("https://api.github.com/users/testuser2/subscriptions"), + OrganizationsURL: Ptr("https://api.github.com/users/testuser2/orgs"), + ReposURL: Ptr("https://api.github.com/users/testuser2/repos"), + EventsURL: Ptr("https://api.github.com/users/testuser2/events{/privacy}"), + ReceivedEventsURL: Ptr("https://api.github.com/users/testuser2/received_events"), + Type: Ptr("User"), + UserViewType: Ptr("public"), + SiteAdmin: Ptr(false), + }, + }, + } + + if !cmp.Equal(activities, want) { + t.Errorf("Repositories.ListRepositoryActivities returned %+v, want %+v", activities, want) + } + + const methodName = "ListRepositoryActivities" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Repositories.ListRepositoryActivities(ctx, "\n", "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Repositories.ListRepositoryActivities(ctx, "o", "r", opts) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestRepositoriesService_ListRepositoryActivities_withOptions(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/activity", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{ + "direction": "desc", + "before": "2023-01-01T12:00:00Z", + "after": "2023-01-01T11:30:00Z", + "ref": "refs/heads/main", + "actor": "testuser1", + "time_period": "day", + "activity_type": "push", + "per_page": "50", + }) + fmt.Fprint(w, `[ + { + "id": 123456789, + "node_id": "PSH_test123", + "before": "abc123def456", + "after": "def456ghi789", + "ref": "refs/heads/main", + "timestamp": "2023-01-01T12:00:00Z", + "activity_type": "push", + "actor": { + "login": "testuser1", + "id": 111111, + "node_id": "MDQ6VXNlcjExMTExMQ==", + "avatar_url": "https://avatars.githubusercontent.com/u/111111?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/testuser1", + "html_url": "https://github.com/testuser1", + "followers_url": "https://api.github.com/users/testuser1/followers", + "following_url": "https://api.github.com/users/testuser1/following{/other_user}", + "gists_url": "https://api.github.com/users/testuser1/gists{/gist_id}", + "starred_url": "https://api.github.com/users/testuser1/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/testuser1/subscriptions", + "organizations_url": "https://api.github.com/users/testuser1/orgs", + "repos_url": "https://api.github.com/users/testuser1/repos", + "events_url": "https://api.github.com/users/testuser1/events{/privacy}", + "received_events_url": "https://api.github.com/users/testuser1/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + } + } + ]`) + }) + + opts := &ListRepositoryActivityOptions{ + Direction: "desc", + Before: "2023-01-01T12:00:00Z", + After: "2023-01-01T11:30:00Z", + Ref: "refs/heads/main", + Actor: "testuser1", + TimePeriod: "day", + ActivityType: "push", + PerPage: 50, + } + ctx := context.Background() + activities, _, err := client.Repositories.ListRepositoryActivities(ctx, "o", "r", opts) + if err != nil { + t.Errorf("Repositories.ListRepositoryActivities returned error: %v", err) + } + + want := []*RepositoryActivity{ + { + ID: 123456789, + NodeID: "PSH_test123", + Before: "abc123def456", + After: "def456ghi789", + Ref: "refs/heads/main", + Timestamp: &Timestamp{Time: time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)}, + ActivityType: "push", + Actor: &RepositoryActor{ + Login: Ptr("testuser1"), + ID: Ptr(int64(111111)), + NodeID: Ptr("MDQ6VXNlcjExMTExMQ=="), + AvatarURL: Ptr("https://avatars.githubusercontent.com/u/111111?v=4"), + GravatarID: Ptr(""), + URL: Ptr("https://api.github.com/users/testuser1"), + HTMLURL: Ptr("https://github.com/testuser1"), + FollowersURL: Ptr("https://api.github.com/users/testuser1/followers"), + FollowingURL: Ptr("https://api.github.com/users/testuser1/following{/other_user}"), + GistsURL: Ptr("https://api.github.com/users/testuser1/gists{/gist_id}"), + StarredURL: Ptr("https://api.github.com/users/testuser1/starred{/owner}{/repo}"), + SubscriptionsURL: Ptr("https://api.github.com/users/testuser1/subscriptions"), + OrganizationsURL: Ptr("https://api.github.com/users/testuser1/orgs"), + ReposURL: Ptr("https://api.github.com/users/testuser1/repos"), + EventsURL: Ptr("https://api.github.com/users/testuser1/events{/privacy}"), + ReceivedEventsURL: Ptr("https://api.github.com/users/testuser1/received_events"), + Type: Ptr("User"), + UserViewType: Ptr("public"), + SiteAdmin: Ptr(false), + }, + }, + } + + if !cmp.Equal(activities, want) { + t.Errorf("Repositories.ListRepositoryActivities returned %+v, want %+v", activities, want) + } +} + +func TestRepositoriesService_ListRepositoryActivities_emptyResponse(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/repos/o/r/activity", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `[]`) + }) + + ctx := context.Background() + activities, _, err := client.Repositories.ListRepositoryActivities(ctx, "o", "r", nil) + if err != nil { + t.Errorf("Repositories.ListRepositoryActivities returned error: %v", err) + } + + want := []*RepositoryActivity{} + if !cmp.Equal(activities, want) { + t.Errorf("Repositories.ListRepositoryActivities returned %+v, want %+v", activities, want) + } +} + +func TestRepositoriesService_ListRepositoryActivities_invalidOwner(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + ctx := context.Background() + _, _, err := client.Repositories.ListRepositoryActivities(ctx, "%", "r", nil) + if err == nil { + t.Error("Expected error to be returned") + } +} + +func TestRepositoriesService_ListRepositoryActivities_invalidRepo(t *testing.T) { + t.Parallel() + client, _, _ := setup(t) + + ctx := context.Background() + _, _, err := client.Repositories.ListRepositoryActivities(ctx, "o", "%", nil) + if err == nil { + t.Error("Expected error to be returned") + } +}