github.com/google/go-github/v70@v70.0.0/github/apps_test.go (about)

     1  // Copyright 2016 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"encoding/json"
    11  	"fmt"
    12  	"net/http"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/google/go-cmp/cmp"
    17  )
    18  
    19  func TestAppsService_Get_authenticatedApp(t *testing.T) {
    20  	t.Parallel()
    21  	client, mux, _ := setup(t)
    22  
    23  	mux.HandleFunc("/app", func(w http.ResponseWriter, r *http.Request) {
    24  		testMethod(t, r, "GET")
    25  		fmt.Fprint(w, `{"id":1}`)
    26  	})
    27  
    28  	ctx := context.Background()
    29  	app, _, err := client.Apps.Get(ctx, "")
    30  	if err != nil {
    31  		t.Errorf("Apps.Get returned error: %v", err)
    32  	}
    33  
    34  	want := &App{ID: Ptr(int64(1))}
    35  	if !cmp.Equal(app, want) {
    36  		t.Errorf("Apps.Get returned %+v, want %+v", app, want)
    37  	}
    38  
    39  	const methodName = "Get"
    40  	testBadOptions(t, methodName, func() (err error) {
    41  		_, _, err = client.Apps.Get(ctx, "\n")
    42  		return err
    43  	})
    44  
    45  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    46  		got, resp, err := client.Apps.Get(ctx, "")
    47  		if got != nil {
    48  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    49  		}
    50  		return resp, err
    51  	})
    52  }
    53  
    54  func TestAppsService_Get_specifiedApp(t *testing.T) {
    55  	t.Parallel()
    56  	client, mux, _ := setup(t)
    57  
    58  	mux.HandleFunc("/apps/a", func(w http.ResponseWriter, r *http.Request) {
    59  		testMethod(t, r, "GET")
    60  		fmt.Fprint(w, `{"html_url":"https://github.com/apps/a"}`)
    61  	})
    62  
    63  	ctx := context.Background()
    64  	app, _, err := client.Apps.Get(ctx, "a")
    65  	if err != nil {
    66  		t.Errorf("Apps.Get returned error: %v", err)
    67  	}
    68  
    69  	want := &App{HTMLURL: Ptr("https://github.com/apps/a")}
    70  	if !cmp.Equal(app, want) {
    71  		t.Errorf("Apps.Get returned %+v, want %+v", *app.HTMLURL, *want.HTMLURL)
    72  	}
    73  }
    74  
    75  func TestAppsService_ListInstallationRequests(t *testing.T) {
    76  	t.Parallel()
    77  	client, mux, _ := setup(t)
    78  
    79  	mux.HandleFunc("/app/installation-requests", func(w http.ResponseWriter, r *http.Request) {
    80  		testMethod(t, r, "GET")
    81  		testFormValues(t, r, values{
    82  			"page":     "1",
    83  			"per_page": "2",
    84  		})
    85  		fmt.Fprint(w, `[{
    86  			"id": 1,
    87  			"account": { "id": 2 },
    88  			"requester": { "id": 3 },
    89  			"created_at": "2018-01-01T00:00:00Z"
    90  		}]`,
    91  		)
    92  	})
    93  
    94  	opt := &ListOptions{Page: 1, PerPage: 2}
    95  	ctx := context.Background()
    96  	installationRequests, _, err := client.Apps.ListInstallationRequests(ctx, opt)
    97  	if err != nil {
    98  		t.Errorf("Apps.ListInstallations returned error: %v", err)
    99  	}
   100  
   101  	date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)}
   102  	want := []*InstallationRequest{{
   103  		ID:        Ptr(int64(1)),
   104  		Account:   &User{ID: Ptr(int64(2))},
   105  		Requester: &User{ID: Ptr(int64(3))},
   106  		CreatedAt: &date,
   107  	}}
   108  	if !cmp.Equal(installationRequests, want) {
   109  		t.Errorf("Apps.ListInstallationRequests returned %+v, want %+v", installationRequests, want)
   110  	}
   111  
   112  	const methodName = "ListInstallationRequests"
   113  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   114  		got, resp, err := client.Apps.ListInstallationRequests(ctx, opt)
   115  		if got != nil {
   116  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   117  		}
   118  		return resp, err
   119  	})
   120  }
   121  
   122  func TestAppsService_ListInstallations(t *testing.T) {
   123  	t.Parallel()
   124  	client, mux, _ := setup(t)
   125  
   126  	mux.HandleFunc("/app/installations", func(w http.ResponseWriter, r *http.Request) {
   127  		testMethod(t, r, "GET")
   128  		testFormValues(t, r, values{
   129  			"page":     "1",
   130  			"per_page": "2",
   131  		})
   132  		fmt.Fprint(w, `[{
   133                                     "id":1,
   134                                     "app_id":1,
   135                                     "target_id":1,
   136                                     "target_type": "Organization",
   137                                     "permissions": {
   138                                         "actions": "read",
   139                                         "administration": "read",
   140                                         "checks": "read",
   141                                         "contents": "read",
   142                                         "content_references": "read",
   143                                         "deployments": "read",
   144                                         "environments": "read",
   145                                         "issues": "write",
   146                                         "metadata": "read",
   147                                         "members": "read",
   148                                         "organization_administration": "write",
   149                                         "organization_custom_roles": "write",
   150                                         "organization_hooks": "write",
   151                                         "organization_packages": "write",
   152                                         "organization_personal_access_tokens": "read",
   153                                         "organization_personal_access_token_requests": "read",
   154                                         "organization_plan": "read",
   155                                         "organization_pre_receive_hooks": "write",
   156                                         "organization_projects": "read",
   157                                         "organization_secrets": "read",
   158                                         "organization_self_hosted_runners": "read",
   159                                         "organization_user_blocking": "write",
   160                                         "packages": "read",
   161                                         "pages": "read",
   162                                         "pull_requests": "write",
   163                                         "repository_hooks": "write",
   164                                         "repository_projects": "read",
   165                                         "repository_pre_receive_hooks": "read",
   166                                         "secrets": "read",
   167                                         "secret_scanning_alerts": "read",
   168                                         "security_events": "read",
   169                                         "single_file": "write",
   170                                         "statuses": "write",
   171                                         "team_discussions": "read",
   172                                         "vulnerability_alerts": "read",
   173                                         "workflows": "write"
   174                                     },
   175                                    "events": [
   176                                        "push",
   177                                        "pull_request"
   178                                    ],
   179                                   "single_file_name": "config.yml",
   180                                   "repository_selection": "selected",
   181                                   "created_at": "2018-01-01T00:00:00Z",
   182                                   "updated_at": "2018-01-01T00:00:00Z"}]`,
   183  		)
   184  	})
   185  
   186  	opt := &ListOptions{Page: 1, PerPage: 2}
   187  	ctx := context.Background()
   188  	installations, _, err := client.Apps.ListInstallations(ctx, opt)
   189  	if err != nil {
   190  		t.Errorf("Apps.ListInstallations returned error: %v", err)
   191  	}
   192  
   193  	date := Timestamp{Time: time.Date(2018, time.January, 1, 0, 0, 0, 0, time.UTC)}
   194  	want := []*Installation{{
   195  		ID:                  Ptr(int64(1)),
   196  		AppID:               Ptr(int64(1)),
   197  		TargetID:            Ptr(int64(1)),
   198  		TargetType:          Ptr("Organization"),
   199  		SingleFileName:      Ptr("config.yml"),
   200  		RepositorySelection: Ptr("selected"),
   201  		Permissions: &InstallationPermissions{
   202  			Actions:                                 Ptr("read"),
   203  			Administration:                          Ptr("read"),
   204  			Checks:                                  Ptr("read"),
   205  			Contents:                                Ptr("read"),
   206  			ContentReferences:                       Ptr("read"),
   207  			Deployments:                             Ptr("read"),
   208  			Environments:                            Ptr("read"),
   209  			Issues:                                  Ptr("write"),
   210  			Metadata:                                Ptr("read"),
   211  			Members:                                 Ptr("read"),
   212  			OrganizationAdministration:              Ptr("write"),
   213  			OrganizationCustomRoles:                 Ptr("write"),
   214  			OrganizationHooks:                       Ptr("write"),
   215  			OrganizationPackages:                    Ptr("write"),
   216  			OrganizationPersonalAccessTokens:        Ptr("read"),
   217  			OrganizationPersonalAccessTokenRequests: Ptr("read"),
   218  			OrganizationPlan:                        Ptr("read"),
   219  			OrganizationPreReceiveHooks:             Ptr("write"),
   220  			OrganizationProjects:                    Ptr("read"),
   221  			OrganizationSecrets:                     Ptr("read"),
   222  			OrganizationSelfHostedRunners:           Ptr("read"),
   223  			OrganizationUserBlocking:                Ptr("write"),
   224  			Packages:                                Ptr("read"),
   225  			Pages:                                   Ptr("read"),
   226  			PullRequests:                            Ptr("write"),
   227  			RepositoryHooks:                         Ptr("write"),
   228  			RepositoryProjects:                      Ptr("read"),
   229  			RepositoryPreReceiveHooks:               Ptr("read"),
   230  			Secrets:                                 Ptr("read"),
   231  			SecretScanningAlerts:                    Ptr("read"),
   232  			SecurityEvents:                          Ptr("read"),
   233  			SingleFile:                              Ptr("write"),
   234  			Statuses:                                Ptr("write"),
   235  			TeamDiscussions:                         Ptr("read"),
   236  			VulnerabilityAlerts:                     Ptr("read"),
   237  			Workflows:                               Ptr("write")},
   238  		Events:    []string{"push", "pull_request"},
   239  		CreatedAt: &date,
   240  		UpdatedAt: &date,
   241  	}}
   242  	if !cmp.Equal(installations, want) {
   243  		t.Errorf("Apps.ListInstallations returned %+v, want %+v", installations, want)
   244  	}
   245  
   246  	const methodName = "ListInstallations"
   247  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   248  		got, resp, err := client.Apps.ListInstallations(ctx, opt)
   249  		if got != nil {
   250  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   251  		}
   252  		return resp, err
   253  	})
   254  }
   255  
   256  func TestAppsService_GetInstallation(t *testing.T) {
   257  	t.Parallel()
   258  	client, mux, _ := setup(t)
   259  
   260  	mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) {
   261  		testMethod(t, r, "GET")
   262  		fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`)
   263  	})
   264  
   265  	ctx := context.Background()
   266  	installation, _, err := client.Apps.GetInstallation(ctx, 1)
   267  	if err != nil {
   268  		t.Errorf("Apps.GetInstallation returned error: %v", err)
   269  	}
   270  
   271  	want := &Installation{ID: Ptr(int64(1)), AppID: Ptr(int64(1)), TargetID: Ptr(int64(1)), TargetType: Ptr("Organization")}
   272  	if !cmp.Equal(installation, want) {
   273  		t.Errorf("Apps.GetInstallation returned %+v, want %+v", installation, want)
   274  	}
   275  
   276  	const methodName = "GetInstallation"
   277  	testBadOptions(t, methodName, func() (err error) {
   278  		_, _, err = client.Apps.GetInstallation(ctx, -1)
   279  		return err
   280  	})
   281  
   282  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   283  		got, resp, err := client.Apps.GetInstallation(ctx, 1)
   284  		if got != nil {
   285  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   286  		}
   287  		return resp, err
   288  	})
   289  }
   290  
   291  func TestAppsService_ListUserInstallations(t *testing.T) {
   292  	t.Parallel()
   293  	client, mux, _ := setup(t)
   294  
   295  	mux.HandleFunc("/user/installations", func(w http.ResponseWriter, r *http.Request) {
   296  		testMethod(t, r, "GET")
   297  		testFormValues(t, r, values{
   298  			"page":     "1",
   299  			"per_page": "2",
   300  		})
   301  		fmt.Fprint(w, `{"installations":[{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}]}`)
   302  	})
   303  
   304  	opt := &ListOptions{Page: 1, PerPage: 2}
   305  	ctx := context.Background()
   306  	installations, _, err := client.Apps.ListUserInstallations(ctx, opt)
   307  	if err != nil {
   308  		t.Errorf("Apps.ListUserInstallations returned error: %v", err)
   309  	}
   310  
   311  	want := []*Installation{{ID: Ptr(int64(1)), AppID: Ptr(int64(1)), TargetID: Ptr(int64(1)), TargetType: Ptr("Organization")}}
   312  	if !cmp.Equal(installations, want) {
   313  		t.Errorf("Apps.ListUserInstallations returned %+v, want %+v", installations, want)
   314  	}
   315  
   316  	const methodName = "ListUserInstallations"
   317  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   318  		got, resp, err := client.Apps.ListUserInstallations(ctx, opt)
   319  		if got != nil {
   320  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   321  		}
   322  		return resp, err
   323  	})
   324  }
   325  
   326  func TestAppsService_SuspendInstallation(t *testing.T) {
   327  	t.Parallel()
   328  	client, mux, _ := setup(t)
   329  
   330  	mux.HandleFunc("/app/installations/1/suspended", func(w http.ResponseWriter, r *http.Request) {
   331  		testMethod(t, r, "PUT")
   332  
   333  		w.WriteHeader(http.StatusNoContent)
   334  	})
   335  
   336  	ctx := context.Background()
   337  	if _, err := client.Apps.SuspendInstallation(ctx, 1); err != nil {
   338  		t.Errorf("Apps.SuspendInstallation returned error: %v", err)
   339  	}
   340  
   341  	const methodName = "SuspendInstallation"
   342  	testBadOptions(t, methodName, func() (err error) {
   343  		_, err = client.Apps.SuspendInstallation(ctx, -1)
   344  		return err
   345  	})
   346  
   347  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   348  		return client.Apps.SuspendInstallation(ctx, 1)
   349  	})
   350  }
   351  
   352  func TestAppsService_UnsuspendInstallation(t *testing.T) {
   353  	t.Parallel()
   354  	client, mux, _ := setup(t)
   355  
   356  	mux.HandleFunc("/app/installations/1/suspended", func(w http.ResponseWriter, r *http.Request) {
   357  		testMethod(t, r, "DELETE")
   358  
   359  		w.WriteHeader(http.StatusNoContent)
   360  	})
   361  
   362  	ctx := context.Background()
   363  	if _, err := client.Apps.UnsuspendInstallation(ctx, 1); err != nil {
   364  		t.Errorf("Apps.UnsuspendInstallation returned error: %v", err)
   365  	}
   366  
   367  	const methodName = "UnsuspendInstallation"
   368  	testBadOptions(t, methodName, func() (err error) {
   369  		_, err = client.Apps.UnsuspendInstallation(ctx, -1)
   370  		return err
   371  	})
   372  
   373  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   374  		return client.Apps.UnsuspendInstallation(ctx, 1)
   375  	})
   376  }
   377  
   378  func TestAppsService_DeleteInstallation(t *testing.T) {
   379  	t.Parallel()
   380  	client, mux, _ := setup(t)
   381  
   382  	mux.HandleFunc("/app/installations/1", func(w http.ResponseWriter, r *http.Request) {
   383  		testMethod(t, r, "DELETE")
   384  		w.WriteHeader(http.StatusNoContent)
   385  	})
   386  
   387  	ctx := context.Background()
   388  	_, err := client.Apps.DeleteInstallation(ctx, 1)
   389  	if err != nil {
   390  		t.Errorf("Apps.DeleteInstallation returned error: %v", err)
   391  	}
   392  
   393  	const methodName = "DeleteInstallation"
   394  	testBadOptions(t, methodName, func() (err error) {
   395  		_, err = client.Apps.DeleteInstallation(ctx, -1)
   396  		return err
   397  	})
   398  
   399  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   400  		return client.Apps.DeleteInstallation(ctx, 1)
   401  	})
   402  }
   403  
   404  func TestAppsService_CreateInstallationToken(t *testing.T) {
   405  	t.Parallel()
   406  	client, mux, _ := setup(t)
   407  
   408  	mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
   409  		testMethod(t, r, "POST")
   410  		fmt.Fprint(w, `{"token":"t"}`)
   411  	})
   412  
   413  	ctx := context.Background()
   414  	token, _, err := client.Apps.CreateInstallationToken(ctx, 1, nil)
   415  	if err != nil {
   416  		t.Errorf("Apps.CreateInstallationToken returned error: %v", err)
   417  	}
   418  
   419  	want := &InstallationToken{Token: Ptr("t")}
   420  	if !cmp.Equal(token, want) {
   421  		t.Errorf("Apps.CreateInstallationToken returned %+v, want %+v", token, want)
   422  	}
   423  
   424  	const methodName = "CreateInstallationToken"
   425  	testBadOptions(t, methodName, func() (err error) {
   426  		_, _, err = client.Apps.CreateInstallationToken(ctx, -1, nil)
   427  		return err
   428  	})
   429  
   430  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   431  		got, resp, err := client.Apps.CreateInstallationToken(ctx, 1, nil)
   432  		if got != nil {
   433  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   434  		}
   435  		return resp, err
   436  	})
   437  }
   438  
   439  func TestAppsService_CreateInstallationTokenWithOptions(t *testing.T) {
   440  	t.Parallel()
   441  	client, mux, _ := setup(t)
   442  
   443  	installationTokenOptions := &InstallationTokenOptions{
   444  		RepositoryIDs: []int64{1234},
   445  		Repositories:  []string{"foo"},
   446  		Permissions: &InstallationPermissions{
   447  			Contents: Ptr("write"),
   448  			Issues:   Ptr("read"),
   449  		},
   450  	}
   451  
   452  	mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
   453  		v := new(InstallationTokenOptions)
   454  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   455  
   456  		if !cmp.Equal(v, installationTokenOptions) {
   457  			t.Errorf("request sent %+v, want %+v", v, installationTokenOptions)
   458  		}
   459  
   460  		testMethod(t, r, "POST")
   461  		fmt.Fprint(w, `{"token":"t"}`)
   462  	})
   463  
   464  	ctx := context.Background()
   465  	token, _, err := client.Apps.CreateInstallationToken(ctx, 1, installationTokenOptions)
   466  	if err != nil {
   467  		t.Errorf("Apps.CreateInstallationToken returned error: %v", err)
   468  	}
   469  
   470  	want := &InstallationToken{Token: Ptr("t")}
   471  	if !cmp.Equal(token, want) {
   472  		t.Errorf("Apps.CreateInstallationToken returned %+v, want %+v", token, want)
   473  	}
   474  }
   475  
   476  func TestAppsService_CreateInstallationTokenListReposWithOptions(t *testing.T) {
   477  	t.Parallel()
   478  	client, mux, _ := setup(t)
   479  
   480  	installationTokenListRepoOptions := &InstallationTokenListRepoOptions{
   481  		Repositories: []string{"foo"},
   482  		Permissions: &InstallationPermissions{
   483  			Contents: Ptr("write"),
   484  			Issues:   Ptr("read"),
   485  		},
   486  	}
   487  
   488  	mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
   489  		v := new(InstallationTokenListRepoOptions)
   490  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   491  
   492  		if !cmp.Equal(v, installationTokenListRepoOptions) {
   493  			t.Errorf("request sent %+v, want %+v", v, installationTokenListRepoOptions)
   494  		}
   495  
   496  		testMethod(t, r, "POST")
   497  		fmt.Fprint(w, `{"token":"t"}`)
   498  	})
   499  
   500  	ctx := context.Background()
   501  	token, _, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, installationTokenListRepoOptions)
   502  	if err != nil {
   503  		t.Errorf("Apps.CreateInstallationTokenListRepos returned error: %v", err)
   504  	}
   505  
   506  	want := &InstallationToken{Token: Ptr("t")}
   507  	if !cmp.Equal(token, want) {
   508  		t.Errorf("Apps.CreateInstallationTokenListRepos returned %+v, want %+v", token, want)
   509  	}
   510  }
   511  
   512  func TestAppsService_CreateInstallationTokenListReposWithNoOptions(t *testing.T) {
   513  	t.Parallel()
   514  	client, mux, _ := setup(t)
   515  
   516  	mux.HandleFunc("/app/installations/1/access_tokens", func(w http.ResponseWriter, r *http.Request) {
   517  		testMethod(t, r, "POST")
   518  		fmt.Fprint(w, `{"token":"t"}`)
   519  	})
   520  
   521  	ctx := context.Background()
   522  	token, _, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, nil)
   523  	if err != nil {
   524  		t.Errorf("Apps.CreateInstallationTokenListRepos returned error: %v", err)
   525  	}
   526  
   527  	want := &InstallationToken{Token: Ptr("t")}
   528  	if !cmp.Equal(token, want) {
   529  		t.Errorf("Apps.CreateInstallationTokenListRepos returned %+v, want %+v", token, want)
   530  	}
   531  
   532  	const methodName = "CreateInstallationTokenListRepos"
   533  	testBadOptions(t, methodName, func() (err error) {
   534  		_, _, err = client.Apps.CreateInstallationTokenListRepos(ctx, -1, nil)
   535  		return err
   536  	})
   537  
   538  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   539  		got, resp, err := client.Apps.CreateInstallationTokenListRepos(ctx, 1, nil)
   540  		if got != nil {
   541  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   542  		}
   543  		return resp, err
   544  	})
   545  }
   546  
   547  func TestAppsService_CreateAttachment(t *testing.T) {
   548  	t.Parallel()
   549  	client, mux, _ := setup(t)
   550  
   551  	mux.HandleFunc("/content_references/11/attachments", func(w http.ResponseWriter, r *http.Request) {
   552  		testMethod(t, r, "POST")
   553  		testHeader(t, r, "Accept", mediaTypeContentAttachmentsPreview)
   554  
   555  		w.WriteHeader(http.StatusOK)
   556  		assertWrite(t, w, []byte(`{"id":1,"title":"title1","body":"body1"}`))
   557  	})
   558  
   559  	ctx := context.Background()
   560  	got, _, err := client.Apps.CreateAttachment(ctx, 11, "title1", "body1")
   561  	if err != nil {
   562  		t.Errorf("CreateAttachment returned error: %v", err)
   563  	}
   564  
   565  	want := &Attachment{ID: Ptr(int64(1)), Title: Ptr("title1"), Body: Ptr("body1")}
   566  	if !cmp.Equal(got, want) {
   567  		t.Errorf("CreateAttachment = %+v, want %+v", got, want)
   568  	}
   569  
   570  	const methodName = "CreateAttachment"
   571  	testBadOptions(t, methodName, func() (err error) {
   572  		_, _, err = client.Apps.CreateAttachment(ctx, -11, "\n", "\n")
   573  		return err
   574  	})
   575  
   576  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   577  		got, resp, err := client.Apps.CreateAttachment(ctx, 11, "title1", "body1")
   578  		if got != nil {
   579  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   580  		}
   581  		return resp, err
   582  	})
   583  }
   584  
   585  func TestAppsService_FindOrganizationInstallation(t *testing.T) {
   586  	t.Parallel()
   587  	client, mux, _ := setup(t)
   588  
   589  	mux.HandleFunc("/orgs/o/installation", func(w http.ResponseWriter, r *http.Request) {
   590  		testMethod(t, r, "GET")
   591  		fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`)
   592  	})
   593  
   594  	ctx := context.Background()
   595  	installation, _, err := client.Apps.FindOrganizationInstallation(ctx, "o")
   596  	if err != nil {
   597  		t.Errorf("Apps.FindOrganizationInstallation returned error: %v", err)
   598  	}
   599  
   600  	want := &Installation{ID: Ptr(int64(1)), AppID: Ptr(int64(1)), TargetID: Ptr(int64(1)), TargetType: Ptr("Organization")}
   601  	if !cmp.Equal(installation, want) {
   602  		t.Errorf("Apps.FindOrganizationInstallation returned %+v, want %+v", installation, want)
   603  	}
   604  
   605  	const methodName = "FindOrganizationInstallation"
   606  	testBadOptions(t, methodName, func() (err error) {
   607  		_, _, err = client.Apps.FindOrganizationInstallation(ctx, "\n")
   608  		return err
   609  	})
   610  
   611  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   612  		got, resp, err := client.Apps.FindOrganizationInstallation(ctx, "o")
   613  		if got != nil {
   614  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   615  		}
   616  		return resp, err
   617  	})
   618  }
   619  
   620  func TestAppsService_FindRepositoryInstallation(t *testing.T) {
   621  	t.Parallel()
   622  	client, mux, _ := setup(t)
   623  
   624  	mux.HandleFunc("/repos/o/r/installation", func(w http.ResponseWriter, r *http.Request) {
   625  		testMethod(t, r, "GET")
   626  		fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`)
   627  	})
   628  
   629  	ctx := context.Background()
   630  	installation, _, err := client.Apps.FindRepositoryInstallation(ctx, "o", "r")
   631  	if err != nil {
   632  		t.Errorf("Apps.FindRepositoryInstallation returned error: %v", err)
   633  	}
   634  
   635  	want := &Installation{ID: Ptr(int64(1)), AppID: Ptr(int64(1)), TargetID: Ptr(int64(1)), TargetType: Ptr("Organization")}
   636  	if !cmp.Equal(installation, want) {
   637  		t.Errorf("Apps.FindRepositoryInstallation returned %+v, want %+v", installation, want)
   638  	}
   639  
   640  	const methodName = "FindRepositoryInstallation"
   641  	testBadOptions(t, methodName, func() (err error) {
   642  		_, _, err = client.Apps.FindRepositoryInstallation(ctx, "\n", "\n")
   643  		return err
   644  	})
   645  
   646  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   647  		got, resp, err := client.Apps.FindRepositoryInstallation(ctx, "o", "r")
   648  		if got != nil {
   649  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   650  		}
   651  		return resp, err
   652  	})
   653  }
   654  
   655  func TestAppsService_FindRepositoryInstallationByID(t *testing.T) {
   656  	t.Parallel()
   657  	client, mux, _ := setup(t)
   658  
   659  	mux.HandleFunc("/repositories/1/installation", func(w http.ResponseWriter, r *http.Request) {
   660  		testMethod(t, r, "GET")
   661  		fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "Organization"}`)
   662  	})
   663  
   664  	ctx := context.Background()
   665  	installation, _, err := client.Apps.FindRepositoryInstallationByID(ctx, 1)
   666  	if err != nil {
   667  		t.Errorf("Apps.FindRepositoryInstallationByID returned error: %v", err)
   668  	}
   669  
   670  	want := &Installation{ID: Ptr(int64(1)), AppID: Ptr(int64(1)), TargetID: Ptr(int64(1)), TargetType: Ptr("Organization")}
   671  	if !cmp.Equal(installation, want) {
   672  		t.Errorf("Apps.FindRepositoryInstallationByID returned %+v, want %+v", installation, want)
   673  	}
   674  
   675  	const methodName = "FindRepositoryInstallationByID"
   676  	testBadOptions(t, methodName, func() (err error) {
   677  		_, _, err = client.Apps.FindRepositoryInstallationByID(ctx, -1)
   678  		return err
   679  	})
   680  
   681  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   682  		got, resp, err := client.Apps.FindRepositoryInstallationByID(ctx, 1)
   683  		if got != nil {
   684  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   685  		}
   686  		return resp, err
   687  	})
   688  }
   689  
   690  func TestAppsService_FindUserInstallation(t *testing.T) {
   691  	t.Parallel()
   692  	client, mux, _ := setup(t)
   693  
   694  	mux.HandleFunc("/users/u/installation", func(w http.ResponseWriter, r *http.Request) {
   695  		testMethod(t, r, "GET")
   696  		fmt.Fprint(w, `{"id":1, "app_id":1, "target_id":1, "target_type": "User"}`)
   697  	})
   698  
   699  	ctx := context.Background()
   700  	installation, _, err := client.Apps.FindUserInstallation(ctx, "u")
   701  	if err != nil {
   702  		t.Errorf("Apps.FindUserInstallation returned error: %v", err)
   703  	}
   704  
   705  	want := &Installation{ID: Ptr(int64(1)), AppID: Ptr(int64(1)), TargetID: Ptr(int64(1)), TargetType: Ptr("User")}
   706  	if !cmp.Equal(installation, want) {
   707  		t.Errorf("Apps.FindUserInstallation returned %+v, want %+v", installation, want)
   708  	}
   709  
   710  	const methodName = "FindUserInstallation"
   711  	testBadOptions(t, methodName, func() (err error) {
   712  		_, _, err = client.Apps.FindUserInstallation(ctx, "\n")
   713  		return err
   714  	})
   715  
   716  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   717  		got, resp, err := client.Apps.FindUserInstallation(ctx, "u")
   718  		if got != nil {
   719  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   720  		}
   721  		return resp, err
   722  	})
   723  }
   724  
   725  func TestContentReference_Marshal(t *testing.T) {
   726  	t.Parallel()
   727  	testJSONMarshal(t, &ContentReference{}, "{}")
   728  
   729  	u := &ContentReference{
   730  		ID:        Ptr(int64(1)),
   731  		NodeID:    Ptr("nid"),
   732  		Reference: Ptr("r"),
   733  	}
   734  
   735  	want := `{
   736  		"id": 1,
   737  		"node_id": "nid",
   738  		"reference": "r"
   739  	}`
   740  
   741  	testJSONMarshal(t, u, want)
   742  }
   743  
   744  func TestAttachment_Marshal(t *testing.T) {
   745  	t.Parallel()
   746  	testJSONMarshal(t, &Attachment{}, "{}")
   747  
   748  	u := &Attachment{
   749  		ID:    Ptr(int64(1)),
   750  		Title: Ptr("t"),
   751  		Body:  Ptr("b"),
   752  	}
   753  
   754  	want := `{
   755  		"id": 1,
   756  		"title": "t",
   757  		"body": "b"
   758  	}`
   759  
   760  	testJSONMarshal(t, u, want)
   761  }
   762  
   763  func TestInstallationPermissions_Marshal(t *testing.T) {
   764  	t.Parallel()
   765  	testJSONMarshal(t, &InstallationPermissions{}, "{}")
   766  
   767  	u := &InstallationPermissions{
   768  		Actions:                       Ptr("a"),
   769  		Administration:                Ptr("ad"),
   770  		Checks:                        Ptr("c"),
   771  		Contents:                      Ptr("co"),
   772  		ContentReferences:             Ptr("cr"),
   773  		Deployments:                   Ptr("d"),
   774  		Environments:                  Ptr("e"),
   775  		Issues:                        Ptr("i"),
   776  		Metadata:                      Ptr("md"),
   777  		Members:                       Ptr("m"),
   778  		OrganizationAdministration:    Ptr("oa"),
   779  		OrganizationCustomOrgRoles:    Ptr("ocr"),
   780  		OrganizationHooks:             Ptr("oh"),
   781  		OrganizationPlan:              Ptr("op"),
   782  		OrganizationPreReceiveHooks:   Ptr("opr"),
   783  		OrganizationProjects:          Ptr("op"),
   784  		OrganizationSecrets:           Ptr("os"),
   785  		OrganizationSelfHostedRunners: Ptr("osh"),
   786  		OrganizationUserBlocking:      Ptr("oub"),
   787  		Packages:                      Ptr("pkg"),
   788  		Pages:                         Ptr("pg"),
   789  		PullRequests:                  Ptr("pr"),
   790  		RepositoryHooks:               Ptr("rh"),
   791  		RepositoryProjects:            Ptr("rp"),
   792  		RepositoryPreReceiveHooks:     Ptr("rprh"),
   793  		Secrets:                       Ptr("s"),
   794  		SecretScanningAlerts:          Ptr("ssa"),
   795  		SecurityEvents:                Ptr("se"),
   796  		SingleFile:                    Ptr("sf"),
   797  		Statuses:                      Ptr("s"),
   798  		TeamDiscussions:               Ptr("td"),
   799  		VulnerabilityAlerts:           Ptr("va"),
   800  		Workflows:                     Ptr("w"),
   801  	}
   802  
   803  	want := `{
   804  		"actions": "a",
   805  		"administration": "ad",
   806  		"checks": "c",
   807  		"contents": "co",
   808  		"content_references": "cr",
   809  		"deployments": "d",
   810  		"environments": "e",
   811  		"issues": "i",
   812  		"metadata": "md",
   813  		"members": "m",
   814  		"organization_administration": "oa",
   815  		"organization_custom_org_roles": "ocr",
   816  		"organization_hooks": "oh",
   817  		"organization_plan": "op",
   818  		"organization_pre_receive_hooks": "opr",
   819  		"organization_projects": "op",
   820  		"organization_secrets": "os",
   821  		"organization_self_hosted_runners": "osh",
   822  		"organization_user_blocking": "oub",
   823  		"packages": "pkg",
   824  		"pages": "pg",
   825  		"pull_requests": "pr",
   826  		"repository_hooks": "rh",
   827  		"repository_projects": "rp",
   828  		"repository_pre_receive_hooks": "rprh",
   829  		"secrets": "s",
   830  		"secret_scanning_alerts": "ssa",
   831  		"security_events": "se",
   832  		"single_file": "sf",
   833  		"statuses": "s",
   834  		"team_discussions": "td",
   835  		"vulnerability_alerts":"va",
   836  		"workflows": "w"
   837  	}`
   838  
   839  	testJSONMarshal(t, u, want)
   840  }
   841  
   842  func TestInstallation_Marshal(t *testing.T) {
   843  	t.Parallel()
   844  	testJSONMarshal(t, &Installation{}, "{}")
   845  
   846  	u := &Installation{
   847  		ID:       Ptr(int64(1)),
   848  		NodeID:   Ptr("nid"),
   849  		AppID:    Ptr(int64(1)),
   850  		AppSlug:  Ptr("as"),
   851  		TargetID: Ptr(int64(1)),
   852  		Account: &User{
   853  			Login:           Ptr("l"),
   854  			ID:              Ptr(int64(1)),
   855  			URL:             Ptr("u"),
   856  			AvatarURL:       Ptr("a"),
   857  			GravatarID:      Ptr("g"),
   858  			Name:            Ptr("n"),
   859  			Company:         Ptr("c"),
   860  			Blog:            Ptr("b"),
   861  			Location:        Ptr("l"),
   862  			Email:           Ptr("e"),
   863  			Hireable:        Ptr(true),
   864  			Bio:             Ptr("b"),
   865  			TwitterUsername: Ptr("t"),
   866  			PublicRepos:     Ptr(1),
   867  			Followers:       Ptr(1),
   868  			Following:       Ptr(1),
   869  			CreatedAt:       &Timestamp{referenceTime},
   870  			SuspendedAt:     &Timestamp{referenceTime},
   871  		},
   872  		AccessTokensURL:     Ptr("atu"),
   873  		RepositoriesURL:     Ptr("ru"),
   874  		HTMLURL:             Ptr("hu"),
   875  		TargetType:          Ptr("tt"),
   876  		SingleFileName:      Ptr("sfn"),
   877  		RepositorySelection: Ptr("rs"),
   878  		Events:              []string{"e"},
   879  		SingleFilePaths:     []string{"s"},
   880  		Permissions: &InstallationPermissions{
   881  			Actions:                       Ptr("a"),
   882  			ActionsVariables:              Ptr("ac"),
   883  			Administration:                Ptr("ad"),
   884  			Checks:                        Ptr("c"),
   885  			Contents:                      Ptr("co"),
   886  			ContentReferences:             Ptr("cr"),
   887  			Deployments:                   Ptr("d"),
   888  			Environments:                  Ptr("e"),
   889  			Issues:                        Ptr("i"),
   890  			Metadata:                      Ptr("md"),
   891  			Members:                       Ptr("m"),
   892  			OrganizationAdministration:    Ptr("oa"),
   893  			OrganizationCustomOrgRoles:    Ptr("ocr"),
   894  			OrganizationHooks:             Ptr("oh"),
   895  			OrganizationPlan:              Ptr("op"),
   896  			OrganizationPreReceiveHooks:   Ptr("opr"),
   897  			OrganizationProjects:          Ptr("op"),
   898  			OrganizationSecrets:           Ptr("os"),
   899  			OrganizationSelfHostedRunners: Ptr("osh"),
   900  			OrganizationUserBlocking:      Ptr("oub"),
   901  			Packages:                      Ptr("pkg"),
   902  			Pages:                         Ptr("pg"),
   903  			PullRequests:                  Ptr("pr"),
   904  			RepositoryHooks:               Ptr("rh"),
   905  			RepositoryProjects:            Ptr("rp"),
   906  			RepositoryPreReceiveHooks:     Ptr("rprh"),
   907  			Secrets:                       Ptr("s"),
   908  			SecretScanningAlerts:          Ptr("ssa"),
   909  			SecurityEvents:                Ptr("se"),
   910  			SingleFile:                    Ptr("sf"),
   911  			Statuses:                      Ptr("s"),
   912  			TeamDiscussions:               Ptr("td"),
   913  			VulnerabilityAlerts:           Ptr("va"),
   914  			Workflows:                     Ptr("w"),
   915  		},
   916  		CreatedAt:              &Timestamp{referenceTime},
   917  		UpdatedAt:              &Timestamp{referenceTime},
   918  		HasMultipleSingleFiles: Ptr(false),
   919  		SuspendedBy: &User{
   920  			Login:           Ptr("l"),
   921  			ID:              Ptr(int64(1)),
   922  			URL:             Ptr("u"),
   923  			AvatarURL:       Ptr("a"),
   924  			GravatarID:      Ptr("g"),
   925  			Name:            Ptr("n"),
   926  			Company:         Ptr("c"),
   927  			Blog:            Ptr("b"),
   928  			Location:        Ptr("l"),
   929  			Email:           Ptr("e"),
   930  			Hireable:        Ptr(true),
   931  			Bio:             Ptr("b"),
   932  			TwitterUsername: Ptr("t"),
   933  			PublicRepos:     Ptr(1),
   934  			Followers:       Ptr(1),
   935  			Following:       Ptr(1),
   936  			CreatedAt:       &Timestamp{referenceTime},
   937  			SuspendedAt:     &Timestamp{referenceTime},
   938  		},
   939  		SuspendedAt: &Timestamp{referenceTime},
   940  	}
   941  
   942  	want := `{
   943  		"id": 1,
   944  		"node_id": "nid",
   945  		"app_id": 1,
   946  		"app_slug": "as",
   947  		"target_id": 1,
   948  		"account": {
   949  			"login": "l",
   950  			"id": 1,
   951  			"avatar_url": "a",
   952  			"gravatar_id": "g",
   953  			"name": "n",
   954  			"company": "c",
   955  			"blog": "b",
   956  			"location": "l",
   957  			"email": "e",
   958  			"hireable": true,
   959  			"bio": "b",
   960  			"twitter_username": "t",
   961  			"public_repos": 1,
   962  			"followers": 1,
   963  			"following": 1,
   964  			"created_at": ` + referenceTimeStr + `,
   965  			"suspended_at": ` + referenceTimeStr + `,
   966  			"url": "u"
   967  		},
   968  		"access_tokens_url": "atu",
   969  		"repositories_url": "ru",
   970  		"html_url": "hu",
   971  		"target_type": "tt",
   972  		"single_file_name": "sfn",
   973  		"repository_selection": "rs",
   974  		"events": [
   975  			"e"
   976  		],
   977  		"single_file_paths": [
   978  			"s"
   979  		],
   980  		"permissions": {
   981  			"actions": "a",
   982  			"actions_variables": "ac",
   983  			"administration": "ad",
   984  			"checks": "c",
   985  			"contents": "co",
   986  			"content_references": "cr",
   987  			"deployments": "d",
   988  			"environments": "e",
   989  			"issues": "i",
   990  			"metadata": "md",
   991  			"members": "m",
   992  			"organization_administration": "oa",
   993  			"organization_custom_org_roles": "ocr",
   994  			"organization_hooks": "oh",
   995  			"organization_plan": "op",
   996  			"organization_pre_receive_hooks": "opr",
   997  			"organization_projects": "op",
   998  			"organization_secrets": "os",
   999  			"organization_self_hosted_runners": "osh",
  1000  			"organization_user_blocking": "oub",
  1001  			"packages": "pkg",
  1002  			"pages": "pg",
  1003  			"pull_requests": "pr",
  1004  			"repository_hooks": "rh",
  1005  			"repository_projects": "rp",
  1006  			"repository_pre_receive_hooks": "rprh",
  1007  			"secrets": "s",
  1008  			"secret_scanning_alerts": "ssa",
  1009  			"security_events": "se",
  1010  			"single_file": "sf",
  1011  			"statuses": "s",
  1012  			"team_discussions": "td",
  1013  			"vulnerability_alerts": "va",
  1014  			"workflows": "w"
  1015  		},
  1016  		"created_at": ` + referenceTimeStr + `,
  1017  		"updated_at": ` + referenceTimeStr + `,
  1018  		"has_multiple_single_files": false,
  1019  		"suspended_by": {
  1020  			"login": "l",
  1021  			"id": 1,
  1022  			"avatar_url": "a",
  1023  			"gravatar_id": "g",
  1024  			"name": "n",
  1025  			"company": "c",
  1026  			"blog": "b",
  1027  			"location": "l",
  1028  			"email": "e",
  1029  			"hireable": true,
  1030  			"bio": "b",
  1031  			"twitter_username": "t",
  1032  			"public_repos": 1,
  1033  			"followers": 1,
  1034  			"following": 1,
  1035  			"created_at": ` + referenceTimeStr + `,
  1036  			"suspended_at": ` + referenceTimeStr + `,
  1037  			"url": "u"
  1038  		},
  1039  		"suspended_at": ` + referenceTimeStr + `
  1040  	}`
  1041  
  1042  	testJSONMarshal(t, u, want)
  1043  }
  1044  
  1045  func TestInstallationTokenOptions_Marshal(t *testing.T) {
  1046  	t.Parallel()
  1047  	testJSONMarshal(t, &InstallationTokenOptions{}, "{}")
  1048  
  1049  	u := &InstallationTokenOptions{
  1050  		RepositoryIDs: []int64{1},
  1051  		Permissions: &InstallationPermissions{
  1052  			Actions:                       Ptr("a"),
  1053  			ActionsVariables:              Ptr("ac"),
  1054  			Administration:                Ptr("ad"),
  1055  			Checks:                        Ptr("c"),
  1056  			Contents:                      Ptr("co"),
  1057  			ContentReferences:             Ptr("cr"),
  1058  			Deployments:                   Ptr("d"),
  1059  			Environments:                  Ptr("e"),
  1060  			Issues:                        Ptr("i"),
  1061  			Metadata:                      Ptr("md"),
  1062  			Members:                       Ptr("m"),
  1063  			OrganizationAdministration:    Ptr("oa"),
  1064  			OrganizationCustomOrgRoles:    Ptr("ocr"),
  1065  			OrganizationHooks:             Ptr("oh"),
  1066  			OrganizationPlan:              Ptr("op"),
  1067  			OrganizationPreReceiveHooks:   Ptr("opr"),
  1068  			OrganizationProjects:          Ptr("op"),
  1069  			OrganizationSecrets:           Ptr("os"),
  1070  			OrganizationSelfHostedRunners: Ptr("osh"),
  1071  			OrganizationUserBlocking:      Ptr("oub"),
  1072  			Packages:                      Ptr("pkg"),
  1073  			Pages:                         Ptr("pg"),
  1074  			PullRequests:                  Ptr("pr"),
  1075  			RepositoryHooks:               Ptr("rh"),
  1076  			RepositoryProjects:            Ptr("rp"),
  1077  			RepositoryPreReceiveHooks:     Ptr("rprh"),
  1078  			Secrets:                       Ptr("s"),
  1079  			SecretScanningAlerts:          Ptr("ssa"),
  1080  			SecurityEvents:                Ptr("se"),
  1081  			SingleFile:                    Ptr("sf"),
  1082  			Statuses:                      Ptr("s"),
  1083  			TeamDiscussions:               Ptr("td"),
  1084  			VulnerabilityAlerts:           Ptr("va"),
  1085  			Workflows:                     Ptr("w"),
  1086  		},
  1087  	}
  1088  
  1089  	want := `{
  1090  		"repository_ids": [1],
  1091  		"permissions": {
  1092  			"actions": "a",
  1093  			"actions_variables": "ac",
  1094  			"administration": "ad",
  1095  			"checks": "c",
  1096  			"contents": "co",
  1097  			"content_references": "cr",
  1098  			"deployments": "d",
  1099  			"environments": "e",
  1100  			"issues": "i",
  1101  			"metadata": "md",
  1102  			"members": "m",
  1103  			"organization_administration": "oa",
  1104  			"organization_custom_org_roles": "ocr",
  1105  			"organization_hooks": "oh",
  1106  			"organization_plan": "op",
  1107  			"organization_pre_receive_hooks": "opr",
  1108  			"organization_projects": "op",
  1109  			"organization_secrets": "os",
  1110  			"organization_self_hosted_runners": "osh",
  1111  			"organization_user_blocking": "oub",
  1112  			"packages": "pkg",
  1113  			"pages": "pg",
  1114  			"pull_requests": "pr",
  1115  			"repository_hooks": "rh",
  1116  			"repository_projects": "rp",
  1117  			"repository_pre_receive_hooks": "rprh",
  1118  			"secrets": "s",
  1119  			"secret_scanning_alerts": "ssa",
  1120  			"security_events": "se",
  1121  			"single_file": "sf",
  1122  			"statuses": "s",
  1123  			"team_discussions": "td",
  1124  			"vulnerability_alerts": "va",
  1125  			"workflows": "w"
  1126  		}
  1127  	}`
  1128  
  1129  	testJSONMarshal(t, u, want)
  1130  }
  1131  
  1132  func TestInstallationToken_Marshal(t *testing.T) {
  1133  	t.Parallel()
  1134  	testJSONMarshal(t, &InstallationToken{}, "{}")
  1135  
  1136  	u := &InstallationToken{
  1137  		Token:     Ptr("t"),
  1138  		ExpiresAt: &Timestamp{referenceTime},
  1139  		Permissions: &InstallationPermissions{
  1140  			Actions:                       Ptr("a"),
  1141  			ActionsVariables:              Ptr("ac"),
  1142  			Administration:                Ptr("ad"),
  1143  			Checks:                        Ptr("c"),
  1144  			Contents:                      Ptr("co"),
  1145  			ContentReferences:             Ptr("cr"),
  1146  			Deployments:                   Ptr("d"),
  1147  			Environments:                  Ptr("e"),
  1148  			Issues:                        Ptr("i"),
  1149  			Metadata:                      Ptr("md"),
  1150  			Members:                       Ptr("m"),
  1151  			OrganizationAdministration:    Ptr("oa"),
  1152  			OrganizationCustomOrgRoles:    Ptr("ocr"),
  1153  			OrganizationHooks:             Ptr("oh"),
  1154  			OrganizationPlan:              Ptr("op"),
  1155  			OrganizationPreReceiveHooks:   Ptr("opr"),
  1156  			OrganizationProjects:          Ptr("op"),
  1157  			OrganizationSecrets:           Ptr("os"),
  1158  			OrganizationSelfHostedRunners: Ptr("osh"),
  1159  			OrganizationUserBlocking:      Ptr("oub"),
  1160  			Packages:                      Ptr("pkg"),
  1161  			Pages:                         Ptr("pg"),
  1162  			PullRequests:                  Ptr("pr"),
  1163  			RepositoryHooks:               Ptr("rh"),
  1164  			RepositoryProjects:            Ptr("rp"),
  1165  			RepositoryPreReceiveHooks:     Ptr("rprh"),
  1166  			Secrets:                       Ptr("s"),
  1167  			SecretScanningAlerts:          Ptr("ssa"),
  1168  			SecurityEvents:                Ptr("se"),
  1169  			SingleFile:                    Ptr("sf"),
  1170  			Statuses:                      Ptr("s"),
  1171  			TeamDiscussions:               Ptr("td"),
  1172  			VulnerabilityAlerts:           Ptr("va"),
  1173  			Workflows:                     Ptr("w"),
  1174  		},
  1175  		Repositories: []*Repository{
  1176  			{
  1177  				ID:   Ptr(int64(1)),
  1178  				URL:  Ptr("u"),
  1179  				Name: Ptr("n"),
  1180  			},
  1181  		},
  1182  	}
  1183  
  1184  	want := `{
  1185  		"token": "t",
  1186  		"expires_at": ` + referenceTimeStr + `,
  1187  		"permissions": {
  1188  			"actions": "a",
  1189  			"actions_variables": "ac",
  1190  			"administration": "ad",
  1191  			"checks": "c",
  1192  			"contents": "co",
  1193  			"content_references": "cr",
  1194  			"deployments": "d",
  1195  			"environments": "e",
  1196  			"issues": "i",
  1197  			"metadata": "md",
  1198  			"members": "m",
  1199  			"organization_administration": "oa",
  1200  			"organization_custom_org_roles": "ocr",
  1201  			"organization_hooks": "oh",
  1202  			"organization_plan": "op",
  1203  			"organization_pre_receive_hooks": "opr",
  1204  			"organization_projects": "op",
  1205  			"organization_secrets": "os",
  1206  			"organization_self_hosted_runners": "osh",
  1207  			"organization_user_blocking": "oub",
  1208  			"packages": "pkg",
  1209  			"pages": "pg",
  1210  			"pull_requests": "pr",
  1211  			"repository_hooks": "rh",
  1212  			"repository_projects": "rp",
  1213  			"repository_pre_receive_hooks": "rprh",
  1214  			"secrets": "s",
  1215  			"secret_scanning_alerts": "ssa",
  1216  			"security_events": "se",
  1217  			"single_file": "sf",
  1218  			"statuses": "s",
  1219  			"team_discussions": "td",
  1220  			"vulnerability_alerts": "va",
  1221  			"workflows": "w"
  1222  		},
  1223  		"repositories": [
  1224  			{
  1225  				"id": 1,
  1226  				"url": "u",
  1227  				"name": "n"
  1228  			}
  1229  		]
  1230  	}`
  1231  
  1232  	testJSONMarshal(t, u, want)
  1233  }
  1234  
  1235  func TestApp_Marshal(t *testing.T) {
  1236  	t.Parallel()
  1237  	testJSONMarshal(t, &App{}, "{}")
  1238  
  1239  	u := &App{
  1240  		ID:     Ptr(int64(1)),
  1241  		Slug:   Ptr("s"),
  1242  		NodeID: Ptr("nid"),
  1243  		Owner: &User{
  1244  			Login:           Ptr("l"),
  1245  			ID:              Ptr(int64(1)),
  1246  			URL:             Ptr("u"),
  1247  			AvatarURL:       Ptr("a"),
  1248  			GravatarID:      Ptr("g"),
  1249  			Name:            Ptr("n"),
  1250  			Company:         Ptr("c"),
  1251  			Blog:            Ptr("b"),
  1252  			Location:        Ptr("l"),
  1253  			Email:           Ptr("e"),
  1254  			Hireable:        Ptr(true),
  1255  			Bio:             Ptr("b"),
  1256  			TwitterUsername: Ptr("t"),
  1257  			PublicRepos:     Ptr(1),
  1258  			Followers:       Ptr(1),
  1259  			Following:       Ptr(1),
  1260  			CreatedAt:       &Timestamp{referenceTime},
  1261  			SuspendedAt:     &Timestamp{referenceTime},
  1262  		},
  1263  		Name:        Ptr("n"),
  1264  		Description: Ptr("d"),
  1265  		ExternalURL: Ptr("eu"),
  1266  		HTMLURL:     Ptr("hu"),
  1267  		CreatedAt:   &Timestamp{referenceTime},
  1268  		UpdatedAt:   &Timestamp{referenceTime},
  1269  		Permissions: &InstallationPermissions{
  1270  			Actions:                       Ptr("a"),
  1271  			ActionsVariables:              Ptr("ac"),
  1272  			Administration:                Ptr("ad"),
  1273  			Checks:                        Ptr("c"),
  1274  			Contents:                      Ptr("co"),
  1275  			ContentReferences:             Ptr("cr"),
  1276  			Deployments:                   Ptr("d"),
  1277  			Environments:                  Ptr("e"),
  1278  			Issues:                        Ptr("i"),
  1279  			Metadata:                      Ptr("md"),
  1280  			Members:                       Ptr("m"),
  1281  			OrganizationAdministration:    Ptr("oa"),
  1282  			OrganizationCustomOrgRoles:    Ptr("ocr"),
  1283  			OrganizationHooks:             Ptr("oh"),
  1284  			OrganizationPlan:              Ptr("op"),
  1285  			OrganizationPreReceiveHooks:   Ptr("opr"),
  1286  			OrganizationProjects:          Ptr("op"),
  1287  			OrganizationSecrets:           Ptr("os"),
  1288  			OrganizationSelfHostedRunners: Ptr("osh"),
  1289  			OrganizationUserBlocking:      Ptr("oub"),
  1290  			Packages:                      Ptr("pkg"),
  1291  			Pages:                         Ptr("pg"),
  1292  			PullRequests:                  Ptr("pr"),
  1293  			RepositoryHooks:               Ptr("rh"),
  1294  			RepositoryProjects:            Ptr("rp"),
  1295  			RepositoryPreReceiveHooks:     Ptr("rprh"),
  1296  			Secrets:                       Ptr("s"),
  1297  			SecretScanningAlerts:          Ptr("ssa"),
  1298  			SecurityEvents:                Ptr("se"),
  1299  			SingleFile:                    Ptr("sf"),
  1300  			Statuses:                      Ptr("s"),
  1301  			TeamDiscussions:               Ptr("td"),
  1302  			VulnerabilityAlerts:           Ptr("va"),
  1303  			Workflows:                     Ptr("w"),
  1304  		},
  1305  		Events: []string{"s"},
  1306  	}
  1307  
  1308  	want := `{
  1309  		"id": 1,
  1310  		"slug": "s",
  1311  		"node_id": "nid",
  1312  		"owner": {
  1313  			"login": "l",
  1314  			"id": 1,
  1315  			"avatar_url": "a",
  1316  			"gravatar_id": "g",
  1317  			"name": "n",
  1318  			"company": "c",
  1319  			"blog": "b",
  1320  			"location": "l",
  1321  			"email": "e",
  1322  			"hireable": true,
  1323  			"bio": "b",
  1324  			"twitter_username": "t",
  1325  			"public_repos": 1,
  1326  			"followers": 1,
  1327  			"following": 1,
  1328  			"created_at": ` + referenceTimeStr + `,
  1329  			"suspended_at": ` + referenceTimeStr + `,
  1330  			"url": "u"
  1331  		},
  1332  		"name": "n",
  1333  		"description": "d",
  1334  		"external_url": "eu",
  1335  		"html_url": "hu",
  1336  		"created_at": ` + referenceTimeStr + `,
  1337  		"updated_at": ` + referenceTimeStr + `,
  1338  		"permissions": {
  1339  			"actions": "a",
  1340  			"actions_variables": "ac",
  1341  			"administration": "ad",
  1342  			"checks": "c",
  1343  			"contents": "co",
  1344  			"content_references": "cr",
  1345  			"deployments": "d",
  1346  			"environments": "e",
  1347  			"issues": "i",
  1348  			"metadata": "md",
  1349  			"members": "m",
  1350  			"organization_administration": "oa",
  1351  			"organization_custom_org_roles": "ocr",
  1352  			"organization_hooks": "oh",
  1353  			"organization_plan": "op",
  1354  			"organization_pre_receive_hooks": "opr",
  1355  			"organization_projects": "op",
  1356  			"organization_secrets": "os",
  1357  			"organization_self_hosted_runners": "osh",
  1358  			"organization_user_blocking": "oub",
  1359  			"packages": "pkg",
  1360  			"pages": "pg",
  1361  			"pull_requests": "pr",
  1362  			"repository_hooks": "rh",
  1363  			"repository_projects": "rp",
  1364  			"repository_pre_receive_hooks": "rprh",
  1365  			"secrets": "s",
  1366  			"secret_scanning_alerts": "ssa",
  1367  			"security_events": "se",
  1368  			"single_file": "sf",
  1369  			"statuses": "s",
  1370  			"team_discussions": "td",
  1371  			"vulnerability_alerts": "va",
  1372  			"workflows": "w"
  1373  		},
  1374  		"events": ["s"]
  1375  	}`
  1376  
  1377  	testJSONMarshal(t, u, want)
  1378  }