github.com/google/go-github/v71@v71.0.0/github/copilot_test.go (about)

     1  // Copyright 2023 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  	"log"
    13  	"net/http"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/google/go-cmp/cmp"
    18  )
    19  
    20  // Test invalid JSON responses, valid responses are covered in the other tests.
    21  func TestCopilotSeatDetails_UnmarshalJSON(t *testing.T) {
    22  	t.Parallel()
    23  	tests := []struct {
    24  		name    string
    25  		data    string
    26  		want    *CopilotSeatDetails
    27  		wantErr bool
    28  	}{
    29  		{
    30  			name: "Invalid JSON",
    31  			data: `{`,
    32  			want: &CopilotSeatDetails{
    33  				Assignee: nil,
    34  			},
    35  			wantErr: true,
    36  		},
    37  		{
    38  			name: "Invalid top level type",
    39  			data: `{
    40  					"assignee": {
    41  						"type": "User",
    42  						"name": "octokittens",
    43  						"id": 1
    44  					},
    45  					"assigning_team": "this should be an object"
    46  				}`,
    47  			want:    &CopilotSeatDetails{},
    48  			wantErr: true,
    49  		},
    50  		{
    51  			name: "No Type Field",
    52  			data: `{
    53  					"assignee": {
    54  						"name": "octokittens",
    55  						"id": 1
    56  					}
    57  				}`,
    58  			want:    &CopilotSeatDetails{},
    59  			wantErr: true,
    60  		},
    61  		{
    62  			name: "Invalid Assignee Field Type",
    63  			data: `{
    64  					"assignee": "test"
    65  				}`,
    66  			want:    &CopilotSeatDetails{},
    67  			wantErr: true,
    68  		},
    69  		{
    70  			name: "Invalid Assignee Type",
    71  			data: `{
    72  					"assignee": {
    73  						"name": "octokittens",
    74  						"id": 1,
    75  						"type": []
    76  					}
    77  				}`,
    78  			want:    &CopilotSeatDetails{},
    79  			wantErr: true,
    80  		},
    81  		{
    82  			name: "Invalid User",
    83  			data: `{
    84  					"assignee": {
    85  						"type": "User",
    86  						"id": "bad"
    87  					}
    88  				}`,
    89  			want:    &CopilotSeatDetails{},
    90  			wantErr: true,
    91  		},
    92  		{
    93  			name: "Invalid Team",
    94  			data: `{
    95  					"assignee": {
    96  						"type": "Team",
    97  						"id": "bad"
    98  					}
    99  				}`,
   100  			want:    &CopilotSeatDetails{},
   101  			wantErr: true,
   102  		},
   103  		{
   104  			name: "Invalid Organization",
   105  			data: `{
   106  					"assignee": {
   107  						"type": "Organization",
   108  						"id": "bad"
   109  					}
   110  				}`,
   111  			want:    &CopilotSeatDetails{},
   112  			wantErr: true,
   113  		},
   114  	}
   115  
   116  	for _, tc := range tests {
   117  		seatDetails := &CopilotSeatDetails{}
   118  
   119  		t.Run(tc.name, func(t *testing.T) {
   120  			t.Parallel()
   121  			err := json.Unmarshal([]byte(tc.data), seatDetails)
   122  			if err == nil && tc.wantErr {
   123  				t.Errorf("CopilotSeatDetails.UnmarshalJSON returned nil instead of an error")
   124  			}
   125  			if err != nil && !tc.wantErr {
   126  				t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   127  			}
   128  			if !cmp.Equal(tc.want, seatDetails) {
   129  				t.Errorf("CopilotSeatDetails.UnmarshalJSON expected %+v, got %+v", tc.want, seatDetails)
   130  			}
   131  		})
   132  	}
   133  }
   134  
   135  func TestCopilotService_GetSeatDetailsUser(t *testing.T) {
   136  	t.Parallel()
   137  	data := `{
   138  				"assignee": {
   139  					"type": "User",
   140  					"id": 1
   141  				}
   142  			}`
   143  
   144  	seatDetails := &CopilotSeatDetails{}
   145  
   146  	err := json.Unmarshal([]byte(data), seatDetails)
   147  	if err != nil {
   148  		t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   149  	}
   150  
   151  	want := &User{
   152  		ID:   Ptr(int64(1)),
   153  		Type: Ptr("User"),
   154  	}
   155  
   156  	if got, ok := seatDetails.GetUser(); ok && !cmp.Equal(got, want) {
   157  		t.Errorf("CopilotSeatDetails.GetTeam returned %+v, want %+v", got, want)
   158  	} else if !ok {
   159  		t.Errorf("CopilotSeatDetails.GetUser returned false, expected true")
   160  	}
   161  
   162  	data = `{
   163  				"assignee": {
   164  					"type": "Organization",
   165  					"id": 1
   166  				}
   167  			}`
   168  
   169  	bad := &Organization{
   170  		ID:   Ptr(int64(1)),
   171  		Type: Ptr("Organization"),
   172  	}
   173  
   174  	err = json.Unmarshal([]byte(data), seatDetails)
   175  	if err != nil {
   176  		t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   177  	}
   178  
   179  	if got, ok := seatDetails.GetUser(); ok {
   180  		t.Errorf("CopilotSeatDetails.GetUser returned true, expected false. Returned %v, expected %v", got, bad)
   181  	}
   182  }
   183  
   184  func TestCopilotService_GetSeatDetailsTeam(t *testing.T) {
   185  	t.Parallel()
   186  	data := `{
   187  				"assignee": {
   188  					"type": "Team",
   189  					"id": 1
   190  				}
   191  			}`
   192  
   193  	seatDetails := &CopilotSeatDetails{}
   194  
   195  	err := json.Unmarshal([]byte(data), seatDetails)
   196  	if err != nil {
   197  		t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   198  	}
   199  
   200  	want := &Team{
   201  		ID: Ptr(int64(1)),
   202  	}
   203  
   204  	if got, ok := seatDetails.GetTeam(); ok && !cmp.Equal(got, want) {
   205  		t.Errorf("CopilotSeatDetails.GetTeam returned %+v, want %+v", got, want)
   206  	} else if !ok {
   207  		t.Errorf("CopilotSeatDetails.GetTeam returned false, expected true")
   208  	}
   209  
   210  	data = `{
   211  				"assignee": {
   212  					"type": "User",
   213  					"id": 1
   214  				}
   215  			}`
   216  
   217  	bad := &User{
   218  		ID:   Ptr(int64(1)),
   219  		Type: Ptr("User"),
   220  	}
   221  
   222  	err = json.Unmarshal([]byte(data), seatDetails)
   223  	if err != nil {
   224  		t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   225  	}
   226  
   227  	if got, ok := seatDetails.GetTeam(); ok {
   228  		t.Errorf("CopilotSeatDetails.GetTeam returned true, expected false. Returned %v, expected %v", got, bad)
   229  	}
   230  }
   231  
   232  func TestCopilotService_GetSeatDetailsOrganization(t *testing.T) {
   233  	t.Parallel()
   234  	data := `{
   235  				"assignee": {
   236  					"type": "Organization",
   237  					"id": 1
   238  				}
   239  			}`
   240  
   241  	seatDetails := &CopilotSeatDetails{}
   242  
   243  	err := json.Unmarshal([]byte(data), seatDetails)
   244  	if err != nil {
   245  		t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   246  	}
   247  
   248  	want := &Organization{
   249  		ID:   Ptr(int64(1)),
   250  		Type: Ptr("Organization"),
   251  	}
   252  
   253  	if got, ok := seatDetails.GetOrganization(); ok && !cmp.Equal(got, want) {
   254  		t.Errorf("CopilotSeatDetails.GetOrganization returned %+v, want %+v", got, want)
   255  	} else if !ok {
   256  		t.Errorf("CopilotSeatDetails.GetOrganization returned false, expected true")
   257  	}
   258  
   259  	data = `{
   260  				"assignee": {
   261  					"type": "Team",
   262  					"id": 1
   263  				}
   264  			}`
   265  
   266  	bad := &Team{
   267  		ID: Ptr(int64(1)),
   268  	}
   269  
   270  	err = json.Unmarshal([]byte(data), seatDetails)
   271  	if err != nil {
   272  		t.Errorf("CopilotSeatDetails.UnmarshalJSON returned an unexpected error: %v", err)
   273  	}
   274  
   275  	if got, ok := seatDetails.GetOrganization(); ok {
   276  		t.Errorf("CopilotSeatDetails.GetOrganization returned true, expected false. Returned %v, expected %v", got, bad)
   277  	}
   278  }
   279  
   280  func TestCopilotService_GetCopilotBilling(t *testing.T) {
   281  	t.Parallel()
   282  	client, mux, _ := setup(t)
   283  
   284  	mux.HandleFunc("/orgs/o/copilot/billing", func(w http.ResponseWriter, r *http.Request) {
   285  		testMethod(t, r, "GET")
   286  		fmt.Fprint(w, `{
   287  			"seat_breakdown": {
   288  				"total": 12,
   289  				"added_this_cycle": 9,
   290  				"pending_invitation": 0,
   291  				"pending_cancellation": 0,
   292  				"active_this_cycle": 12,
   293  				"inactive_this_cycle": 11
   294  			},
   295  			"seat_management_setting": "assign_selected",
   296  			"public_code_suggestions": "block"
   297  			}`)
   298  	})
   299  
   300  	ctx := context.Background()
   301  	got, _, err := client.Copilot.GetCopilotBilling(ctx, "o")
   302  	if err != nil {
   303  		t.Errorf("Copilot.GetCopilotBilling returned error: %v", err)
   304  	}
   305  
   306  	want := &CopilotOrganizationDetails{
   307  		SeatBreakdown: &CopilotSeatBreakdown{
   308  			Total:               12,
   309  			AddedThisCycle:      9,
   310  			PendingInvitation:   0,
   311  			PendingCancellation: 0,
   312  			ActiveThisCycle:     12,
   313  			InactiveThisCycle:   11,
   314  		},
   315  		PublicCodeSuggestions: "block",
   316  		CopilotChat:           "",
   317  		SeatManagementSetting: "assign_selected",
   318  	}
   319  	if !cmp.Equal(got, want) {
   320  		t.Errorf("Copilot.GetCopilotBilling returned %+v, want %+v", got, want)
   321  	}
   322  
   323  	const methodName = "GetCopilotBilling"
   324  
   325  	testBadOptions(t, methodName, func() (err error) {
   326  		_, _, err = client.Copilot.GetCopilotBilling(ctx, "\n")
   327  		return err
   328  	})
   329  
   330  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   331  		got, resp, err := client.Copilot.GetCopilotBilling(ctx, "o")
   332  		if got != nil {
   333  			t.Errorf("Copilot.GetCopilotBilling returned %+v, want nil", got)
   334  		}
   335  		return resp, err
   336  	})
   337  }
   338  
   339  func TestCopilotService_ListCopilotSeats(t *testing.T) {
   340  	t.Parallel()
   341  	client, mux, _ := setup(t)
   342  
   343  	mux.HandleFunc("/orgs/o/copilot/billing/seats", func(w http.ResponseWriter, r *http.Request) {
   344  		testMethod(t, r, "GET")
   345  		testFormValues(t, r, values{
   346  			"per_page": "100",
   347  			"page":     "1",
   348  		})
   349  		fmt.Fprint(w, `{
   350  				"total_seats": 4,
   351  				"seats": [
   352  					{
   353  						"created_at": "2021-08-03T18:00:00-06:00",
   354  						"updated_at": "2021-09-23T15:00:00-06:00",
   355  						"pending_cancellation_date": null,
   356  						"last_activity_at": "2021-10-14T00:53:32-06:00",
   357  						"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
   358  						"assignee": {
   359  							"login": "octocat",
   360  							"id": 1,
   361  							"node_id": "MDQ6VXNlcjE=",
   362  							"avatar_url": "https://github.com/images/error/octocat_happy.gif",
   363  							"gravatar_id": "",
   364  							"url": "https://api.github.com/users/octocat",
   365  							"html_url": "https://github.com/octocat",
   366  							"followers_url": "https://api.github.com/users/octocat/followers",
   367  							"following_url": "https://api.github.com/users/octocat/following{/other_user}",
   368  							"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
   369  							"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
   370  							"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
   371  							"organizations_url": "https://api.github.com/users/octocat/orgs",
   372  							"repos_url": "https://api.github.com/users/octocat/repos",
   373  							"events_url": "https://api.github.com/users/octocat/events{/privacy}",
   374  							"received_events_url": "https://api.github.com/users/octocat/received_events",
   375  							"type": "User",
   376  							"site_admin": false
   377  						},
   378  						"assigning_team": {
   379  							"id": 1,
   380  							"node_id": "MDQ6VGVhbTE=",
   381  							"url": "https://api.github.com/teams/1",
   382  							"html_url": "https://github.com/orgs/github/teams/justice-league",
   383  							"name": "Justice League",
   384  							"slug": "justice-league",
   385  							"description": "A great team.",
   386  							"privacy": "closed",
   387  							"notification_setting": "notifications_enabled",
   388  							"permission": "admin",
   389  							"members_url": "https://api.github.com/teams/1/members{/member}",
   390  							"repositories_url": "https://api.github.com/teams/1/repos",
   391  							"parent": null
   392  						}
   393  					},
   394  					{
   395  						"created_at": "2021-09-23T18:00:00-06:00",
   396  						"updated_at": "2021-09-23T15:00:00-06:00",
   397  						"pending_cancellation_date": "2021-11-01",
   398  						"last_activity_at": "2021-10-13T00:53:32-06:00",
   399  						"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
   400  						"assignee": {
   401  							"login": "octokitten",
   402  							"id": 1,
   403  							"node_id": "MDQ76VNlcjE=",
   404  							"avatar_url": "https://github.com/images/error/octokitten_happy.gif",
   405  							"gravatar_id": "",
   406  							"url": "https://api.github.com/users/octokitten",
   407  							"html_url": "https://github.com/octokitten",
   408  							"followers_url": "https://api.github.com/users/octokitten/followers",
   409  							"following_url": "https://api.github.com/users/octokitten/following{/other_user}",
   410  							"gists_url": "https://api.github.com/users/octokitten/gists{/gist_id}",
   411  							"starred_url": "https://api.github.com/users/octokitten/starred{/owner}{/repo}",
   412  							"subscriptions_url": "https://api.github.com/users/octokitten/subscriptions",
   413  							"organizations_url": "https://api.github.com/users/octokitten/orgs",
   414  							"repos_url": "https://api.github.com/users/octokitten/repos",
   415  							"events_url": "https://api.github.com/users/octokitten/events{/privacy}",
   416  							"received_events_url": "https://api.github.com/users/octokitten/received_events",
   417  							"type": "User",
   418  							"site_admin": false
   419  						}
   420  					},
   421  					{
   422  						"created_at": "2021-09-23T18:00:00-06:00",
   423  						"updated_at": "2021-09-23T15:00:00-06:00",
   424  						"pending_cancellation_date": "2021-11-01",
   425  						"last_activity_at": "2021-10-13T00:53:32-06:00",
   426  						"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
   427  						"assignee": {
   428  							"name": "octokittens",
   429  							"id": 1,
   430  							"type": "Team"
   431  						}
   432  					},
   433  					{
   434  						"created_at": "2021-09-23T18:00:00-06:00",
   435  						"updated_at": "2021-09-23T15:00:00-06:00",
   436  						"pending_cancellation_date": "2021-11-01",
   437  						"last_activity_at": "2021-10-13T00:53:32-06:00",
   438  						"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
   439  						"assignee": {
   440  							"name": "octocats",
   441  							"id": 1,
   442  							"type": "Organization"
   443  						}
   444  					}
   445  				]
   446  			}`)
   447  	})
   448  
   449  	tmp, err := time.Parse(time.RFC3339, "2021-08-03T18:00:00-06:00")
   450  	if err != nil {
   451  		panic(err)
   452  	}
   453  	createdAt1 := Timestamp{tmp}
   454  
   455  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T15:00:00-06:00")
   456  	if err != nil {
   457  		panic(err)
   458  	}
   459  	updatedAt1 := Timestamp{tmp}
   460  
   461  	tmp, err = time.Parse(time.RFC3339, "2021-10-14T00:53:32-06:00")
   462  	if err != nil {
   463  		panic(err)
   464  	}
   465  	lastActivityAt1 := Timestamp{tmp}
   466  
   467  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T18:00:00-06:00")
   468  	if err != nil {
   469  		panic(err)
   470  	}
   471  	createdAt2 := Timestamp{tmp}
   472  
   473  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T15:00:00-06:00")
   474  	if err != nil {
   475  		panic(err)
   476  	}
   477  	updatedAt2 := Timestamp{tmp}
   478  
   479  	tmp, err = time.Parse(time.RFC3339, "2021-10-13T00:53:32-06:00")
   480  	if err != nil {
   481  		panic(err)
   482  	}
   483  	lastActivityAt2 := Timestamp{tmp}
   484  
   485  	ctx := context.Background()
   486  	opts := &ListOptions{Page: 1, PerPage: 100}
   487  	got, _, err := client.Copilot.ListCopilotSeats(ctx, "o", opts)
   488  	if err != nil {
   489  		t.Errorf("Copilot.ListCopilotSeats returned error: %v", err)
   490  	}
   491  
   492  	want := &ListCopilotSeatsResponse{
   493  		TotalSeats: 4,
   494  		Seats: []*CopilotSeatDetails{
   495  			{
   496  				Assignee: &User{
   497  					Login:             Ptr("octocat"),
   498  					ID:                Ptr(int64(1)),
   499  					NodeID:            Ptr("MDQ6VXNlcjE="),
   500  					AvatarURL:         Ptr("https://github.com/images/error/octocat_happy.gif"),
   501  					GravatarID:        Ptr(""),
   502  					URL:               Ptr("https://api.github.com/users/octocat"),
   503  					HTMLURL:           Ptr("https://github.com/octocat"),
   504  					FollowersURL:      Ptr("https://api.github.com/users/octocat/followers"),
   505  					FollowingURL:      Ptr("https://api.github.com/users/octocat/following{/other_user}"),
   506  					GistsURL:          Ptr("https://api.github.com/users/octocat/gists{/gist_id}"),
   507  					StarredURL:        Ptr("https://api.github.com/users/octocat/starred{/owner}{/repo}"),
   508  					SubscriptionsURL:  Ptr("https://api.github.com/users/octocat/subscriptions"),
   509  					OrganizationsURL:  Ptr("https://api.github.com/users/octocat/orgs"),
   510  					ReposURL:          Ptr("https://api.github.com/users/octocat/repos"),
   511  					EventsURL:         Ptr("https://api.github.com/users/octocat/events{/privacy}"),
   512  					ReceivedEventsURL: Ptr("https://api.github.com/users/octocat/received_events"),
   513  					Type:              Ptr("User"),
   514  					SiteAdmin:         Ptr(false),
   515  				},
   516  				AssigningTeam: &Team{
   517  					ID:                  Ptr(int64(1)),
   518  					NodeID:              Ptr("MDQ6VGVhbTE="),
   519  					URL:                 Ptr("https://api.github.com/teams/1"),
   520  					HTMLURL:             Ptr("https://github.com/orgs/github/teams/justice-league"),
   521  					Name:                Ptr("Justice League"),
   522  					Slug:                Ptr("justice-league"),
   523  					Description:         Ptr("A great team."),
   524  					Privacy:             Ptr("closed"),
   525  					Permission:          Ptr("admin"),
   526  					NotificationSetting: Ptr("notifications_enabled"),
   527  					MembersURL:          Ptr("https://api.github.com/teams/1/members{/member}"),
   528  					RepositoriesURL:     Ptr("https://api.github.com/teams/1/repos"),
   529  					Parent:              nil,
   530  				},
   531  				CreatedAt:               &createdAt1,
   532  				UpdatedAt:               &updatedAt1,
   533  				PendingCancellationDate: nil,
   534  				LastActivityAt:          &lastActivityAt1,
   535  				LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
   536  			},
   537  			{
   538  				Assignee: &User{
   539  					Login:             Ptr("octokitten"),
   540  					ID:                Ptr(int64(1)),
   541  					NodeID:            Ptr("MDQ76VNlcjE="),
   542  					AvatarURL:         Ptr("https://github.com/images/error/octokitten_happy.gif"),
   543  					GravatarID:        Ptr(""),
   544  					URL:               Ptr("https://api.github.com/users/octokitten"),
   545  					HTMLURL:           Ptr("https://github.com/octokitten"),
   546  					FollowersURL:      Ptr("https://api.github.com/users/octokitten/followers"),
   547  					FollowingURL:      Ptr("https://api.github.com/users/octokitten/following{/other_user}"),
   548  					GistsURL:          Ptr("https://api.github.com/users/octokitten/gists{/gist_id}"),
   549  					StarredURL:        Ptr("https://api.github.com/users/octokitten/starred{/owner}{/repo}"),
   550  					SubscriptionsURL:  Ptr("https://api.github.com/users/octokitten/subscriptions"),
   551  					OrganizationsURL:  Ptr("https://api.github.com/users/octokitten/orgs"),
   552  					ReposURL:          Ptr("https://api.github.com/users/octokitten/repos"),
   553  					EventsURL:         Ptr("https://api.github.com/users/octokitten/events{/privacy}"),
   554  					ReceivedEventsURL: Ptr("https://api.github.com/users/octokitten/received_events"),
   555  					Type:              Ptr("User"),
   556  					SiteAdmin:         Ptr(false),
   557  				},
   558  				AssigningTeam:           nil,
   559  				CreatedAt:               &createdAt2,
   560  				UpdatedAt:               &updatedAt2,
   561  				PendingCancellationDate: Ptr("2021-11-01"),
   562  				LastActivityAt:          &lastActivityAt2,
   563  				LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
   564  			},
   565  			{
   566  				Assignee: &Team{
   567  					ID:   Ptr(int64(1)),
   568  					Name: Ptr("octokittens"),
   569  				},
   570  				AssigningTeam:           nil,
   571  				CreatedAt:               &createdAt2,
   572  				UpdatedAt:               &updatedAt2,
   573  				PendingCancellationDate: Ptr("2021-11-01"),
   574  				LastActivityAt:          &lastActivityAt2,
   575  				LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
   576  			},
   577  			{
   578  				Assignee: &Organization{
   579  					ID:   Ptr(int64(1)),
   580  					Name: Ptr("octocats"),
   581  					Type: Ptr("Organization"),
   582  				},
   583  				AssigningTeam:           nil,
   584  				CreatedAt:               &createdAt2,
   585  				UpdatedAt:               &updatedAt2,
   586  				PendingCancellationDate: Ptr("2021-11-01"),
   587  				LastActivityAt:          &lastActivityAt2,
   588  				LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
   589  			},
   590  		},
   591  	}
   592  
   593  	if !cmp.Equal(got, want) {
   594  		t.Errorf("Copilot.ListCopilotSeats returned %+v, want %+v", got, want)
   595  	}
   596  
   597  	const methodName = "ListCopilotSeats"
   598  
   599  	testBadOptions(t, methodName, func() (err error) {
   600  		_, _, err = client.Copilot.ListCopilotSeats(ctx, "\n", opts)
   601  		return err
   602  	})
   603  
   604  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   605  		got, resp, err := client.Copilot.ListCopilotSeats(ctx, "o", opts)
   606  		if got != nil {
   607  			t.Errorf("Copilot.ListCopilotSeats returned %+v, want nil", got)
   608  		}
   609  		return resp, err
   610  	})
   611  }
   612  
   613  func TestCopilotService_ListCopilotEnterpriseSeats(t *testing.T) {
   614  	t.Parallel()
   615  	client, mux, _ := setup(t)
   616  
   617  	mux.HandleFunc("/enterprises/e/copilot/billing/seats", func(w http.ResponseWriter, r *http.Request) {
   618  		testMethod(t, r, "GET")
   619  		testFormValues(t, r, values{
   620  			"per_page": "100",
   621  			"page":     "1",
   622  		})
   623  		fmt.Fprint(w, `{
   624  			"total_seats": 2,
   625  			"seats": [
   626  				{
   627  					"created_at": "2021-08-03T18:00:00-06:00",
   628  					"updated_at": "2021-09-23T15:00:00-06:00",
   629  					"pending_cancellation_date": null,
   630  					"last_activity_at": "2021-10-14T00:53:32-06:00",
   631  					"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
   632  					"plan_type": "business",
   633  					"assignee": {
   634  						"login": "octocat",
   635  						"id": 1,
   636  						"node_id": "MDQ6VXNlcjE=",
   637  						"avatar_url": "https://github.com/images/error/octocat_happy.gif",
   638  						"gravatar_id": "",
   639  						"url": "https://api.github.com/users/octocat",
   640  						"html_url": "https://github.com/octocat",
   641  						"followers_url": "https://api.github.com/users/octocat/followers",
   642  						"following_url": "https://api.github.com/users/octocat/following{/other_user}",
   643  						"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
   644  						"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
   645  						"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
   646  						"organizations_url": "https://api.github.com/users/octocat/orgs",
   647  						"repos_url": "https://api.github.com/users/octocat/repos",
   648  						"events_url": "https://api.github.com/users/octocat/events{/privacy}",
   649  						"received_events_url": "https://api.github.com/users/octocat/received_events",
   650  						"type": "User",
   651  						"site_admin": false
   652  					},
   653  					"assigning_team": {
   654  						"id": 1,
   655  						"node_id": "MDQ6VGVhbTE=",
   656  						"url": "https://api.github.com/teams/1",
   657  						"html_url": "https://github.com/orgs/github/teams/justice-league",
   658  						"name": "Justice League",
   659  						"slug": "justice-league",
   660  						"description": "A great team.",
   661  						"privacy": "closed",
   662  						"notification_setting": "notifications_enabled",
   663  						"permission": "admin",
   664  						"members_url": "https://api.github.com/teams/1/members{/member}",
   665  						"repositories_url": "https://api.github.com/teams/1/repos",
   666  						"parent": null
   667  					}
   668  				},
   669  				{
   670  					"created_at": "2021-09-23T18:00:00-06:00",
   671  					"updated_at": "2021-09-23T15:00:00-06:00",
   672  					"pending_cancellation_date": "2021-11-01",
   673  					"last_activity_at": "2021-10-13T00:53:32-06:00",
   674  					"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
   675  					"assignee": {
   676  						"login": "octokitten",
   677  						"id": 1,
   678  						"node_id": "MDQ76VNlcjE=",
   679  						"avatar_url": "https://github.com/images/error/octokitten_happy.gif",
   680  						"gravatar_id": "",
   681  						"url": "https://api.github.com/users/octokitten",
   682  						"html_url": "https://github.com/octokitten",
   683  						"followers_url": "https://api.github.com/users/octokitten/followers",
   684  						"following_url": "https://api.github.com/users/octokitten/following{/other_user}",
   685  						"gists_url": "https://api.github.com/users/octokitten/gists{/gist_id}",
   686  						"starred_url": "https://api.github.com/users/octokitten/starred{/owner}{/repo}",
   687  						"subscriptions_url": "https://api.github.com/users/octokitten/subscriptions",
   688  						"organizations_url": "https://api.github.com/users/octokitten/orgs",
   689  						"repos_url": "https://api.github.com/users/octokitten/repos",
   690  						"events_url": "https://api.github.com/users/octokitten/events{/privacy}",
   691  						"received_events_url": "https://api.github.com/users/octokitten/received_events",
   692  						"type": "User",
   693  						"site_admin": false
   694  					}
   695  				}
   696  			]
   697  		}`)
   698  	})
   699  
   700  	tmp, err := time.Parse(time.RFC3339, "2021-08-03T18:00:00-06:00")
   701  	if err != nil {
   702  		panic(err)
   703  	}
   704  	createdAt1 := Timestamp{tmp}
   705  
   706  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T15:00:00-06:00")
   707  	if err != nil {
   708  		panic(err)
   709  	}
   710  	updatedAt1 := Timestamp{tmp}
   711  
   712  	tmp, err = time.Parse(time.RFC3339, "2021-10-14T00:53:32-06:00")
   713  	if err != nil {
   714  		panic(err)
   715  	}
   716  	lastActivityAt1 := Timestamp{tmp}
   717  
   718  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T18:00:00-06:00")
   719  	if err != nil {
   720  		panic(err)
   721  	}
   722  	createdAt2 := Timestamp{tmp}
   723  
   724  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T15:00:00-06:00")
   725  	if err != nil {
   726  		panic(err)
   727  	}
   728  	updatedAt2 := Timestamp{tmp}
   729  
   730  	tmp, err = time.Parse(time.RFC3339, "2021-10-13T00:53:32-06:00")
   731  	if err != nil {
   732  		panic(err)
   733  	}
   734  	lastActivityAt2 := Timestamp{tmp}
   735  
   736  	ctx := context.Background()
   737  	opts := &ListOptions{Page: 1, PerPage: 100}
   738  	got, _, err := client.Copilot.ListCopilotEnterpriseSeats(ctx, "e", opts)
   739  	if err != nil {
   740  		t.Errorf("Copilot.ListCopilotEnterpriseSeats returned error: %v", err)
   741  	}
   742  
   743  	want := &ListCopilotSeatsResponse{
   744  		TotalSeats: 2,
   745  		Seats: []*CopilotSeatDetails{
   746  			{
   747  				Assignee: &User{
   748  					Login:             Ptr("octocat"),
   749  					ID:                Ptr(int64(1)),
   750  					NodeID:            Ptr("MDQ6VXNlcjE="),
   751  					AvatarURL:         Ptr("https://github.com/images/error/octocat_happy.gif"),
   752  					GravatarID:        Ptr(""),
   753  					URL:               Ptr("https://api.github.com/users/octocat"),
   754  					HTMLURL:           Ptr("https://github.com/octocat"),
   755  					FollowersURL:      Ptr("https://api.github.com/users/octocat/followers"),
   756  					FollowingURL:      Ptr("https://api.github.com/users/octocat/following{/other_user}"),
   757  					GistsURL:          Ptr("https://api.github.com/users/octocat/gists{/gist_id}"),
   758  					StarredURL:        Ptr("https://api.github.com/users/octocat/starred{/owner}{/repo}"),
   759  					SubscriptionsURL:  Ptr("https://api.github.com/users/octocat/subscriptions"),
   760  					OrganizationsURL:  Ptr("https://api.github.com/users/octocat/orgs"),
   761  					ReposURL:          Ptr("https://api.github.com/users/octocat/repos"),
   762  					EventsURL:         Ptr("https://api.github.com/users/octocat/events{/privacy}"),
   763  					ReceivedEventsURL: Ptr("https://api.github.com/users/octocat/received_events"),
   764  					Type:              Ptr("User"),
   765  					SiteAdmin:         Ptr(false),
   766  				},
   767  				AssigningTeam: &Team{
   768  					ID:                  Ptr(int64(1)),
   769  					NodeID:              Ptr("MDQ6VGVhbTE="),
   770  					URL:                 Ptr("https://api.github.com/teams/1"),
   771  					HTMLURL:             Ptr("https://github.com/orgs/github/teams/justice-league"),
   772  					Name:                Ptr("Justice League"),
   773  					Slug:                Ptr("justice-league"),
   774  					Description:         Ptr("A great team."),
   775  					Privacy:             Ptr("closed"),
   776  					NotificationSetting: Ptr("notifications_enabled"),
   777  					Permission:          Ptr("admin"),
   778  					MembersURL:          Ptr("https://api.github.com/teams/1/members{/member}"),
   779  					RepositoriesURL:     Ptr("https://api.github.com/teams/1/repos"),
   780  					Parent:              nil,
   781  				},
   782  				CreatedAt:               &createdAt1,
   783  				UpdatedAt:               &updatedAt1,
   784  				PendingCancellationDate: nil,
   785  				LastActivityAt:          &lastActivityAt1,
   786  				LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
   787  				PlanType:                Ptr("business"),
   788  			},
   789  			{
   790  				Assignee: &User{
   791  					Login:             Ptr("octokitten"),
   792  					ID:                Ptr(int64(1)),
   793  					NodeID:            Ptr("MDQ76VNlcjE="),
   794  					AvatarURL:         Ptr("https://github.com/images/error/octokitten_happy.gif"),
   795  					GravatarID:        Ptr(""),
   796  					URL:               Ptr("https://api.github.com/users/octokitten"),
   797  					HTMLURL:           Ptr("https://github.com/octokitten"),
   798  					FollowersURL:      Ptr("https://api.github.com/users/octokitten/followers"),
   799  					FollowingURL:      Ptr("https://api.github.com/users/octokitten/following{/other_user}"),
   800  					GistsURL:          Ptr("https://api.github.com/users/octokitten/gists{/gist_id}"),
   801  					StarredURL:        Ptr("https://api.github.com/users/octokitten/starred{/owner}{/repo}"),
   802  					SubscriptionsURL:  Ptr("https://api.github.com/users/octokitten/subscriptions"),
   803  					OrganizationsURL:  Ptr("https://api.github.com/users/octokitten/orgs"),
   804  					ReposURL:          Ptr("https://api.github.com/users/octokitten/repos"),
   805  					EventsURL:         Ptr("https://api.github.com/users/octokitten/events{/privacy}"),
   806  					ReceivedEventsURL: Ptr("https://api.github.com/users/octokitten/received_events"),
   807  					Type:              Ptr("User"),
   808  					SiteAdmin:         Ptr(false),
   809  				},
   810  				AssigningTeam:           nil,
   811  				CreatedAt:               &createdAt2,
   812  				UpdatedAt:               &updatedAt2,
   813  				PendingCancellationDate: Ptr("2021-11-01"),
   814  				LastActivityAt:          &lastActivityAt2,
   815  				LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
   816  				PlanType:                nil,
   817  			},
   818  		},
   819  	}
   820  
   821  	if !cmp.Equal(got, want) {
   822  		log.Printf("got: %+v", got.Seats[1])
   823  		log.Printf("want: %+v", want.Seats[1])
   824  		t.Errorf("Copilot.ListCopilotEnterpriseSeats returned %+v, want %+v", got, want)
   825  	}
   826  
   827  	const methodName = "ListCopilotEnterpriseSeats"
   828  
   829  	testBadOptions(t, methodName, func() (err error) {
   830  		_, _, err = client.Copilot.ListCopilotEnterpriseSeats(ctx, "\n", opts)
   831  		return err
   832  	})
   833  
   834  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   835  		got, resp, err := client.Copilot.ListCopilotEnterpriseSeats(ctx, "e", opts)
   836  		if got != nil {
   837  			t.Errorf("Copilot.ListCopilotEnterpriseSeats returned %+v, want nil", got)
   838  		}
   839  		return resp, err
   840  	})
   841  }
   842  
   843  func TestCopilotService_AddCopilotTeams(t *testing.T) {
   844  	t.Parallel()
   845  	client, mux, _ := setup(t)
   846  
   847  	mux.HandleFunc("/orgs/o/copilot/billing/selected_teams", func(w http.ResponseWriter, r *http.Request) {
   848  		testMethod(t, r, "POST")
   849  		testBody(t, r, `{"selected_teams":["team1","team2"]}`+"\n")
   850  		fmt.Fprint(w, `{"seats_created": 2}`)
   851  	})
   852  
   853  	ctx := context.Background()
   854  	got, _, err := client.Copilot.AddCopilotTeams(ctx, "o", []string{"team1", "team2"})
   855  	if err != nil {
   856  		t.Errorf("Copilot.AddCopilotTeams returned error: %v", err)
   857  	}
   858  
   859  	want := &SeatAssignments{SeatsCreated: 2}
   860  
   861  	if !cmp.Equal(got, want) {
   862  		t.Errorf("Copilot.AddCopilotTeams returned %+v, want %+v", got, want)
   863  	}
   864  
   865  	const methodName = "AddCopilotTeams"
   866  
   867  	testBadOptions(t, methodName, func() (err error) {
   868  		_, _, err = client.Copilot.AddCopilotTeams(ctx, "\n", []string{"team1", "team2"})
   869  		return err
   870  	})
   871  
   872  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   873  		got, resp, err := client.Copilot.AddCopilotTeams(ctx, "o", []string{"team1", "team2"})
   874  		if got != nil {
   875  			t.Errorf("Copilot.AddCopilotTeams returned %+v, want nil", got)
   876  		}
   877  		return resp, err
   878  	})
   879  }
   880  
   881  func TestCopilotService_RemoveCopilotTeams(t *testing.T) {
   882  	t.Parallel()
   883  	client, mux, _ := setup(t)
   884  
   885  	mux.HandleFunc("/orgs/o/copilot/billing/selected_teams", func(w http.ResponseWriter, r *http.Request) {
   886  		testMethod(t, r, "DELETE")
   887  		testBody(t, r, `{"selected_teams":["team1","team2"]}`+"\n")
   888  		fmt.Fprint(w, `{"seats_cancelled": 2}`)
   889  	})
   890  
   891  	ctx := context.Background()
   892  	got, _, err := client.Copilot.RemoveCopilotTeams(ctx, "o", []string{"team1", "team2"})
   893  	if err != nil {
   894  		t.Errorf("Copilot.RemoveCopilotTeams returned error: %v", err)
   895  	}
   896  
   897  	want := &SeatCancellations{SeatsCancelled: 2}
   898  
   899  	if !cmp.Equal(got, want) {
   900  		t.Errorf("Copilot.RemoveCopilotTeams returned %+v, want %+v", got, want)
   901  	}
   902  
   903  	const methodName = "RemoveCopilotTeams"
   904  
   905  	testBadOptions(t, methodName, func() (err error) {
   906  		_, _, err = client.Copilot.RemoveCopilotTeams(ctx, "\n", []string{"team1", "team2"})
   907  		return err
   908  	})
   909  
   910  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   911  		got, resp, err := client.Copilot.RemoveCopilotTeams(ctx, "o", []string{"team1", "team2"})
   912  		if got != nil {
   913  			t.Errorf("Copilot.RemoveCopilotTeams returned %+v, want nil", got)
   914  		}
   915  		return resp, err
   916  	})
   917  }
   918  
   919  func TestCopilotService_AddCopilotUsers(t *testing.T) {
   920  	t.Parallel()
   921  	client, mux, _ := setup(t)
   922  
   923  	mux.HandleFunc("/orgs/o/copilot/billing/selected_users", func(w http.ResponseWriter, r *http.Request) {
   924  		testMethod(t, r, "POST")
   925  		testBody(t, r, `{"selected_usernames":["user1","user2"]}`+"\n")
   926  		fmt.Fprint(w, `{"seats_created": 2}`)
   927  	})
   928  
   929  	ctx := context.Background()
   930  	got, _, err := client.Copilot.AddCopilotUsers(ctx, "o", []string{"user1", "user2"})
   931  	if err != nil {
   932  		t.Errorf("Copilot.AddCopilotUsers returned error: %v", err)
   933  	}
   934  
   935  	want := &SeatAssignments{SeatsCreated: 2}
   936  
   937  	if !cmp.Equal(got, want) {
   938  		t.Errorf("Copilot.AddCopilotUsers returned %+v, want %+v", got, want)
   939  	}
   940  
   941  	const methodName = "AddCopilotUsers"
   942  
   943  	testBadOptions(t, methodName, func() (err error) {
   944  		_, _, err = client.Copilot.AddCopilotUsers(ctx, "\n", []string{"user1", "user2"})
   945  		return err
   946  	})
   947  
   948  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   949  		got, resp, err := client.Copilot.AddCopilotUsers(ctx, "o", []string{"user1", "user2"})
   950  		if got != nil {
   951  			t.Errorf("Copilot.AddCopilotUsers returned %+v, want nil", got)
   952  		}
   953  		return resp, err
   954  	})
   955  }
   956  
   957  func TestCopilotService_RemoveCopilotUsers(t *testing.T) {
   958  	t.Parallel()
   959  	client, mux, _ := setup(t)
   960  
   961  	mux.HandleFunc("/orgs/o/copilot/billing/selected_users", func(w http.ResponseWriter, r *http.Request) {
   962  		testMethod(t, r, "DELETE")
   963  		testBody(t, r, `{"selected_usernames":["user1","user2"]}`+"\n")
   964  		fmt.Fprint(w, `{"seats_cancelled": 2}`)
   965  	})
   966  
   967  	ctx := context.Background()
   968  	got, _, err := client.Copilot.RemoveCopilotUsers(ctx, "o", []string{"user1", "user2"})
   969  	if err != nil {
   970  		t.Errorf("Copilot.RemoveCopilotUsers returned error: %v", err)
   971  	}
   972  
   973  	want := &SeatCancellations{SeatsCancelled: 2}
   974  
   975  	if !cmp.Equal(got, want) {
   976  		t.Errorf("Copilot.RemoveCopilotUsers returned %+v, want %+v", got, want)
   977  	}
   978  
   979  	const methodName = "RemoveCopilotUsers"
   980  
   981  	testBadOptions(t, methodName, func() (err error) {
   982  		_, _, err = client.Copilot.RemoveCopilotUsers(ctx, "\n", []string{"user1", "user2"})
   983  		return err
   984  	})
   985  
   986  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   987  		got, resp, err := client.Copilot.RemoveCopilotUsers(ctx, "o", []string{"user1", "user2"})
   988  		if got != nil {
   989  			t.Errorf("Copilot.RemoveCopilotUsers returned %+v, want nil", got)
   990  		}
   991  		return resp, err
   992  	})
   993  }
   994  
   995  func TestCopilotService_GetSeatDetails(t *testing.T) {
   996  	t.Parallel()
   997  	client, mux, _ := setup(t)
   998  
   999  	mux.HandleFunc("/orgs/o/members/u/copilot", func(w http.ResponseWriter, r *http.Request) {
  1000  		testMethod(t, r, "GET")
  1001  		fmt.Fprint(w, `{
  1002  				"created_at": "2021-08-03T18:00:00-06:00",
  1003  				"updated_at": "2021-09-23T15:00:00-06:00",
  1004  				"pending_cancellation_date": null,
  1005  				"last_activity_at": "2021-10-14T00:53:32-06:00",
  1006  				"last_activity_editor": "vscode/1.77.3/copilot/1.86.82",
  1007  				"assignee": {
  1008  					"login": "octocat",
  1009  					"id": 1,
  1010  					"node_id": "MDQ6VXNlcjE=",
  1011  					"avatar_url": "https://github.com/images/error/octocat_happy.gif",
  1012  					"gravatar_id": "",
  1013  					"url": "https://api.github.com/users/octocat",
  1014  					"html_url": "https://github.com/octocat",
  1015  					"followers_url": "https://api.github.com/users/octocat/followers",
  1016  					"following_url": "https://api.github.com/users/octocat/following{/other_user}",
  1017  					"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
  1018  					"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
  1019  					"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
  1020  					"organizations_url": "https://api.github.com/users/octocat/orgs",
  1021  					"repos_url": "https://api.github.com/users/octocat/repos",
  1022  					"events_url": "https://api.github.com/users/octocat/events{/privacy}",
  1023  					"received_events_url": "https://api.github.com/users/octocat/received_events",
  1024  					"type": "User",
  1025  					"site_admin": false
  1026  				},
  1027  				"assigning_team": {
  1028  					"id": 1,
  1029  					"node_id": "MDQ6VGVhbTE=",
  1030  					"url": "https://api.github.com/teams/1",
  1031  					"html_url": "https://github.com/orgs/github/teams/justice-league",
  1032  					"name": "Justice League",
  1033  					"slug": "justice-league",
  1034  					"description": "A great team.",
  1035  					"privacy": "closed",
  1036  					"notification_setting": "notifications_enabled",
  1037  					"permission": "admin",
  1038  					"members_url": "https://api.github.com/teams/1/members{/member}",
  1039  					"repositories_url": "https://api.github.com/teams/1/repos",
  1040  					"parent": null
  1041  				}
  1042  			}`)
  1043  	})
  1044  
  1045  	tmp, err := time.Parse(time.RFC3339, "2021-08-03T18:00:00-06:00")
  1046  	if err != nil {
  1047  		panic(err)
  1048  	}
  1049  	createdAt := Timestamp{tmp}
  1050  
  1051  	tmp, err = time.Parse(time.RFC3339, "2021-09-23T15:00:00-06:00")
  1052  	if err != nil {
  1053  		panic(err)
  1054  	}
  1055  	updatedAt := Timestamp{tmp}
  1056  
  1057  	tmp, err = time.Parse(time.RFC3339, "2021-10-14T00:53:32-06:00")
  1058  	if err != nil {
  1059  		panic(err)
  1060  	}
  1061  	lastActivityAt := Timestamp{tmp}
  1062  
  1063  	ctx := context.Background()
  1064  	got, _, err := client.Copilot.GetSeatDetails(ctx, "o", "u")
  1065  	if err != nil {
  1066  		t.Errorf("Copilot.GetSeatDetails returned error: %v", err)
  1067  	}
  1068  
  1069  	want := &CopilotSeatDetails{
  1070  		Assignee: &User{
  1071  			Login:             Ptr("octocat"),
  1072  			ID:                Ptr(int64(1)),
  1073  			NodeID:            Ptr("MDQ6VXNlcjE="),
  1074  			AvatarURL:         Ptr("https://github.com/images/error/octocat_happy.gif"),
  1075  			GravatarID:        Ptr(""),
  1076  			URL:               Ptr("https://api.github.com/users/octocat"),
  1077  			HTMLURL:           Ptr("https://github.com/octocat"),
  1078  			FollowersURL:      Ptr("https://api.github.com/users/octocat/followers"),
  1079  			FollowingURL:      Ptr("https://api.github.com/users/octocat/following{/other_user}"),
  1080  			GistsURL:          Ptr("https://api.github.com/users/octocat/gists{/gist_id}"),
  1081  			StarredURL:        Ptr("https://api.github.com/users/octocat/starred{/owner}{/repo}"),
  1082  			SubscriptionsURL:  Ptr("https://api.github.com/users/octocat/subscriptions"),
  1083  			OrganizationsURL:  Ptr("https://api.github.com/users/octocat/orgs"),
  1084  			ReposURL:          Ptr("https://api.github.com/users/octocat/repos"),
  1085  			EventsURL:         Ptr("https://api.github.com/users/octocat/events{/privacy}"),
  1086  			ReceivedEventsURL: Ptr("https://api.github.com/users/octocat/received_events"),
  1087  			Type:              Ptr("User"),
  1088  			SiteAdmin:         Ptr(false),
  1089  		},
  1090  		AssigningTeam: &Team{
  1091  			ID:                  Ptr(int64(1)),
  1092  			NodeID:              Ptr("MDQ6VGVhbTE="),
  1093  			URL:                 Ptr("https://api.github.com/teams/1"),
  1094  			HTMLURL:             Ptr("https://github.com/orgs/github/teams/justice-league"),
  1095  			Name:                Ptr("Justice League"),
  1096  			Slug:                Ptr("justice-league"),
  1097  			Description:         Ptr("A great team."),
  1098  			Privacy:             Ptr("closed"),
  1099  			NotificationSetting: Ptr("notifications_enabled"),
  1100  			Permission:          Ptr("admin"),
  1101  			MembersURL:          Ptr("https://api.github.com/teams/1/members{/member}"),
  1102  			RepositoriesURL:     Ptr("https://api.github.com/teams/1/repos"),
  1103  			Parent:              nil,
  1104  		},
  1105  		CreatedAt:               &createdAt,
  1106  		UpdatedAt:               &updatedAt,
  1107  		PendingCancellationDate: nil,
  1108  		LastActivityAt:          &lastActivityAt,
  1109  		LastActivityEditor:      Ptr("vscode/1.77.3/copilot/1.86.82"),
  1110  	}
  1111  
  1112  	if !cmp.Equal(got, want) {
  1113  		t.Errorf("Copilot.GetSeatDetails returned %+v, want %+v", got, want)
  1114  	}
  1115  
  1116  	const methodName = "GetSeatDetails"
  1117  
  1118  	testBadOptions(t, methodName, func() (err error) {
  1119  		_, _, err = client.Copilot.GetSeatDetails(ctx, "\n", "u")
  1120  		return err
  1121  	})
  1122  
  1123  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1124  		got, resp, err := client.Copilot.GetSeatDetails(ctx, "o", "u")
  1125  		if got != nil {
  1126  			t.Errorf("Copilot.GetSeatDetails returned %+v, want nil", got)
  1127  		}
  1128  		return resp, err
  1129  	})
  1130  }
  1131  
  1132  func TestCopilotService_GetEnterpriseMetrics(t *testing.T) {
  1133  	t.Parallel()
  1134  	client, mux, _ := setup(t)
  1135  
  1136  	mux.HandleFunc("/enterprises/e/copilot/metrics", func(w http.ResponseWriter, r *http.Request) {
  1137  		testMethod(t, r, "GET")
  1138  		fmt.Fprint(w, `[
  1139  			{
  1140  				"date": "2024-06-24",
  1141  				"total_active_users": 24,
  1142  				"total_engaged_users": 20,
  1143  				"copilot_ide_code_completions": {
  1144  				"total_engaged_users": 20,
  1145  				"languages": [
  1146  					{
  1147  					"name": "python",
  1148  					"total_engaged_users": 10
  1149  					},
  1150  					{
  1151  					"name": "ruby",
  1152  					"total_engaged_users": 10
  1153  					}
  1154  				],
  1155  				"editors": [
  1156  					{
  1157  					"name": "vscode",
  1158  					"total_engaged_users": 13,
  1159  					"models": [
  1160  						{
  1161  						"name": "default",
  1162  						"is_custom_model": false,
  1163  						"custom_model_training_date": null,
  1164  						"total_engaged_users": 13,
  1165  						"languages": [
  1166  							{
  1167  							"name": "python",
  1168  							"total_engaged_users": 6,
  1169  							"total_code_suggestions": 249,
  1170  							"total_code_acceptances": 123,
  1171  							"total_code_lines_suggested": 225,
  1172  							"total_code_lines_accepted": 135
  1173  							},
  1174  							{
  1175  							"name": "ruby",
  1176  							"total_engaged_users": 7,
  1177  							"total_code_suggestions": 496,
  1178  							"total_code_acceptances": 253,
  1179  							"total_code_lines_suggested": 520,
  1180  							"total_code_lines_accepted": 270
  1181  							}
  1182  						]
  1183  						}
  1184  					]
  1185  					},
  1186  					{
  1187  					"name": "neovim",
  1188  					"total_engaged_users": 7,
  1189  					"models": [
  1190  						{
  1191  						"name": "a-custom-model",
  1192  						"is_custom_model": true,
  1193  						"custom_model_training_date": "2024-02-01",
  1194  						"languages": [
  1195  							{
  1196  							"name": "typescript",
  1197  							"total_engaged_users": 3,
  1198  							"total_code_suggestions": 112,
  1199  							"total_code_acceptances": 56,
  1200  							"total_code_lines_suggested": 143,
  1201  							"total_code_lines_accepted": 61
  1202  							},
  1203  							{
  1204  							"name": "go",
  1205  							"total_engaged_users": 4,
  1206  							"total_code_suggestions": 132,
  1207  							"total_code_acceptances": 67,
  1208  							"total_code_lines_suggested": 154,
  1209  							"total_code_lines_accepted": 72
  1210  							}
  1211  						]
  1212  						}
  1213  					]
  1214  					}
  1215  				]
  1216  				},
  1217  				"copilot_ide_chat": {
  1218  				"total_engaged_users": 13,
  1219  				"editors": [
  1220  					{
  1221  					"name": "vscode",
  1222  					"total_engaged_users": 13,
  1223  					"models": [
  1224  						{
  1225  						"name": "default",
  1226  						"is_custom_model": false,
  1227  						"custom_model_training_date": null,
  1228  						"total_engaged_users": 12,
  1229  						"total_chats": 45,
  1230  						"total_chat_insertion_events": 12,
  1231  						"total_chat_copy_events": 16
  1232  						},
  1233  						{
  1234  						"name": "a-custom-model",
  1235  						"is_custom_model": true,
  1236  						"custom_model_training_date": "2024-02-01",
  1237  						"total_engaged_users": 1,
  1238  						"total_chats": 10,
  1239  						"total_chat_insertion_events": 11,
  1240  						"total_chat_copy_events": 3
  1241  						}
  1242  					]
  1243  					}
  1244  				]
  1245  				},
  1246  				"copilot_dotcom_chat": {
  1247  				"total_engaged_users": 14,
  1248  				"models": [
  1249  					{
  1250  					"name": "default",
  1251  					"is_custom_model": false,
  1252  					"custom_model_training_date": null,
  1253  					"total_engaged_users": 14,
  1254  					"total_chats": 38
  1255  					}
  1256  				]
  1257  				},
  1258  				"copilot_dotcom_pull_requests": {
  1259  				"total_engaged_users": 12,
  1260  				"repositories": [
  1261  					{
  1262  					"name": "demo/repo1",
  1263  					"total_engaged_users": 8,
  1264  					"models": [
  1265  						{
  1266  						"name": "default",
  1267  						"is_custom_model": false,
  1268  						"custom_model_training_date": null,
  1269  						"total_pr_summaries_created": 6,
  1270  						"total_engaged_users": 8
  1271  						}
  1272  					]
  1273  					},
  1274  					{
  1275  					"name": "demo/repo2",
  1276  					"total_engaged_users": 4,
  1277  					"models": [
  1278  						{
  1279  						"name": "a-custom-model",
  1280  						"is_custom_model": true,
  1281  						"custom_model_training_date": "2024-02-01",
  1282  						"total_pr_summaries_created": 10,
  1283  						"total_engaged_users": 4
  1284  						}
  1285  					]
  1286  					}
  1287  				]
  1288  				}
  1289  			}
  1290  		]`)
  1291  	})
  1292  
  1293  	ctx := context.Background()
  1294  	got, _, err := client.Copilot.GetEnterpriseMetrics(ctx, "e", &CopilotMetricsListOptions{})
  1295  	if err != nil {
  1296  		t.Errorf("Copilot.GetEnterpriseMetrics returned error: %v", err)
  1297  	}
  1298  
  1299  	totalActiveUsers := 24
  1300  	totalEngagedUsers := 20
  1301  	want := []*CopilotMetrics{
  1302  		{
  1303  			Date:              "2024-06-24",
  1304  			TotalActiveUsers:  &totalActiveUsers,
  1305  			TotalEngagedUsers: &totalEngagedUsers,
  1306  			CopilotIDECodeCompletions: &CopilotIDECodeCompletions{
  1307  				TotalEngagedUsers: 20,
  1308  				Languages: []*CopilotIDECodeCompletionsLanguage{
  1309  					{
  1310  						Name:              "python",
  1311  						TotalEngagedUsers: 10,
  1312  					},
  1313  					{
  1314  						Name:              "ruby",
  1315  						TotalEngagedUsers: 10,
  1316  					},
  1317  				},
  1318  				Editors: []*CopilotIDECodeCompletionsEditor{
  1319  					{
  1320  						Name:              "vscode",
  1321  						TotalEngagedUsers: 13,
  1322  						Models: []*CopilotIDECodeCompletionsModel{
  1323  							{
  1324  								Name:                    "default",
  1325  								IsCustomModel:           false,
  1326  								CustomModelTrainingDate: nil,
  1327  								TotalEngagedUsers:       13,
  1328  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  1329  									{
  1330  										Name:                    "python",
  1331  										TotalEngagedUsers:       6,
  1332  										TotalCodeSuggestions:    249,
  1333  										TotalCodeAcceptances:    123,
  1334  										TotalCodeLinesSuggested: 225,
  1335  										TotalCodeLinesAccepted:  135,
  1336  									},
  1337  									{
  1338  										Name:                    "ruby",
  1339  										TotalEngagedUsers:       7,
  1340  										TotalCodeSuggestions:    496,
  1341  										TotalCodeAcceptances:    253,
  1342  										TotalCodeLinesSuggested: 520,
  1343  										TotalCodeLinesAccepted:  270,
  1344  									},
  1345  								},
  1346  							},
  1347  						},
  1348  					},
  1349  					{
  1350  						Name:              "neovim",
  1351  						TotalEngagedUsers: 7,
  1352  						Models: []*CopilotIDECodeCompletionsModel{
  1353  							{
  1354  								Name:                    "a-custom-model",
  1355  								IsCustomModel:           true,
  1356  								CustomModelTrainingDate: Ptr("2024-02-01"),
  1357  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  1358  									{
  1359  										Name:                    "typescript",
  1360  										TotalEngagedUsers:       3,
  1361  										TotalCodeSuggestions:    112,
  1362  										TotalCodeAcceptances:    56,
  1363  										TotalCodeLinesSuggested: 143,
  1364  										TotalCodeLinesAccepted:  61,
  1365  									},
  1366  									{
  1367  										Name:                    "go",
  1368  										TotalEngagedUsers:       4,
  1369  										TotalCodeSuggestions:    132,
  1370  										TotalCodeAcceptances:    67,
  1371  										TotalCodeLinesSuggested: 154,
  1372  										TotalCodeLinesAccepted:  72,
  1373  									},
  1374  								},
  1375  							},
  1376  						},
  1377  					},
  1378  				},
  1379  			},
  1380  			CopilotIDEChat: &CopilotIDEChat{
  1381  				TotalEngagedUsers: 13,
  1382  				Editors: []*CopilotIDEChatEditor{
  1383  					{
  1384  						Name:              "vscode",
  1385  						TotalEngagedUsers: 13,
  1386  						Models: []*CopilotIDEChatModel{
  1387  							{
  1388  								Name:                     "default",
  1389  								IsCustomModel:            false,
  1390  								CustomModelTrainingDate:  nil,
  1391  								TotalEngagedUsers:        12,
  1392  								TotalChats:               45,
  1393  								TotalChatInsertionEvents: 12,
  1394  								TotalChatCopyEvents:      16,
  1395  							},
  1396  							{
  1397  								Name:                     "a-custom-model",
  1398  								IsCustomModel:            true,
  1399  								CustomModelTrainingDate:  Ptr("2024-02-01"),
  1400  								TotalEngagedUsers:        1,
  1401  								TotalChats:               10,
  1402  								TotalChatInsertionEvents: 11,
  1403  								TotalChatCopyEvents:      3,
  1404  							},
  1405  						},
  1406  					},
  1407  				},
  1408  			},
  1409  			CopilotDotcomChat: &CopilotDotcomChat{
  1410  				TotalEngagedUsers: 14,
  1411  				Models: []*CopilotDotcomChatModel{
  1412  					{
  1413  						Name:                    "default",
  1414  						IsCustomModel:           false,
  1415  						CustomModelTrainingDate: nil,
  1416  						TotalEngagedUsers:       14,
  1417  						TotalChats:              38,
  1418  					},
  1419  				},
  1420  			},
  1421  			CopilotDotcomPullRequests: &CopilotDotcomPullRequests{
  1422  				TotalEngagedUsers: 12,
  1423  				Repositories: []*CopilotDotcomPullRequestsRepository{
  1424  					{
  1425  						Name:              "demo/repo1",
  1426  						TotalEngagedUsers: 8,
  1427  						Models: []*CopilotDotcomPullRequestsModel{
  1428  							{
  1429  								Name:                    "default",
  1430  								IsCustomModel:           false,
  1431  								CustomModelTrainingDate: nil,
  1432  								TotalPRSummariesCreated: 6,
  1433  								TotalEngagedUsers:       8,
  1434  							},
  1435  						},
  1436  					},
  1437  					{
  1438  						Name:              "demo/repo2",
  1439  						TotalEngagedUsers: 4,
  1440  						Models: []*CopilotDotcomPullRequestsModel{
  1441  							{
  1442  								Name:                    "a-custom-model",
  1443  								IsCustomModel:           true,
  1444  								CustomModelTrainingDate: Ptr("2024-02-01"),
  1445  								TotalPRSummariesCreated: 10,
  1446  								TotalEngagedUsers:       4,
  1447  							},
  1448  						},
  1449  					},
  1450  				},
  1451  			},
  1452  		},
  1453  	}
  1454  
  1455  	if !cmp.Equal(got, want) {
  1456  		t.Errorf("Copilot.GetEnterpriseMetrics returned %+v, want %+v", got, want)
  1457  	}
  1458  
  1459  	const methodName = "GetEnterpriseMetrics"
  1460  
  1461  	testBadOptions(t, methodName, func() (err error) {
  1462  		_, _, err = client.Copilot.GetEnterpriseMetrics(ctx, "\n", &CopilotMetricsListOptions{})
  1463  		return err
  1464  	})
  1465  
  1466  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1467  		got, resp, err := client.Copilot.GetEnterpriseMetrics(ctx, "e", &CopilotMetricsListOptions{})
  1468  		if got != nil {
  1469  			t.Errorf("Copilot.GetEnterpriseMetrics returned %+v, want nil", got)
  1470  		}
  1471  		return resp, err
  1472  	})
  1473  }
  1474  
  1475  func TestCopilotService_GetEnterpriseTeamMetrics(t *testing.T) {
  1476  	t.Parallel()
  1477  	client, mux, _ := setup(t)
  1478  
  1479  	mux.HandleFunc("/enterprises/e/team/t/copilot/metrics", func(w http.ResponseWriter, r *http.Request) {
  1480  		testMethod(t, r, "GET")
  1481  		fmt.Fprint(w, `[
  1482  			{
  1483  				"date": "2024-06-24",
  1484  				"total_active_users": 24,
  1485  				"total_engaged_users": 20,
  1486  				"copilot_ide_code_completions": {
  1487  				"total_engaged_users": 20,
  1488  				"languages": [
  1489  					{
  1490  					"name": "python",
  1491  					"total_engaged_users": 10
  1492  					},
  1493  					{
  1494  					"name": "ruby",
  1495  					"total_engaged_users": 10
  1496  					}
  1497  				],
  1498  				"editors": [
  1499  					{
  1500  					"name": "vscode",
  1501  					"total_engaged_users": 13,
  1502  					"models": [
  1503  						{
  1504  						"name": "default",
  1505  						"is_custom_model": false,
  1506  						"custom_model_training_date": null,
  1507  						"total_engaged_users": 13,
  1508  						"languages": [
  1509  							{
  1510  							"name": "python",
  1511  							"total_engaged_users": 6,
  1512  							"total_code_suggestions": 249,
  1513  							"total_code_acceptances": 123,
  1514  							"total_code_lines_suggested": 225,
  1515  							"total_code_lines_accepted": 135
  1516  							},
  1517  							{
  1518  							"name": "ruby",
  1519  							"total_engaged_users": 7,
  1520  							"total_code_suggestions": 496,
  1521  							"total_code_acceptances": 253,
  1522  							"total_code_lines_suggested": 520,
  1523  							"total_code_lines_accepted": 270
  1524  							}
  1525  						]
  1526  						}
  1527  					]
  1528  					},
  1529  					{
  1530  					"name": "neovim",
  1531  					"total_engaged_users": 7,
  1532  					"models": [
  1533  						{
  1534  						"name": "a-custom-model",
  1535  						"is_custom_model": true,
  1536  						"custom_model_training_date": "2024-02-01",
  1537  						"languages": [
  1538  							{
  1539  							"name": "typescript",
  1540  							"total_engaged_users": 3,
  1541  							"total_code_suggestions": 112,
  1542  							"total_code_acceptances": 56,
  1543  							"total_code_lines_suggested": 143,
  1544  							"total_code_lines_accepted": 61
  1545  							},
  1546  							{
  1547  							"name": "go",
  1548  							"total_engaged_users": 4,
  1549  							"total_code_suggestions": 132,
  1550  							"total_code_acceptances": 67,
  1551  							"total_code_lines_suggested": 154,
  1552  							"total_code_lines_accepted": 72
  1553  							}
  1554  						]
  1555  						}
  1556  					]
  1557  					}
  1558  				]
  1559  				},
  1560  				"copilot_ide_chat": {
  1561  				"total_engaged_users": 13,
  1562  				"editors": [
  1563  					{
  1564  					"name": "vscode",
  1565  					"total_engaged_users": 13,
  1566  					"models": [
  1567  						{
  1568  						"name": "default",
  1569  						"is_custom_model": false,
  1570  						"custom_model_training_date": null,
  1571  						"total_engaged_users": 12,
  1572  						"total_chats": 45,
  1573  						"total_chat_insertion_events": 12,
  1574  						"total_chat_copy_events": 16
  1575  						},
  1576  						{
  1577  						"name": "a-custom-model",
  1578  						"is_custom_model": true,
  1579  						"custom_model_training_date": "2024-02-01",
  1580  						"total_engaged_users": 1,
  1581  						"total_chats": 10,
  1582  						"total_chat_insertion_events": 11,
  1583  						"total_chat_copy_events": 3
  1584  						}
  1585  					]
  1586  					}
  1587  				]
  1588  				},
  1589  				"copilot_dotcom_chat": {
  1590  				"total_engaged_users": 14,
  1591  				"models": [
  1592  					{
  1593  					"name": "default",
  1594  					"is_custom_model": false,
  1595  					"custom_model_training_date": null,
  1596  					"total_engaged_users": 14,
  1597  					"total_chats": 38
  1598  					}
  1599  				]
  1600  				},
  1601  				"copilot_dotcom_pull_requests": {
  1602  				"total_engaged_users": 12,
  1603  				"repositories": [
  1604  					{
  1605  					"name": "demo/repo1",
  1606  					"total_engaged_users": 8,
  1607  					"models": [
  1608  						{
  1609  						"name": "default",
  1610  						"is_custom_model": false,
  1611  						"custom_model_training_date": null,
  1612  						"total_pr_summaries_created": 6,
  1613  						"total_engaged_users": 8
  1614  						}
  1615  					]
  1616  					},
  1617  					{
  1618  					"name": "demo/repo2",
  1619  					"total_engaged_users": 4,
  1620  					"models": [
  1621  						{
  1622  						"name": "a-custom-model",
  1623  						"is_custom_model": true,
  1624  						"custom_model_training_date": "2024-02-01",
  1625  						"total_pr_summaries_created": 10,
  1626  						"total_engaged_users": 4
  1627  						}
  1628  					]
  1629  					}
  1630  				]
  1631  				}
  1632  			}
  1633  		]`)
  1634  	})
  1635  
  1636  	ctx := context.Background()
  1637  	got, _, err := client.Copilot.GetEnterpriseTeamMetrics(ctx, "e", "t", &CopilotMetricsListOptions{})
  1638  	if err != nil {
  1639  		t.Errorf("Copilot.GetEnterpriseTeamMetrics returned error: %v", err)
  1640  	}
  1641  
  1642  	totalActiveUsers := 24
  1643  	totalEngagedUsers := 20
  1644  	want := []*CopilotMetrics{
  1645  		{
  1646  			Date:              "2024-06-24",
  1647  			TotalActiveUsers:  &totalActiveUsers,
  1648  			TotalEngagedUsers: &totalEngagedUsers,
  1649  			CopilotIDECodeCompletions: &CopilotIDECodeCompletions{
  1650  				TotalEngagedUsers: 20,
  1651  				Languages: []*CopilotIDECodeCompletionsLanguage{
  1652  					{
  1653  						Name:              "python",
  1654  						TotalEngagedUsers: 10,
  1655  					},
  1656  					{
  1657  						Name:              "ruby",
  1658  						TotalEngagedUsers: 10,
  1659  					},
  1660  				},
  1661  				Editors: []*CopilotIDECodeCompletionsEditor{
  1662  					{
  1663  						Name:              "vscode",
  1664  						TotalEngagedUsers: 13,
  1665  						Models: []*CopilotIDECodeCompletionsModel{
  1666  							{
  1667  								Name:                    "default",
  1668  								IsCustomModel:           false,
  1669  								CustomModelTrainingDate: nil,
  1670  								TotalEngagedUsers:       13,
  1671  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  1672  									{
  1673  										Name:                    "python",
  1674  										TotalEngagedUsers:       6,
  1675  										TotalCodeSuggestions:    249,
  1676  										TotalCodeAcceptances:    123,
  1677  										TotalCodeLinesSuggested: 225,
  1678  										TotalCodeLinesAccepted:  135,
  1679  									},
  1680  									{
  1681  										Name:                    "ruby",
  1682  										TotalEngagedUsers:       7,
  1683  										TotalCodeSuggestions:    496,
  1684  										TotalCodeAcceptances:    253,
  1685  										TotalCodeLinesSuggested: 520,
  1686  										TotalCodeLinesAccepted:  270,
  1687  									},
  1688  								},
  1689  							},
  1690  						},
  1691  					},
  1692  					{
  1693  						Name:              "neovim",
  1694  						TotalEngagedUsers: 7,
  1695  						Models: []*CopilotIDECodeCompletionsModel{
  1696  							{
  1697  								Name:                    "a-custom-model",
  1698  								IsCustomModel:           true,
  1699  								CustomModelTrainingDate: Ptr("2024-02-01"),
  1700  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  1701  									{
  1702  										Name:                    "typescript",
  1703  										TotalEngagedUsers:       3,
  1704  										TotalCodeSuggestions:    112,
  1705  										TotalCodeAcceptances:    56,
  1706  										TotalCodeLinesSuggested: 143,
  1707  										TotalCodeLinesAccepted:  61,
  1708  									},
  1709  									{
  1710  										Name:                    "go",
  1711  										TotalEngagedUsers:       4,
  1712  										TotalCodeSuggestions:    132,
  1713  										TotalCodeAcceptances:    67,
  1714  										TotalCodeLinesSuggested: 154,
  1715  										TotalCodeLinesAccepted:  72,
  1716  									},
  1717  								},
  1718  							},
  1719  						},
  1720  					},
  1721  				},
  1722  			},
  1723  			CopilotIDEChat: &CopilotIDEChat{
  1724  				TotalEngagedUsers: 13,
  1725  				Editors: []*CopilotIDEChatEditor{
  1726  					{
  1727  						Name:              "vscode",
  1728  						TotalEngagedUsers: 13,
  1729  						Models: []*CopilotIDEChatModel{
  1730  							{
  1731  								Name:                     "default",
  1732  								IsCustomModel:            false,
  1733  								CustomModelTrainingDate:  nil,
  1734  								TotalEngagedUsers:        12,
  1735  								TotalChats:               45,
  1736  								TotalChatInsertionEvents: 12,
  1737  								TotalChatCopyEvents:      16,
  1738  							},
  1739  							{
  1740  								Name:                     "a-custom-model",
  1741  								IsCustomModel:            true,
  1742  								CustomModelTrainingDate:  Ptr("2024-02-01"),
  1743  								TotalEngagedUsers:        1,
  1744  								TotalChats:               10,
  1745  								TotalChatInsertionEvents: 11,
  1746  								TotalChatCopyEvents:      3,
  1747  							},
  1748  						},
  1749  					},
  1750  				},
  1751  			},
  1752  			CopilotDotcomChat: &CopilotDotcomChat{
  1753  				TotalEngagedUsers: 14,
  1754  				Models: []*CopilotDotcomChatModel{
  1755  					{
  1756  						Name:                    "default",
  1757  						IsCustomModel:           false,
  1758  						CustomModelTrainingDate: nil,
  1759  						TotalEngagedUsers:       14,
  1760  						TotalChats:              38,
  1761  					},
  1762  				},
  1763  			},
  1764  			CopilotDotcomPullRequests: &CopilotDotcomPullRequests{
  1765  				TotalEngagedUsers: 12,
  1766  				Repositories: []*CopilotDotcomPullRequestsRepository{
  1767  					{
  1768  						Name:              "demo/repo1",
  1769  						TotalEngagedUsers: 8,
  1770  						Models: []*CopilotDotcomPullRequestsModel{
  1771  							{
  1772  								Name:                    "default",
  1773  								IsCustomModel:           false,
  1774  								CustomModelTrainingDate: nil,
  1775  								TotalPRSummariesCreated: 6,
  1776  								TotalEngagedUsers:       8,
  1777  							},
  1778  						},
  1779  					},
  1780  					{
  1781  						Name:              "demo/repo2",
  1782  						TotalEngagedUsers: 4,
  1783  						Models: []*CopilotDotcomPullRequestsModel{
  1784  							{
  1785  								Name:                    "a-custom-model",
  1786  								IsCustomModel:           true,
  1787  								CustomModelTrainingDate: Ptr("2024-02-01"),
  1788  								TotalPRSummariesCreated: 10,
  1789  								TotalEngagedUsers:       4,
  1790  							},
  1791  						},
  1792  					},
  1793  				},
  1794  			},
  1795  		},
  1796  	}
  1797  
  1798  	if !cmp.Equal(got, want) {
  1799  		t.Errorf("Copilot.GetEnterpriseTeamMetrics returned %+v, want %+v", got, want)
  1800  	}
  1801  
  1802  	const methodName = "GetEnterpriseTeamMetrics"
  1803  
  1804  	testBadOptions(t, methodName, func() (err error) {
  1805  		_, _, err = client.Copilot.GetEnterpriseTeamMetrics(ctx, "\n", "t", &CopilotMetricsListOptions{})
  1806  		return err
  1807  	})
  1808  
  1809  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  1810  		got, resp, err := client.Copilot.GetEnterpriseTeamMetrics(ctx, "e", "t", &CopilotMetricsListOptions{})
  1811  		if got != nil {
  1812  			t.Errorf("Copilot.GetEnterpriseTeamMetrics returned %+v, want nil", got)
  1813  		}
  1814  		return resp, err
  1815  	})
  1816  }
  1817  
  1818  func TestCopilotService_GetOrganizationMetrics(t *testing.T) {
  1819  	t.Parallel()
  1820  	client, mux, _ := setup(t)
  1821  
  1822  	mux.HandleFunc("/orgs/o/copilot/metrics", func(w http.ResponseWriter, r *http.Request) {
  1823  		testMethod(t, r, "GET")
  1824  		fmt.Fprint(w, `[
  1825  			{
  1826  				"date": "2024-06-24",
  1827  				"total_active_users": 24,
  1828  				"total_engaged_users": 20,
  1829  				"copilot_ide_code_completions": {
  1830  				"total_engaged_users": 20,
  1831  				"languages": [
  1832  					{
  1833  					"name": "python",
  1834  					"total_engaged_users": 10
  1835  					},
  1836  					{
  1837  					"name": "ruby",
  1838  					"total_engaged_users": 10
  1839  					}
  1840  				],
  1841  				"editors": [
  1842  					{
  1843  					"name": "vscode",
  1844  					"total_engaged_users": 13,
  1845  					"models": [
  1846  						{
  1847  						"name": "default",
  1848  						"is_custom_model": false,
  1849  						"custom_model_training_date": null,
  1850  						"total_engaged_users": 13,
  1851  						"languages": [
  1852  							{
  1853  							"name": "python",
  1854  							"total_engaged_users": 6,
  1855  							"total_code_suggestions": 249,
  1856  							"total_code_acceptances": 123,
  1857  							"total_code_lines_suggested": 225,
  1858  							"total_code_lines_accepted": 135
  1859  							},
  1860  							{
  1861  							"name": "ruby",
  1862  							"total_engaged_users": 7,
  1863  							"total_code_suggestions": 496,
  1864  							"total_code_acceptances": 253,
  1865  							"total_code_lines_suggested": 520,
  1866  							"total_code_lines_accepted": 270
  1867  							}
  1868  						]
  1869  						}
  1870  					]
  1871  					},
  1872  					{
  1873  					"name": "neovim",
  1874  					"total_engaged_users": 7,
  1875  					"models": [
  1876  						{
  1877  						"name": "a-custom-model",
  1878  						"is_custom_model": true,
  1879  						"custom_model_training_date": "2024-02-01",
  1880  						"languages": [
  1881  							{
  1882  							"name": "typescript",
  1883  							"total_engaged_users": 3,
  1884  							"total_code_suggestions": 112,
  1885  							"total_code_acceptances": 56,
  1886  							"total_code_lines_suggested": 143,
  1887  							"total_code_lines_accepted": 61
  1888  							},
  1889  							{
  1890  							"name": "go",
  1891  							"total_engaged_users": 4,
  1892  							"total_code_suggestions": 132,
  1893  							"total_code_acceptances": 67,
  1894  							"total_code_lines_suggested": 154,
  1895  							"total_code_lines_accepted": 72
  1896  							}
  1897  						]
  1898  						}
  1899  					]
  1900  					}
  1901  				]
  1902  				},
  1903  				"copilot_ide_chat": {
  1904  				"total_engaged_users": 13,
  1905  				"editors": [
  1906  					{
  1907  					"name": "vscode",
  1908  					"total_engaged_users": 13,
  1909  					"models": [
  1910  						{
  1911  						"name": "default",
  1912  						"is_custom_model": false,
  1913  						"custom_model_training_date": null,
  1914  						"total_engaged_users": 12,
  1915  						"total_chats": 45,
  1916  						"total_chat_insertion_events": 12,
  1917  						"total_chat_copy_events": 16
  1918  						},
  1919  						{
  1920  						"name": "a-custom-model",
  1921  						"is_custom_model": true,
  1922  						"custom_model_training_date": "2024-02-01",
  1923  						"total_engaged_users": 1,
  1924  						"total_chats": 10,
  1925  						"total_chat_insertion_events": 11,
  1926  						"total_chat_copy_events": 3
  1927  						}
  1928  					]
  1929  					}
  1930  				]
  1931  				},
  1932  				"copilot_dotcom_chat": {
  1933  				"total_engaged_users": 14,
  1934  				"models": [
  1935  					{
  1936  					"name": "default",
  1937  					"is_custom_model": false,
  1938  					"custom_model_training_date": null,
  1939  					"total_engaged_users": 14,
  1940  					"total_chats": 38
  1941  					}
  1942  				]
  1943  				},
  1944  				"copilot_dotcom_pull_requests": {
  1945  				"total_engaged_users": 12,
  1946  				"repositories": [
  1947  					{
  1948  					"name": "demo/repo1",
  1949  					"total_engaged_users": 8,
  1950  					"models": [
  1951  						{
  1952  						"name": "default",
  1953  						"is_custom_model": false,
  1954  						"custom_model_training_date": null,
  1955  						"total_pr_summaries_created": 6,
  1956  						"total_engaged_users": 8
  1957  						}
  1958  					]
  1959  					},
  1960  					{
  1961  					"name": "demo/repo2",
  1962  					"total_engaged_users": 4,
  1963  					"models": [
  1964  						{
  1965  						"name": "a-custom-model",
  1966  						"is_custom_model": true,
  1967  						"custom_model_training_date": "2024-02-01",
  1968  						"total_pr_summaries_created": 10,
  1969  						"total_engaged_users": 4
  1970  						}
  1971  					]
  1972  					}
  1973  				]
  1974  				}
  1975  			}
  1976  		]`)
  1977  	})
  1978  
  1979  	ctx := context.Background()
  1980  	got, _, err := client.Copilot.GetOrganizationMetrics(ctx, "o", &CopilotMetricsListOptions{})
  1981  	if err != nil {
  1982  		t.Errorf("Copilot.GetOrganizationMetrics returned error: %v", err)
  1983  	}
  1984  
  1985  	totalActiveUsers := 24
  1986  	totalEngagedUsers := 20
  1987  	want := []*CopilotMetrics{
  1988  		{
  1989  			Date:              "2024-06-24",
  1990  			TotalActiveUsers:  &totalActiveUsers,
  1991  			TotalEngagedUsers: &totalEngagedUsers,
  1992  			CopilotIDECodeCompletions: &CopilotIDECodeCompletions{
  1993  				TotalEngagedUsers: 20,
  1994  				Languages: []*CopilotIDECodeCompletionsLanguage{
  1995  					{
  1996  						Name:              "python",
  1997  						TotalEngagedUsers: 10,
  1998  					},
  1999  					{
  2000  						Name:              "ruby",
  2001  						TotalEngagedUsers: 10,
  2002  					},
  2003  				},
  2004  				Editors: []*CopilotIDECodeCompletionsEditor{
  2005  					{
  2006  						Name:              "vscode",
  2007  						TotalEngagedUsers: 13,
  2008  						Models: []*CopilotIDECodeCompletionsModel{
  2009  							{
  2010  								Name:                    "default",
  2011  								IsCustomModel:           false,
  2012  								CustomModelTrainingDate: nil,
  2013  								TotalEngagedUsers:       13,
  2014  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  2015  									{
  2016  										Name:                    "python",
  2017  										TotalEngagedUsers:       6,
  2018  										TotalCodeSuggestions:    249,
  2019  										TotalCodeAcceptances:    123,
  2020  										TotalCodeLinesSuggested: 225,
  2021  										TotalCodeLinesAccepted:  135,
  2022  									},
  2023  									{
  2024  										Name:                    "ruby",
  2025  										TotalEngagedUsers:       7,
  2026  										TotalCodeSuggestions:    496,
  2027  										TotalCodeAcceptances:    253,
  2028  										TotalCodeLinesSuggested: 520,
  2029  										TotalCodeLinesAccepted:  270,
  2030  									},
  2031  								},
  2032  							},
  2033  						},
  2034  					},
  2035  					{
  2036  						Name:              "neovim",
  2037  						TotalEngagedUsers: 7,
  2038  						Models: []*CopilotIDECodeCompletionsModel{
  2039  							{
  2040  								Name:                    "a-custom-model",
  2041  								IsCustomModel:           true,
  2042  								CustomModelTrainingDate: Ptr("2024-02-01"),
  2043  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  2044  									{
  2045  										Name:                    "typescript",
  2046  										TotalEngagedUsers:       3,
  2047  										TotalCodeSuggestions:    112,
  2048  										TotalCodeAcceptances:    56,
  2049  										TotalCodeLinesSuggested: 143,
  2050  										TotalCodeLinesAccepted:  61,
  2051  									},
  2052  									{
  2053  										Name:                    "go",
  2054  										TotalEngagedUsers:       4,
  2055  										TotalCodeSuggestions:    132,
  2056  										TotalCodeAcceptances:    67,
  2057  										TotalCodeLinesSuggested: 154,
  2058  										TotalCodeLinesAccepted:  72,
  2059  									},
  2060  								},
  2061  							},
  2062  						},
  2063  					},
  2064  				},
  2065  			},
  2066  			CopilotIDEChat: &CopilotIDEChat{
  2067  				TotalEngagedUsers: 13,
  2068  				Editors: []*CopilotIDEChatEditor{
  2069  					{
  2070  						Name:              "vscode",
  2071  						TotalEngagedUsers: 13,
  2072  						Models: []*CopilotIDEChatModel{
  2073  							{
  2074  								Name:                     "default",
  2075  								IsCustomModel:            false,
  2076  								CustomModelTrainingDate:  nil,
  2077  								TotalEngagedUsers:        12,
  2078  								TotalChats:               45,
  2079  								TotalChatInsertionEvents: 12,
  2080  								TotalChatCopyEvents:      16,
  2081  							},
  2082  							{
  2083  								Name:                     "a-custom-model",
  2084  								IsCustomModel:            true,
  2085  								CustomModelTrainingDate:  Ptr("2024-02-01"),
  2086  								TotalEngagedUsers:        1,
  2087  								TotalChats:               10,
  2088  								TotalChatInsertionEvents: 11,
  2089  								TotalChatCopyEvents:      3,
  2090  							},
  2091  						},
  2092  					},
  2093  				},
  2094  			},
  2095  			CopilotDotcomChat: &CopilotDotcomChat{
  2096  				TotalEngagedUsers: 14,
  2097  				Models: []*CopilotDotcomChatModel{
  2098  					{
  2099  						Name:                    "default",
  2100  						IsCustomModel:           false,
  2101  						CustomModelTrainingDate: nil,
  2102  						TotalEngagedUsers:       14,
  2103  						TotalChats:              38,
  2104  					},
  2105  				},
  2106  			},
  2107  			CopilotDotcomPullRequests: &CopilotDotcomPullRequests{
  2108  				TotalEngagedUsers: 12,
  2109  				Repositories: []*CopilotDotcomPullRequestsRepository{
  2110  					{
  2111  						Name:              "demo/repo1",
  2112  						TotalEngagedUsers: 8,
  2113  						Models: []*CopilotDotcomPullRequestsModel{
  2114  							{
  2115  								Name:                    "default",
  2116  								IsCustomModel:           false,
  2117  								CustomModelTrainingDate: nil,
  2118  								TotalPRSummariesCreated: 6,
  2119  								TotalEngagedUsers:       8,
  2120  							},
  2121  						},
  2122  					},
  2123  					{
  2124  						Name:              "demo/repo2",
  2125  						TotalEngagedUsers: 4,
  2126  						Models: []*CopilotDotcomPullRequestsModel{
  2127  							{
  2128  								Name:                    "a-custom-model",
  2129  								IsCustomModel:           true,
  2130  								CustomModelTrainingDate: Ptr("2024-02-01"),
  2131  								TotalPRSummariesCreated: 10,
  2132  								TotalEngagedUsers:       4,
  2133  							},
  2134  						},
  2135  					},
  2136  				},
  2137  			},
  2138  		},
  2139  	}
  2140  
  2141  	if !cmp.Equal(got, want) {
  2142  		t.Errorf("Copilot.GetOrganizationMetrics returned %+v, want %+v", got, want)
  2143  	}
  2144  
  2145  	const methodName = "GetOrganizationMetrics"
  2146  
  2147  	testBadOptions(t, methodName, func() (err error) {
  2148  		_, _, err = client.Copilot.GetOrganizationMetrics(ctx, "\n", &CopilotMetricsListOptions{})
  2149  		return err
  2150  	})
  2151  
  2152  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2153  		got, resp, err := client.Copilot.GetOrganizationMetrics(ctx, "o", &CopilotMetricsListOptions{})
  2154  		if got != nil {
  2155  			t.Errorf("Copilot.GetOrganizationMetrics returned %+v, want nil", got)
  2156  		}
  2157  		return resp, err
  2158  	})
  2159  }
  2160  
  2161  func TestCopilotService_GetOrganizationTeamMetrics(t *testing.T) {
  2162  	t.Parallel()
  2163  	client, mux, _ := setup(t)
  2164  
  2165  	mux.HandleFunc("/orgs/o/team/t/copilot/metrics", func(w http.ResponseWriter, r *http.Request) {
  2166  		testMethod(t, r, "GET")
  2167  		fmt.Fprint(w, `[
  2168  			{
  2169  				"date": "2024-06-24",
  2170  				"total_active_users": 24,
  2171  				"total_engaged_users": 20,
  2172  				"copilot_ide_code_completions": {
  2173  					"total_engaged_users": 20,
  2174  					"languages": [
  2175  						{
  2176  							"name": "python",
  2177  							"total_engaged_users": 10
  2178  						},
  2179  						{
  2180  							"name": "ruby",
  2181  							"total_engaged_users": 10
  2182  						}
  2183  					],
  2184  					"editors": [
  2185  						{
  2186  							"name": "vscode",
  2187  							"total_engaged_users": 13,
  2188  							"models": [
  2189  								{
  2190  									"name": "default",
  2191  									"is_custom_model": false,
  2192  									"custom_model_training_date": null,
  2193  									"total_engaged_users": 13,
  2194  									"languages": [
  2195  										{
  2196  											"name": "python",
  2197  											"total_engaged_users": 6,
  2198  											"total_code_suggestions": 249,
  2199  											"total_code_acceptances": 123,
  2200  											"total_code_lines_suggested": 225,
  2201  											"total_code_lines_accepted": 135
  2202  										},
  2203  										{
  2204  											"name": "ruby",
  2205  											"total_engaged_users": 7,
  2206  											"total_code_suggestions": 496,
  2207  											"total_code_acceptances": 253,
  2208  											"total_code_lines_suggested": 520,
  2209  											"total_code_lines_accepted": 270
  2210  										}
  2211  									]
  2212  								}
  2213  							]
  2214  						},
  2215  						{
  2216  							"name": "neovim",
  2217  							"total_engaged_users": 7,
  2218  							"models": [
  2219  								{
  2220  									"name": "a-custom-model",
  2221  									"is_custom_model": true,
  2222  									"custom_model_training_date": "2024-02-01",
  2223  									"languages": [
  2224  										{
  2225  											"name": "typescript",
  2226  											"total_engaged_users": 3,
  2227  											"total_code_suggestions": 112,
  2228  											"total_code_acceptances": 56,
  2229  											"total_code_lines_suggested": 143,
  2230  											"total_code_lines_accepted": 61
  2231  										},
  2232  										{
  2233  											"name": "go",
  2234  											"total_engaged_users": 4,
  2235  											"total_code_suggestions": 132,
  2236  											"total_code_acceptances": 67,
  2237  											"total_code_lines_suggested": 154,
  2238  											"total_code_lines_accepted": 72
  2239  										}
  2240  									]
  2241  								}
  2242  							]
  2243  						}
  2244  					]
  2245  				},
  2246  				"copilot_ide_chat": {
  2247  					"total_engaged_users": 13,
  2248  					"editors": [
  2249  						{
  2250  							"name": "vscode",
  2251  							"total_engaged_users": 13,
  2252  							"models": [
  2253  								{
  2254  									"name": "default",
  2255  									"is_custom_model": false,
  2256  									"custom_model_training_date": null,
  2257  									"total_engaged_users": 12,
  2258  									"total_chats": 45,
  2259  									"total_chat_insertion_events": 12,
  2260  									"total_chat_copy_events": 16
  2261  								},
  2262  								{
  2263  									"name": "a-custom-model",
  2264  									"is_custom_model": true,
  2265  									"custom_model_training_date": "2024-02-01",
  2266  									"total_engaged_users": 1,
  2267  									"total_chats": 10,
  2268  									"total_chat_insertion_events": 11,
  2269  									"total_chat_copy_events": 3
  2270  								}
  2271  							]
  2272  						}
  2273  					]
  2274  				},
  2275  				"copilot_dotcom_chat": {
  2276  					"total_engaged_users": 14,
  2277  					"models": [
  2278  						{
  2279  							"name": "default",
  2280  							"is_custom_model": false,
  2281  							"custom_model_training_date": null,
  2282  							"total_engaged_users": 14,
  2283  							"total_chats": 38
  2284  						}
  2285  					]
  2286  				},
  2287  				"copilot_dotcom_pull_requests": {
  2288  					"total_engaged_users": 12,
  2289  					"repositories": [
  2290  						{
  2291  							"name": "demo/repo1",
  2292  							"total_engaged_users": 8,
  2293  							"models": [
  2294  								{
  2295  									"name": "default",
  2296  									"is_custom_model": false,
  2297  									"custom_model_training_date": null,
  2298  									"total_pr_summaries_created": 6,
  2299  									"total_engaged_users": 8
  2300  								}
  2301  							]
  2302  						},
  2303  						{
  2304  							"name": "demo/repo2",
  2305  							"total_engaged_users": 4,
  2306  							"models": [
  2307  								{
  2308  									"name": "a-custom-model",
  2309  									"is_custom_model": true,
  2310  									"custom_model_training_date": "2024-02-01",
  2311  									"total_pr_summaries_created": 10,
  2312  									"total_engaged_users": 4
  2313  								}
  2314  							]
  2315  						}
  2316  					]
  2317  				}
  2318  			}
  2319  		]`)
  2320  	})
  2321  
  2322  	ctx := context.Background()
  2323  	got, _, err := client.Copilot.GetOrganizationTeamMetrics(ctx, "o", "t", &CopilotMetricsListOptions{})
  2324  	if err != nil {
  2325  		t.Errorf("Copilot.GetOrganizationTeamMetrics returned error: %v", err)
  2326  	}
  2327  
  2328  	totalActiveUsers := 24
  2329  	totalEngagedUsers := 20
  2330  	want := []*CopilotMetrics{
  2331  		{
  2332  			Date:              "2024-06-24",
  2333  			TotalActiveUsers:  &totalActiveUsers,
  2334  			TotalEngagedUsers: &totalEngagedUsers,
  2335  			CopilotIDECodeCompletions: &CopilotIDECodeCompletions{
  2336  				TotalEngagedUsers: 20,
  2337  				Languages: []*CopilotIDECodeCompletionsLanguage{
  2338  					{
  2339  						Name:              "python",
  2340  						TotalEngagedUsers: 10,
  2341  					},
  2342  					{
  2343  						Name:              "ruby",
  2344  						TotalEngagedUsers: 10,
  2345  					},
  2346  				},
  2347  				Editors: []*CopilotIDECodeCompletionsEditor{
  2348  					{
  2349  						Name:              "vscode",
  2350  						TotalEngagedUsers: 13,
  2351  						Models: []*CopilotIDECodeCompletionsModel{
  2352  							{
  2353  								Name:                    "default",
  2354  								IsCustomModel:           false,
  2355  								CustomModelTrainingDate: nil,
  2356  								TotalEngagedUsers:       13,
  2357  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  2358  									{
  2359  										Name:                    "python",
  2360  										TotalEngagedUsers:       6,
  2361  										TotalCodeSuggestions:    249,
  2362  										TotalCodeAcceptances:    123,
  2363  										TotalCodeLinesSuggested: 225,
  2364  										TotalCodeLinesAccepted:  135,
  2365  									},
  2366  									{
  2367  										Name:                    "ruby",
  2368  										TotalEngagedUsers:       7,
  2369  										TotalCodeSuggestions:    496,
  2370  										TotalCodeAcceptances:    253,
  2371  										TotalCodeLinesSuggested: 520,
  2372  										TotalCodeLinesAccepted:  270,
  2373  									},
  2374  								},
  2375  							},
  2376  						},
  2377  					},
  2378  					{
  2379  						Name:              "neovim",
  2380  						TotalEngagedUsers: 7,
  2381  						Models: []*CopilotIDECodeCompletionsModel{
  2382  							{
  2383  								Name:                    "a-custom-model",
  2384  								IsCustomModel:           true,
  2385  								CustomModelTrainingDate: Ptr("2024-02-01"),
  2386  								Languages: []*CopilotIDECodeCompletionsModelLanguage{
  2387  									{
  2388  										Name:                    "typescript",
  2389  										TotalEngagedUsers:       3,
  2390  										TotalCodeSuggestions:    112,
  2391  										TotalCodeAcceptances:    56,
  2392  										TotalCodeLinesSuggested: 143,
  2393  										TotalCodeLinesAccepted:  61,
  2394  									},
  2395  									{
  2396  										Name:                    "go",
  2397  										TotalEngagedUsers:       4,
  2398  										TotalCodeSuggestions:    132,
  2399  										TotalCodeAcceptances:    67,
  2400  										TotalCodeLinesSuggested: 154,
  2401  										TotalCodeLinesAccepted:  72,
  2402  									},
  2403  								},
  2404  							},
  2405  						},
  2406  					},
  2407  				},
  2408  			},
  2409  			CopilotIDEChat: &CopilotIDEChat{
  2410  				TotalEngagedUsers: 13,
  2411  				Editors: []*CopilotIDEChatEditor{
  2412  					{
  2413  						Name:              "vscode",
  2414  						TotalEngagedUsers: 13,
  2415  						Models: []*CopilotIDEChatModel{
  2416  							{
  2417  								Name:                     "default",
  2418  								IsCustomModel:            false,
  2419  								CustomModelTrainingDate:  nil,
  2420  								TotalEngagedUsers:        12,
  2421  								TotalChats:               45,
  2422  								TotalChatInsertionEvents: 12,
  2423  								TotalChatCopyEvents:      16,
  2424  							},
  2425  							{
  2426  								Name:                     "a-custom-model",
  2427  								IsCustomModel:            true,
  2428  								CustomModelTrainingDate:  Ptr("2024-02-01"),
  2429  								TotalEngagedUsers:        1,
  2430  								TotalChats:               10,
  2431  								TotalChatInsertionEvents: 11,
  2432  								TotalChatCopyEvents:      3,
  2433  							},
  2434  						},
  2435  					},
  2436  				},
  2437  			},
  2438  			CopilotDotcomChat: &CopilotDotcomChat{
  2439  				TotalEngagedUsers: 14,
  2440  				Models: []*CopilotDotcomChatModel{
  2441  					{
  2442  						Name:                    "default",
  2443  						IsCustomModel:           false,
  2444  						CustomModelTrainingDate: nil,
  2445  						TotalEngagedUsers:       14,
  2446  						TotalChats:              38,
  2447  					},
  2448  				},
  2449  			},
  2450  			CopilotDotcomPullRequests: &CopilotDotcomPullRequests{
  2451  				TotalEngagedUsers: 12,
  2452  				Repositories: []*CopilotDotcomPullRequestsRepository{
  2453  					{
  2454  						Name:              "demo/repo1",
  2455  						TotalEngagedUsers: 8,
  2456  						Models: []*CopilotDotcomPullRequestsModel{
  2457  							{
  2458  								Name:                    "default",
  2459  								IsCustomModel:           false,
  2460  								CustomModelTrainingDate: nil,
  2461  								TotalPRSummariesCreated: 6,
  2462  								TotalEngagedUsers:       8,
  2463  							},
  2464  						},
  2465  					},
  2466  					{
  2467  						Name:              "demo/repo2",
  2468  						TotalEngagedUsers: 4,
  2469  						Models: []*CopilotDotcomPullRequestsModel{
  2470  							{
  2471  								Name:                    "a-custom-model",
  2472  								IsCustomModel:           true,
  2473  								CustomModelTrainingDate: Ptr("2024-02-01"),
  2474  								TotalPRSummariesCreated: 10,
  2475  								TotalEngagedUsers:       4,
  2476  							},
  2477  						},
  2478  					},
  2479  				},
  2480  			},
  2481  		},
  2482  	}
  2483  
  2484  	if !cmp.Equal(got, want) {
  2485  		t.Errorf("Copilot.GetOrganizationTeamMetrics returned %+v, want %+v", got, want)
  2486  	}
  2487  
  2488  	const methodName = "GetOrganizationTeamMetrics"
  2489  
  2490  	testBadOptions(t, methodName, func() (err error) {
  2491  		_, _, err = client.Copilot.GetOrganizationTeamMetrics(ctx, "\n", "\n", &CopilotMetricsListOptions{})
  2492  		return err
  2493  	})
  2494  
  2495  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
  2496  		got, resp, err := client.Copilot.GetOrganizationTeamMetrics(ctx, "o", "t", &CopilotMetricsListOptions{})
  2497  		if got != nil {
  2498  			t.Errorf("Copilot.GetOrganizationTeamMetrics returned %+v, want nil", got)
  2499  		}
  2500  		return resp, err
  2501  	})
  2502  }