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