github.com/google/go-github/v74@v74.0.0/github/billing_test.go (about)

     1  // Copyright 2021 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  	"fmt"
    11  	"net/http"
    12  	"testing"
    13  
    14  	"github.com/google/go-cmp/cmp"
    15  )
    16  
    17  func TestBillingService_GetActionsBillingOrg(t *testing.T) {
    18  	t.Parallel()
    19  	client, mux, _ := setup(t)
    20  
    21  	mux.HandleFunc("/orgs/o/settings/billing/actions", func(w http.ResponseWriter, r *http.Request) {
    22  		testMethod(t, r, "GET")
    23  		fmt.Fprint(w, `{
    24  				"total_minutes_used": 305.0,
    25  				"total_paid_minutes_used": 0.0,
    26  				"included_minutes": 3000.0,
    27  				"minutes_used_breakdown": {
    28  					"UBUNTU": 205,
    29  					"MACOS": 10,
    30  					"WINDOWS": 90
    31  				}
    32  			}`)
    33  	})
    34  
    35  	ctx := context.Background()
    36  	hook, _, err := client.Billing.GetActionsBillingOrg(ctx, "o")
    37  	if err != nil {
    38  		t.Errorf("Billing.GetActionsBillingOrg returned error: %v", err)
    39  	}
    40  
    41  	want := &ActionBilling{
    42  		TotalMinutesUsed:     305.0,
    43  		TotalPaidMinutesUsed: 0.0,
    44  		IncludedMinutes:      3000.0,
    45  		MinutesUsedBreakdown: MinutesUsedBreakdown{
    46  			"UBUNTU":  205,
    47  			"MACOS":   10,
    48  			"WINDOWS": 90,
    49  		},
    50  	}
    51  	if !cmp.Equal(hook, want) {
    52  		t.Errorf("Billing.GetActionsBillingOrg returned %+v, want %+v", hook, want)
    53  	}
    54  
    55  	const methodName = "GetActionsBillingOrg"
    56  	testBadOptions(t, methodName, func() (err error) {
    57  		_, _, err = client.Billing.GetActionsBillingOrg(ctx, "\n")
    58  		return err
    59  	})
    60  
    61  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    62  		got, resp, err := client.Billing.GetActionsBillingOrg(ctx, "o")
    63  		if got != nil {
    64  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    65  		}
    66  		return resp, err
    67  	})
    68  }
    69  
    70  func TestBillingService_GetActionsBillingOrg_invalidOrg(t *testing.T) {
    71  	t.Parallel()
    72  	client, _, _ := setup(t)
    73  
    74  	ctx := context.Background()
    75  	_, _, err := client.Billing.GetActionsBillingOrg(ctx, "%")
    76  	testURLParseError(t, err)
    77  }
    78  
    79  func TestBillingService_GetPackagesBillingOrg(t *testing.T) {
    80  	t.Parallel()
    81  	client, mux, _ := setup(t)
    82  
    83  	mux.HandleFunc("/orgs/o/settings/billing/packages", func(w http.ResponseWriter, r *http.Request) {
    84  		testMethod(t, r, "GET")
    85  		fmt.Fprint(w, `{
    86  				"total_gigabytes_bandwidth_used": 50,
    87  				"total_paid_gigabytes_bandwidth_used": 40,
    88  				"included_gigabytes_bandwidth": 10
    89  			}`)
    90  	})
    91  
    92  	ctx := context.Background()
    93  	hook, _, err := client.Billing.GetPackagesBillingOrg(ctx, "o")
    94  	if err != nil {
    95  		t.Errorf("Billing.GetPackagesBillingOrg returned error: %v", err)
    96  	}
    97  
    98  	want := &PackageBilling{
    99  		TotalGigabytesBandwidthUsed:     50,
   100  		TotalPaidGigabytesBandwidthUsed: 40,
   101  		IncludedGigabytesBandwidth:      10,
   102  	}
   103  	if !cmp.Equal(hook, want) {
   104  		t.Errorf("Billing.GetPackagesBillingOrg returned %+v, want %+v", hook, want)
   105  	}
   106  
   107  	const methodName = "GetPackagesBillingOrg"
   108  	testBadOptions(t, methodName, func() (err error) {
   109  		_, _, err = client.Billing.GetPackagesBillingOrg(ctx, "\n")
   110  		return err
   111  	})
   112  
   113  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   114  		got, resp, err := client.Billing.GetPackagesBillingOrg(ctx, "o")
   115  		if got != nil {
   116  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   117  		}
   118  		return resp, err
   119  	})
   120  }
   121  
   122  func TestBillingService_GetPackagesBillingOrg_invalidOrg(t *testing.T) {
   123  	t.Parallel()
   124  	client, _, _ := setup(t)
   125  
   126  	ctx := context.Background()
   127  	_, _, err := client.Billing.GetPackagesBillingOrg(ctx, "%")
   128  	testURLParseError(t, err)
   129  }
   130  
   131  func TestBillingService_GetStorageBillingOrg(t *testing.T) {
   132  	t.Parallel()
   133  	client, mux, _ := setup(t)
   134  
   135  	mux.HandleFunc("/orgs/o/settings/billing/shared-storage", func(w http.ResponseWriter, r *http.Request) {
   136  		testMethod(t, r, "GET")
   137  		fmt.Fprint(w, `{
   138  				"days_left_in_billing_cycle": 20,
   139  				"estimated_paid_storage_for_month": 15.25,
   140  				"estimated_storage_for_month": 40
   141  			}`)
   142  	})
   143  
   144  	ctx := context.Background()
   145  	hook, _, err := client.Billing.GetStorageBillingOrg(ctx, "o")
   146  	if err != nil {
   147  		t.Errorf("Billing.GetStorageBillingOrg returned error: %v", err)
   148  	}
   149  
   150  	want := &StorageBilling{
   151  		DaysLeftInBillingCycle:       20,
   152  		EstimatedPaidStorageForMonth: 15.25,
   153  		EstimatedStorageForMonth:     40,
   154  	}
   155  	if !cmp.Equal(hook, want) {
   156  		t.Errorf("Billing.GetStorageBillingOrg returned %+v, want %+v", hook, want)
   157  	}
   158  
   159  	const methodName = "GetStorageBillingOrg"
   160  	testBadOptions(t, methodName, func() (err error) {
   161  		_, _, err = client.Billing.GetStorageBillingOrg(ctx, "\n")
   162  		return err
   163  	})
   164  
   165  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   166  		got, resp, err := client.Billing.GetStorageBillingOrg(ctx, "o")
   167  		if got != nil {
   168  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   169  		}
   170  		return resp, err
   171  	})
   172  }
   173  
   174  func TestBillingService_GetStorageBillingOrg_invalidOrg(t *testing.T) {
   175  	t.Parallel()
   176  	client, _, _ := setup(t)
   177  
   178  	ctx := context.Background()
   179  	_, _, err := client.Billing.GetStorageBillingOrg(ctx, "%")
   180  	testURLParseError(t, err)
   181  }
   182  
   183  func TestBillingService_GetActionsBillingUser(t *testing.T) {
   184  	t.Parallel()
   185  	client, mux, _ := setup(t)
   186  
   187  	mux.HandleFunc("/users/u/settings/billing/actions", func(w http.ResponseWriter, r *http.Request) {
   188  		testMethod(t, r, "GET")
   189  		fmt.Fprint(w, `{
   190  				"total_minutes_used": 10,
   191  				"total_paid_minutes_used": 0,
   192  				"included_minutes": 3000,
   193  				"minutes_used_breakdown": {
   194  					"UBUNTU": 205,
   195  					"MACOS": 10,
   196  					"WINDOWS": 90
   197  				}
   198  			}`)
   199  	})
   200  
   201  	ctx := context.Background()
   202  	hook, _, err := client.Billing.GetActionsBillingUser(ctx, "u")
   203  	if err != nil {
   204  		t.Errorf("Billing.GetActionsBillingUser returned error: %v", err)
   205  	}
   206  
   207  	want := &ActionBilling{
   208  		TotalMinutesUsed:     10,
   209  		TotalPaidMinutesUsed: 0,
   210  		IncludedMinutes:      3000,
   211  		MinutesUsedBreakdown: MinutesUsedBreakdown{
   212  			"UBUNTU":  205,
   213  			"MACOS":   10,
   214  			"WINDOWS": 90,
   215  		},
   216  	}
   217  	if !cmp.Equal(hook, want) {
   218  		t.Errorf("Billing.GetActionsBillingUser returned %+v, want %+v", hook, want)
   219  	}
   220  
   221  	const methodName = "GetActionsBillingUser"
   222  	testBadOptions(t, methodName, func() (err error) {
   223  		_, _, err = client.Billing.GetActionsBillingOrg(ctx, "\n")
   224  		return err
   225  	})
   226  
   227  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   228  		got, resp, err := client.Billing.GetActionsBillingUser(ctx, "o")
   229  		if got != nil {
   230  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   231  		}
   232  		return resp, err
   233  	})
   234  }
   235  
   236  func TestBillingService_GetActionsBillingUser_invalidUser(t *testing.T) {
   237  	t.Parallel()
   238  	client, _, _ := setup(t)
   239  
   240  	ctx := context.Background()
   241  	_, _, err := client.Billing.GetActionsBillingUser(ctx, "%")
   242  	testURLParseError(t, err)
   243  }
   244  
   245  func TestBillingService_GetPackagesBillingUser(t *testing.T) {
   246  	t.Parallel()
   247  	client, mux, _ := setup(t)
   248  
   249  	mux.HandleFunc("/users/u/settings/billing/packages", func(w http.ResponseWriter, r *http.Request) {
   250  		testMethod(t, r, "GET")
   251  		fmt.Fprint(w, `{
   252  				"total_gigabytes_bandwidth_used": 50,
   253  				"total_paid_gigabytes_bandwidth_used": 40,
   254  				"included_gigabytes_bandwidth": 10
   255  			}`)
   256  	})
   257  
   258  	ctx := context.Background()
   259  	hook, _, err := client.Billing.GetPackagesBillingUser(ctx, "u")
   260  	if err != nil {
   261  		t.Errorf("Billing.GetPackagesBillingUser returned error: %v", err)
   262  	}
   263  
   264  	want := &PackageBilling{
   265  		TotalGigabytesBandwidthUsed:     50,
   266  		TotalPaidGigabytesBandwidthUsed: 40,
   267  		IncludedGigabytesBandwidth:      10,
   268  	}
   269  	if !cmp.Equal(hook, want) {
   270  		t.Errorf("Billing.GetPackagesBillingUser returned %+v, want %+v", hook, want)
   271  	}
   272  
   273  	const methodName = "GetPackagesBillingUser"
   274  	testBadOptions(t, methodName, func() (err error) {
   275  		_, _, err = client.Billing.GetPackagesBillingUser(ctx, "\n")
   276  		return err
   277  	})
   278  
   279  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   280  		got, resp, err := client.Billing.GetPackagesBillingUser(ctx, "o")
   281  		if got != nil {
   282  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   283  		}
   284  		return resp, err
   285  	})
   286  }
   287  
   288  func TestBillingService_GetPackagesBillingUser_invalidUser(t *testing.T) {
   289  	t.Parallel()
   290  	client, _, _ := setup(t)
   291  
   292  	ctx := context.Background()
   293  	_, _, err := client.Billing.GetPackagesBillingUser(ctx, "%")
   294  	testURLParseError(t, err)
   295  }
   296  
   297  func TestBillingService_GetStorageBillingUser(t *testing.T) {
   298  	t.Parallel()
   299  	client, mux, _ := setup(t)
   300  
   301  	mux.HandleFunc("/users/u/settings/billing/shared-storage", func(w http.ResponseWriter, r *http.Request) {
   302  		testMethod(t, r, "GET")
   303  		fmt.Fprint(w, `{
   304  				"days_left_in_billing_cycle": 20,
   305  				"estimated_paid_storage_for_month": 15.25,
   306  				"estimated_storage_for_month": 40
   307  			}`)
   308  	})
   309  
   310  	ctx := context.Background()
   311  	hook, _, err := client.Billing.GetStorageBillingUser(ctx, "u")
   312  	if err != nil {
   313  		t.Errorf("Billing.GetStorageBillingUser returned error: %v", err)
   314  	}
   315  
   316  	want := &StorageBilling{
   317  		DaysLeftInBillingCycle:       20,
   318  		EstimatedPaidStorageForMonth: 15.25,
   319  		EstimatedStorageForMonth:     40,
   320  	}
   321  	if !cmp.Equal(hook, want) {
   322  		t.Errorf("Billing.GetStorageBillingUser returned %+v, want %+v", hook, want)
   323  	}
   324  
   325  	const methodName = "GetStorageBillingUser"
   326  	testBadOptions(t, methodName, func() (err error) {
   327  		_, _, err = client.Billing.GetStorageBillingUser(ctx, "\n")
   328  		return err
   329  	})
   330  
   331  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   332  		got, resp, err := client.Billing.GetStorageBillingUser(ctx, "o")
   333  		if got != nil {
   334  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   335  		}
   336  		return resp, err
   337  	})
   338  }
   339  
   340  func TestBillingService_GetStorageBillingUser_invalidUser(t *testing.T) {
   341  	t.Parallel()
   342  	client, _, _ := setup(t)
   343  
   344  	ctx := context.Background()
   345  	_, _, err := client.Billing.GetStorageBillingUser(ctx, "%")
   346  	testURLParseError(t, err)
   347  }
   348  
   349  func TestMinutesUsedBreakdown_Marshal(t *testing.T) {
   350  	t.Parallel()
   351  	testJSONMarshal(t, &MinutesUsedBreakdown{}, "{}")
   352  
   353  	u := &MinutesUsedBreakdown{
   354  		"UBUNTU":  1,
   355  		"MACOS":   1,
   356  		"WINDOWS": 1,
   357  	}
   358  
   359  	want := `{
   360  		"UBUNTU": 1,
   361  		"MACOS": 1,
   362  		"WINDOWS": 1
   363  	}`
   364  
   365  	testJSONMarshal(t, u, want)
   366  }
   367  
   368  func TestActionBilling_Marshal(t *testing.T) {
   369  	t.Parallel()
   370  	testJSONMarshal(t, &MinutesUsedBreakdown{}, "{}")
   371  
   372  	u := &ActionBilling{
   373  		TotalMinutesUsed:     1,
   374  		TotalPaidMinutesUsed: 1,
   375  		IncludedMinutes:      1,
   376  		MinutesUsedBreakdown: MinutesUsedBreakdown{
   377  			"UBUNTU":  1,
   378  			"MACOS":   1,
   379  			"WINDOWS": 1,
   380  		},
   381  	}
   382  
   383  	want := `{
   384  		"total_minutes_used": 1,
   385  		"total_paid_minutes_used": 1,
   386  		"included_minutes": 1,
   387  		"minutes_used_breakdown": {
   388  			"UBUNTU": 1,
   389  			"MACOS": 1,
   390  			"WINDOWS": 1
   391  		}
   392  	}`
   393  
   394  	testJSONMarshal(t, u, want)
   395  }
   396  
   397  func TestPackageBilling_Marshal(t *testing.T) {
   398  	t.Parallel()
   399  	testJSONMarshal(t, &PackageBilling{}, "{}")
   400  
   401  	u := &PackageBilling{
   402  		TotalGigabytesBandwidthUsed:     1,
   403  		TotalPaidGigabytesBandwidthUsed: 1,
   404  		IncludedGigabytesBandwidth:      1,
   405  	}
   406  
   407  	want := `{
   408  		"total_gigabytes_bandwidth_used": 1,
   409  		"total_paid_gigabytes_bandwidth_used": 1,
   410  		"included_gigabytes_bandwidth": 1
   411  	}`
   412  
   413  	testJSONMarshal(t, u, want)
   414  }
   415  
   416  func TestStorageBilling_Marshal(t *testing.T) {
   417  	t.Parallel()
   418  	testJSONMarshal(t, &StorageBilling{}, "{}")
   419  
   420  	u := &StorageBilling{
   421  		DaysLeftInBillingCycle:       1,
   422  		EstimatedPaidStorageForMonth: 1,
   423  		EstimatedStorageForMonth:     1,
   424  	}
   425  
   426  	want := `{
   427  		"days_left_in_billing_cycle": 1,
   428  		"estimated_paid_storage_for_month": 1,
   429  		"estimated_storage_for_month": 1
   430  	}`
   431  
   432  	testJSONMarshal(t, u, want)
   433  }
   434  
   435  func TestBillingService_GetAdvancedSecurityActiveCommittersOrg(t *testing.T) {
   436  	t.Parallel()
   437  	client, mux, _ := setup(t)
   438  
   439  	mux.HandleFunc("/orgs/o/settings/billing/advanced-security", func(w http.ResponseWriter, r *http.Request) {
   440  		testMethod(t, r, "GET")
   441  		fmt.Fprint(w, `{
   442    "total_advanced_security_committers": 2,
   443    "total_count": 2,
   444    "maximum_advanced_security_committers": 3,
   445    "purchased_advanced_security_committers": 4,
   446    "repositories": [
   447      {
   448        "name": "octocat-org/Hello-World",
   449        "advanced_security_committers": 2,
   450        "advanced_security_committers_breakdown": [
   451          {
   452            "user_login": "octokitten",
   453            "last_pushed_date": "2021-10-25"
   454          }
   455        ]
   456      }
   457    ]
   458  }`)
   459  	})
   460  
   461  	ctx := context.Background()
   462  	opts := &ListOptions{Page: 2, PerPage: 50}
   463  	hook, _, err := client.Billing.GetAdvancedSecurityActiveCommittersOrg(ctx, "o", opts)
   464  	if err != nil {
   465  		t.Errorf("Billing.GetAdvancedSecurityActiveCommittersOrg	 returned error: %v", err)
   466  	}
   467  
   468  	want := &ActiveCommitters{
   469  		TotalAdvancedSecurityCommitters:     2,
   470  		TotalCount:                          2,
   471  		MaximumAdvancedSecurityCommitters:   3,
   472  		PurchasedAdvancedSecurityCommitters: 4,
   473  		Repositories: []*RepositoryActiveCommitters{
   474  			{
   475  				Name:                       Ptr("octocat-org/Hello-World"),
   476  				AdvancedSecurityCommitters: Ptr(2),
   477  				AdvancedSecurityCommittersBreakdown: []*AdvancedSecurityCommittersBreakdown{
   478  					{
   479  						UserLogin:      Ptr("octokitten"),
   480  						LastPushedDate: Ptr("2021-10-25"),
   481  					},
   482  				},
   483  			},
   484  		},
   485  	}
   486  	if !cmp.Equal(hook, want) {
   487  		t.Errorf("Billing.GetAdvancedSecurityActiveCommittersOrg returned %+v, want %+v", hook, want)
   488  	}
   489  
   490  	const methodName = "GetAdvancedSecurityActiveCommittersOrg"
   491  	testBadOptions(t, methodName, func() (err error) {
   492  		_, _, err = client.Billing.GetAdvancedSecurityActiveCommittersOrg(ctx, "\n", nil)
   493  		return err
   494  	})
   495  
   496  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   497  		got, resp, err := client.Billing.GetAdvancedSecurityActiveCommittersOrg(ctx, "o", nil)
   498  		if got != nil {
   499  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   500  		}
   501  		return resp, err
   502  	})
   503  }
   504  
   505  func TestBillingService_GetAdvancedSecurityActiveCommittersOrg_invalidOrg(t *testing.T) {
   506  	t.Parallel()
   507  	client, _, _ := setup(t)
   508  
   509  	ctx := context.Background()
   510  	_, _, err := client.Billing.GetAdvancedSecurityActiveCommittersOrg(ctx, "%", nil)
   511  	testURLParseError(t, err)
   512  }
   513  
   514  func TestBillingService_GetUsageReportOrg(t *testing.T) {
   515  	t.Parallel()
   516  	client, mux, _ := setup(t)
   517  
   518  	mux.HandleFunc("/organizations/o/settings/billing/usage", func(w http.ResponseWriter, r *http.Request) {
   519  		testMethod(t, r, "GET")
   520  		testFormValues(t, r, values{
   521  			"year":  "2023",
   522  			"month": "8",
   523  		})
   524  		fmt.Fprint(w, `{
   525  			"usageItems": [
   526  				{
   527  					"date": "2023-08-01",
   528  					"product": "Actions",
   529  					"sku": "Actions Linux",
   530  					"quantity": 100,
   531  					"unitType": "minutes",
   532  					"pricePerUnit": 0.008,
   533  					"grossAmount": 0.8,
   534  					"discountAmount": 0,
   535  					"netAmount": 0.8,
   536  					"organizationName": "GitHub",
   537  					"repositoryName": "github/example"
   538  				}
   539  			]
   540  		}`)
   541  	})
   542  
   543  	ctx := context.Background()
   544  	opts := &UsageReportOptions{
   545  		Year:  Ptr(2023),
   546  		Month: Ptr(8),
   547  	}
   548  	report, _, err := client.Billing.GetUsageReportOrg(ctx, "o", opts)
   549  	if err != nil {
   550  		t.Errorf("Billing.GetUsageReportOrg returned error: %v", err)
   551  	}
   552  
   553  	want := &UsageReport{
   554  		UsageItems: []*UsageItem{
   555  			{
   556  				Date:             Ptr("2023-08-01"),
   557  				Product:          Ptr("Actions"),
   558  				SKU:              Ptr("Actions Linux"),
   559  				Quantity:         Ptr(100.0),
   560  				UnitType:         Ptr("minutes"),
   561  				PricePerUnit:     Ptr(0.008),
   562  				GrossAmount:      Ptr(0.8),
   563  				DiscountAmount:   Ptr(0.0),
   564  				NetAmount:        Ptr(0.8),
   565  				OrganizationName: Ptr("GitHub"),
   566  				RepositoryName:   Ptr("github/example"),
   567  			},
   568  		},
   569  	}
   570  	if !cmp.Equal(report, want) {
   571  		t.Errorf("Billing.GetUsageReportOrg returned %+v, want %+v", report, want)
   572  	}
   573  
   574  	const methodName = "GetUsageReportOrg"
   575  	testBadOptions(t, methodName, func() (err error) {
   576  		_, _, err = client.Billing.GetUsageReportOrg(ctx, "\n", opts)
   577  		return err
   578  	})
   579  
   580  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   581  		got, resp, err := client.Billing.GetUsageReportOrg(ctx, "o", nil)
   582  		if got != nil {
   583  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   584  		}
   585  		return resp, err
   586  	})
   587  }
   588  
   589  func TestBillingService_GetUsageReportOrg_invalidOrg(t *testing.T) {
   590  	t.Parallel()
   591  	client, _, _ := setup(t)
   592  
   593  	ctx := context.Background()
   594  	_, _, err := client.Billing.GetUsageReportOrg(ctx, "%", nil)
   595  	testURLParseError(t, err)
   596  }
   597  
   598  func TestBillingService_GetUsageReportUser(t *testing.T) {
   599  	t.Parallel()
   600  	client, mux, _ := setup(t)
   601  
   602  	mux.HandleFunc("/users/u/settings/billing/usage", func(w http.ResponseWriter, r *http.Request) {
   603  		testMethod(t, r, "GET")
   604  		testFormValues(t, r, values{
   605  			"day": "15",
   606  		})
   607  		fmt.Fprint(w, `{
   608  			"usageItems": [
   609  				{
   610  					"date": "2023-08-15",
   611  					"product": "Codespaces",
   612  					"sku": "Codespaces Linux",
   613  					"quantity": 50,
   614  					"unitType": "hours",
   615  					"pricePerUnit": 0.18,
   616  					"grossAmount": 9.0,
   617  					"discountAmount": 1.0,
   618  					"netAmount": 8.0,
   619  					"repositoryName": "user/example"
   620  				}
   621  			]
   622  		}`)
   623  	})
   624  
   625  	ctx := context.Background()
   626  	opts := &UsageReportOptions{
   627  		Day: Ptr(15),
   628  	}
   629  	report, _, err := client.Billing.GetUsageReportUser(ctx, "u", opts)
   630  	if err != nil {
   631  		t.Errorf("Billing.GetUsageReportUser returned error: %v", err)
   632  	}
   633  
   634  	want := &UsageReport{
   635  		UsageItems: []*UsageItem{
   636  			{
   637  				Date:           Ptr("2023-08-15"),
   638  				Product:        Ptr("Codespaces"),
   639  				SKU:            Ptr("Codespaces Linux"),
   640  				Quantity:       Ptr(50.0),
   641  				UnitType:       Ptr("hours"),
   642  				PricePerUnit:   Ptr(0.18),
   643  				GrossAmount:    Ptr(9.0),
   644  				DiscountAmount: Ptr(1.0),
   645  				NetAmount:      Ptr(8.0),
   646  				RepositoryName: Ptr("user/example"),
   647  			},
   648  		},
   649  	}
   650  	if !cmp.Equal(report, want) {
   651  		t.Errorf("Billing.GetUsageReportUser returned %+v, want %+v", report, want)
   652  	}
   653  
   654  	const methodName = "GetUsageReportUser"
   655  	testBadOptions(t, methodName, func() (err error) {
   656  		_, _, err = client.Billing.GetUsageReportUser(ctx, "\n", opts)
   657  		return err
   658  	})
   659  
   660  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   661  		got, resp, err := client.Billing.GetUsageReportUser(ctx, "u", nil)
   662  		if got != nil {
   663  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   664  		}
   665  		return resp, err
   666  	})
   667  }
   668  
   669  func TestBillingService_GetUsageReportUser_invalidUser(t *testing.T) {
   670  	t.Parallel()
   671  	client, _, _ := setup(t)
   672  
   673  	ctx := context.Background()
   674  	_, _, err := client.Billing.GetUsageReportUser(ctx, "%", nil)
   675  	testURLParseError(t, err)
   676  }