Repository: google/go-github
Pull request #2947 (2023-10-03 04:43:12)

Add List Installation Requests API
The PR adds support for [listing installation requests for the authenticated app](https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#list-installation-requests-for-the-authenticated-app).


- [x] Feature addition
- [x] Added Tests
- [x] Run the essential scripts for linting, generation etc.

google-cla[bot]: Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this [failed invocation](https://github.com/google/go-github/pull/2947/checks?check_run_id=17339117232) of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.
abhijit-hota: Signed CLA and rescanned.
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/google/go-github/pull/2947?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
> Merging [#2947](https://app.codecov.io/gh/google/go-github/pull/2947?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (3bc5b0b) into [master](https://app.codecov.io/gh/google/go-github/commit/8cd452b85e821c32eefcc5964e91e57f9731891f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (8cd452b) will **decrease** coverage by `0.03%`.
> The diff coverage is `80.00%`.

```diff
@@            Coverage Diff             @@
##           master    #2947      +/-   ##
==========================================
- Coverage   98.19%   98.17%   -0.03%     
==========================================
  Files         145      145              
  Lines       12720    12735      +15     
==========================================
+ Hits        12490    12502      +12     
- Misses        156      158       +2     
- Partials       74       75       +1     
```


| [Files](https://app.codecov.io/gh/google/go-github/pull/2947?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) | Coverage Δ | |
|---|---|---|
| [github/apps.go](https://app.codecov.io/gh/google/go-github/pull/2947?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL2FwcHMuZ28=) | `93.52% <80.00%> (-1.64%)` | :arrow_down: |


abhijit-hota: Thanks, @gmlewis. I see that the coverage has decreased somehow. Can I do anything about it?
gmlewis: > Thanks, @gmlewis. I see that the coverage has decreased somehow. Can I do anything about it?

I don't think so, because it is harder to test the endpoints that take no parameters in the URL itself... as we can't corrupt it as easily... so I'm not worried about the dropping code coverage in this case.

Thank you for checking, though, @abhijit-hota !  It is appreciated. ❤️ 
gmlewis: Thank you, @WillAbides !
Merging.

Patch:
diff --git a/github/apps.go b/github/apps.go
index ab83d59a..8965e668 100644
--- a/github/apps.go
+++ b/github/apps.go
@@ -102,6 +102,15 @@ type InstallationPermissions struct {
 	Workflows                     *string `json:"workflows,omitempty"`
 }
 
+// InstallationRequest represents a pending GitHub App installation request.
+type InstallationRequest struct {
+	ID        *int64     `json:"id,omitempty"`
+	NodeID    *string    `json:"node_id,omitempty"`
+	Account   *User      `json:"account,omitempty"`
+	Requester *User      `json:"requester,omitempty"`
+	CreatedAt *Timestamp `json:"created_at,omitempty"`
+}
+
 // Installation represents a GitHub Apps installation.
 type Installation struct {
 	ID                     *int64                   `json:"id,omitempty"`
@@ -175,6 +184,29 @@ func (s *AppsService) Get(ctx context.Context, appSlug string) (*App, *Response,
 	return app, resp, nil
 }
 
+// ListInstallationRequests lists the pending installation requests that the current GitHub App has.
+//
+// GitHub API docs: https://docs.github.com/en/rest/apps/apps#list-installation-requests-for-the-authenticated-app
+func (s *AppsService) ListInstallationRequests(ctx context.Context, opts *ListOptions) ([]*InstallationRequest, *Response, error) {
+	u, err := addOptions("app/installation-requests", opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var i []*InstallationRequest
+	resp, err := s.client.Do(ctx, req, &i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
 // ListInstallations lists the installations that the current GitHub App has.
 //
 // GitHub API docs: https://docs.github.com/en/rest/apps/apps#list-installations-for-the-authenticated-app
diff --git a/github/github-accessors.go b/github/github-accessors.go
index b305bfc6..f34d9a4a 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -8910,6 +8910,46 @@ func (i *InstallationRepositoriesEvent) GetSender() *User {
 	return i.Sender
 }
 
+// GetAccount returns the Account field.
+func (i *InstallationRequest) GetAccount() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Account
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (i *InstallationRequest) GetCreatedAt() Timestamp {
+	if i == nil || i.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *i.CreatedAt
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (i *InstallationRequest) GetID() int64 {
+	if i == nil || i.ID == nil {
+		return 0
+	}
+	return *i.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (i *InstallationRequest) GetNodeID() string {
+	if i == nil || i.NodeID == nil {
+		return ""
+	}
+	return *i.NodeID
+}
+
+// GetRequester returns the Requester field.
+func (i *InstallationRequest) GetRequester() *User {
+	if i == nil {
+		return nil
+	}
+	return i.Requester
+}
+
 // GetFrom returns the From field if it's non-nil, zero value otherwise.
 func (i *InstallationSlugChange) GetFrom() string {
 	if i == nil || i.From == nil {


Test patch:
diff --git a/github/apps_test.go b/github/apps_test.go
index f87d5006..a58326ea 100644
--- a/github/apps_test.go
+++ b/github/apps_test.go
@@ -72,6 +72,53 @@ func TestAppsService_Get_specifiedApp(t *testing.T) {
 	}
 }
 
+func TestAppsService_ListInstallationRequests(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/app/installation-requests", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{
+			"page":     "1",
+			"per_page": "2",
+		})
+		fmt.Fprint(w, `[{
+			"id": 1,
+			"account": { "id": 2 },
+			"requester": { "id": 3 },
+			"created_at": "2018-01-01T00:00:00Z"
+		}]`,
+		)
+	})
+
+	opt := &ListOptions{Page: 1, PerPage: 2}
+	ctx := context.Background()
+	installationRequests, _, err := client.Apps.ListInstallationRequests(ctx, opt)
+	if err != nil {
+		t.Errorf("Apps.ListInstallations returned error: %v", err)
+	}
+
+	date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)}
+	want := []*InstallationRequest{{
+		ID:        Int64(1),
+		Account:   &User{ID: Int64(2)},
+		Requester: &User{ID: Int64(3)},
+		CreatedAt: &date,
+	}}
+	if !cmp.Equal(installationRequests, want) {
+		t.Errorf("Apps.ListInstallationRequests returned %+v, want %+v", installationRequests, want)
+	}
+
+	const methodName = "ListInstallationRequests"
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Apps.ListInstallationRequests(ctx, opt)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
 func TestAppsService_ListInstallations(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 962e5e8f..25c8ab7e 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -10487,6 +10487,50 @@ func TestInstallationRepositoriesEvent_GetSender(tt *testing.T) {
 	i.GetSender()
 }
 
+func TestInstallationRequest_GetAccount(tt *testing.T) {
+	i := &InstallationRequest{}
+	i.GetAccount()
+	i = nil
+	i.GetAccount()
+}
+
+func TestInstallationRequest_GetCreatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	i := &InstallationRequest{CreatedAt: &zeroValue}
+	i.GetCreatedAt()
+	i = &InstallationRequest{}
+	i.GetCreatedAt()
+	i = nil
+	i.GetCreatedAt()
+}
+
+func TestInstallationRequest_GetID(tt *testing.T) {
+	var zeroValue int64
+	i := &InstallationRequest{ID: &zeroValue}
+	i.GetID()
+	i = &InstallationRequest{}
+	i.GetID()
+	i = nil
+	i.GetID()
+}
+
+func TestInstallationRequest_GetNodeID(tt *testing.T) {
+	var zeroValue string
+	i := &InstallationRequest{NodeID: &zeroValue}
+	i.GetNodeID()
+	i = &InstallationRequest{}
+	i.GetNodeID()
+	i = nil
+	i.GetNodeID()
+}
+
+func TestInstallationRequest_GetRequester(tt *testing.T) {
+	i := &InstallationRequest{}
+	i.GetRequester()
+	i = nil
+	i.GetRequester()
+}
+
 func TestInstallationSlugChange_GetFrom(tt *testing.T) {
 	var zeroValue string
 	i := &InstallationSlugChange{From: &zeroValue}