github.com/google/go-github/v71@v71.0.0/github/orgs_properties_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 "fmt" 11 "net/http" 12 "testing" 13 14 "github.com/google/go-cmp/cmp" 15 ) 16 17 func TestOrganizationsService_GetAllCustomProperties(t *testing.T) { 18 t.Parallel() 19 client, mux, _ := setup(t) 20 21 mux.HandleFunc("/orgs/o/properties/schema", func(w http.ResponseWriter, r *http.Request) { 22 testMethod(t, r, "GET") 23 fmt.Fprint(w, `[ 24 { 25 "property_name": "name", 26 "value_type": "single_select", 27 "required": true, 28 "default_value": "production", 29 "description": "Prod or dev environment", 30 "allowed_values":[ 31 "production", 32 "development" 33 ], 34 "values_editable_by": "org_actors" 35 }, 36 { 37 "property_name": "service", 38 "value_type": "string" 39 }, 40 { 41 "property_name": "team", 42 "value_type": "string", 43 "description": "Team owning the repository" 44 } 45 ]`) 46 }) 47 48 ctx := context.Background() 49 properties, _, err := client.Organizations.GetAllCustomProperties(ctx, "o") 50 if err != nil { 51 t.Errorf("Organizations.GetAllCustomProperties returned error: %v", err) 52 } 53 54 want := []*CustomProperty{ 55 { 56 PropertyName: Ptr("name"), 57 ValueType: "single_select", 58 Required: Ptr(true), 59 DefaultValue: Ptr("production"), 60 Description: Ptr("Prod or dev environment"), 61 AllowedValues: []string{"production", "development"}, 62 ValuesEditableBy: Ptr("org_actors"), 63 }, 64 { 65 PropertyName: Ptr("service"), 66 ValueType: "string", 67 }, 68 { 69 PropertyName: Ptr("team"), 70 ValueType: "string", 71 Description: Ptr("Team owning the repository"), 72 }, 73 } 74 if !cmp.Equal(properties, want) { 75 t.Errorf("Organizations.GetAllCustomProperties returned %+v, want %+v", properties, want) 76 } 77 78 const methodName = "GetAllCustomProperties" 79 80 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 81 got, resp, err := client.Organizations.GetAllCustomProperties(ctx, "o") 82 if got != nil { 83 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 84 } 85 return resp, err 86 }) 87 } 88 89 func TestOrganizationsService_CreateOrUpdateCustomProperties(t *testing.T) { 90 t.Parallel() 91 client, mux, _ := setup(t) 92 93 mux.HandleFunc("/orgs/o/properties/schema", func(w http.ResponseWriter, r *http.Request) { 94 testMethod(t, r, "PATCH") 95 testBody(t, r, `{"properties":[{"property_name":"name","value_type":"single_select","required":true},{"property_name":"service","value_type":"string"}]}`+"\n") 96 fmt.Fprint(w, `[ 97 { 98 "property_name": "name", 99 "value_type": "single_select", 100 "required": true 101 }, 102 { 103 "property_name": "service", 104 "value_type": "string" 105 } 106 ]`) 107 }) 108 109 ctx := context.Background() 110 properties, _, err := client.Organizations.CreateOrUpdateCustomProperties(ctx, "o", []*CustomProperty{ 111 { 112 PropertyName: Ptr("name"), 113 ValueType: "single_select", 114 Required: Ptr(true), 115 }, 116 { 117 PropertyName: Ptr("service"), 118 ValueType: "string", 119 }, 120 }) 121 if err != nil { 122 t.Errorf("Organizations.CreateOrUpdateCustomProperties returned error: %v", err) 123 } 124 125 want := []*CustomProperty{ 126 { 127 PropertyName: Ptr("name"), 128 ValueType: "single_select", 129 Required: Ptr(true), 130 }, 131 { 132 PropertyName: Ptr("service"), 133 ValueType: "string", 134 }, 135 } 136 137 if !cmp.Equal(properties, want) { 138 t.Errorf("Organizations.CreateOrUpdateCustomProperties returned %+v, want %+v", properties, want) 139 } 140 141 const methodName = "CreateOrUpdateCustomProperties" 142 143 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 144 got, resp, err := client.Organizations.CreateOrUpdateCustomProperties(ctx, "o", nil) 145 if got != nil { 146 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 147 } 148 return resp, err 149 }) 150 } 151 152 func TestOrganizationsService_GetCustomProperty(t *testing.T) { 153 t.Parallel() 154 client, mux, _ := setup(t) 155 156 mux.HandleFunc("/orgs/o/properties/schema/name", func(w http.ResponseWriter, r *http.Request) { 157 testMethod(t, r, "GET") 158 fmt.Fprint(w, `{ 159 "property_name": "name", 160 "value_type": "single_select", 161 "required": true, 162 "default_value": "production", 163 "description": "Prod or dev environment", 164 "allowed_values":[ 165 "production", 166 "development" 167 ], 168 "values_editable_by": "org_actors" 169 }`) 170 }) 171 172 ctx := context.Background() 173 property, _, err := client.Organizations.GetCustomProperty(ctx, "o", "name") 174 if err != nil { 175 t.Errorf("Organizations.GetCustomProperty returned error: %v", err) 176 } 177 178 want := &CustomProperty{ 179 PropertyName: Ptr("name"), 180 ValueType: "single_select", 181 Required: Ptr(true), 182 DefaultValue: Ptr("production"), 183 Description: Ptr("Prod or dev environment"), 184 AllowedValues: []string{"production", "development"}, 185 ValuesEditableBy: Ptr("org_actors"), 186 } 187 if !cmp.Equal(property, want) { 188 t.Errorf("Organizations.GetCustomProperty returned %+v, want %+v", property, want) 189 } 190 191 const methodName = "GetCustomProperty" 192 193 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 194 got, resp, err := client.Organizations.GetCustomProperty(ctx, "o", "name") 195 if got != nil { 196 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 197 } 198 return resp, err 199 }) 200 } 201 202 func TestOrganizationsService_CreateOrUpdateCustomProperty(t *testing.T) { 203 t.Parallel() 204 client, mux, _ := setup(t) 205 206 mux.HandleFunc("/orgs/o/properties/schema/name", func(w http.ResponseWriter, r *http.Request) { 207 testMethod(t, r, "PUT") 208 fmt.Fprint(w, `{ 209 "property_name": "name", 210 "value_type": "single_select", 211 "required": true, 212 "default_value": "production", 213 "description": "Prod or dev environment", 214 "allowed_values":[ 215 "production", 216 "development" 217 ], 218 "values_editable_by": "org_actors" 219 }`) 220 }) 221 222 ctx := context.Background() 223 property, _, err := client.Organizations.CreateOrUpdateCustomProperty(ctx, "o", "name", &CustomProperty{ 224 ValueType: "single_select", 225 Required: Ptr(true), 226 DefaultValue: Ptr("production"), 227 Description: Ptr("Prod or dev environment"), 228 AllowedValues: []string{"production", "development"}, 229 ValuesEditableBy: Ptr("org_actors"), 230 }) 231 if err != nil { 232 t.Errorf("Organizations.CreateOrUpdateCustomProperty returned error: %v", err) 233 } 234 235 want := &CustomProperty{ 236 PropertyName: Ptr("name"), 237 ValueType: "single_select", 238 Required: Ptr(true), 239 DefaultValue: Ptr("production"), 240 Description: Ptr("Prod or dev environment"), 241 AllowedValues: []string{"production", "development"}, 242 ValuesEditableBy: Ptr("org_actors"), 243 } 244 if !cmp.Equal(property, want) { 245 t.Errorf("Organizations.CreateOrUpdateCustomProperty returned %+v, want %+v", property, want) 246 } 247 248 const methodName = "CreateOrUpdateCustomProperty" 249 250 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 251 got, resp, err := client.Organizations.CreateOrUpdateCustomProperty(ctx, "o", "name", nil) 252 if got != nil { 253 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 254 } 255 return resp, err 256 }) 257 } 258 259 func TestOrganizationsService_RemoveCustomProperty(t *testing.T) { 260 t.Parallel() 261 client, mux, _ := setup(t) 262 263 mux.HandleFunc("/orgs/o/properties/schema/name", func(w http.ResponseWriter, r *http.Request) { 264 testMethod(t, r, "DELETE") 265 }) 266 267 ctx := context.Background() 268 _, err := client.Organizations.RemoveCustomProperty(ctx, "o", "name") 269 if err != nil { 270 t.Errorf("Organizations.RemoveCustomProperty returned error: %v", err) 271 } 272 273 const methodName = "RemoveCustomProperty" 274 275 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 276 return client.Organizations.RemoveCustomProperty(ctx, "0", "name") 277 }) 278 } 279 280 func TestOrganizationsService_ListCustomPropertyValues(t *testing.T) { 281 t.Parallel() 282 client, mux, _ := setup(t) 283 284 mux.HandleFunc("/orgs/o/properties/values", func(w http.ResponseWriter, r *http.Request) { 285 testMethod(t, r, "GET") 286 testFormValues(t, r, values{"page": "1", "per_page": "100"}) 287 fmt.Fprint(w, `[{ 288 "repository_id": 1296269, 289 "repository_name": "Hello-World", 290 "repository_full_name": "octocat/Hello-World", 291 "properties": [ 292 { 293 "property_name": "environment", 294 "value": "production" 295 }, 296 { 297 "property_name": "service", 298 "value": "web" 299 }, 300 { 301 "property_name": "languages", 302 "value": ["Go", "JavaScript"] 303 }, 304 { 305 "property_name": "null_property", 306 "value": null 307 } 308 ] 309 }]`) 310 }) 311 312 ctx := context.Background() 313 repoPropertyValues, _, err := client.Organizations.ListCustomPropertyValues(ctx, "o", &ListOptions{ 314 Page: 1, 315 PerPage: 100, 316 }) 317 if err != nil { 318 t.Errorf("Organizations.ListCustomPropertyValues returned error: %v", err) 319 } 320 321 want := []*RepoCustomPropertyValue{ 322 { 323 RepositoryID: 1296269, 324 RepositoryName: "Hello-World", 325 RepositoryFullName: "octocat/Hello-World", 326 Properties: []*CustomPropertyValue{ 327 { 328 PropertyName: "environment", 329 Value: "production", 330 }, 331 { 332 PropertyName: "service", 333 Value: "web", 334 }, 335 { 336 PropertyName: "languages", 337 Value: []string{"Go", "JavaScript"}, 338 }, 339 { 340 PropertyName: "null_property", 341 Value: nil, 342 }, 343 }, 344 }, 345 } 346 347 if !cmp.Equal(repoPropertyValues, want) { 348 t.Errorf("Organizations.ListCustomPropertyValues returned %+v, want %+v", repoPropertyValues, want) 349 } 350 351 const methodName = "ListCustomPropertyValues" 352 353 testBadOptions(t, methodName, func() (err error) { 354 _, _, err = client.Organizations.ListCustomPropertyValues(ctx, "\n", &ListOptions{}) 355 return err 356 }) 357 358 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 359 got, resp, err := client.Organizations.ListCustomPropertyValues(ctx, "o", nil) 360 if got != nil { 361 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 362 } 363 return resp, err 364 }) 365 } 366 367 func TestCustomPropertyValue_UnmarshalJSON(t *testing.T) { 368 t.Parallel() 369 tests := map[string]struct { 370 data string 371 want *CustomPropertyValue 372 wantErr bool 373 }{ 374 "Invalid JSON": { 375 data: `{`, 376 want: &CustomPropertyValue{}, 377 wantErr: true, 378 }, 379 "String value": { 380 data: `{ 381 "property_name": "environment", 382 "value": "production" 383 }`, 384 want: &CustomPropertyValue{ 385 PropertyName: "environment", 386 Value: "production", 387 }, 388 wantErr: false, 389 }, 390 "Array of strings value": { 391 data: `{ 392 "property_name": "languages", 393 "value": ["Go", "JavaScript"] 394 }`, 395 want: &CustomPropertyValue{ 396 PropertyName: "languages", 397 Value: []string{"Go", "JavaScript"}, 398 }, 399 wantErr: false, 400 }, 401 "Non-string value in array": { 402 data: `{ 403 "property_name": "languages", 404 "value": ["Go", 42] 405 }`, 406 want: &CustomPropertyValue{ 407 PropertyName: "languages", 408 Value: nil, 409 }, 410 wantErr: true, 411 }, 412 "Unexpected value type": { 413 data: `{ 414 "property_name": "environment", 415 "value": {"invalid": "type"} 416 }`, 417 want: &CustomPropertyValue{ 418 PropertyName: "environment", 419 Value: nil, 420 }, 421 wantErr: true, 422 }, 423 } 424 425 for name, tc := range tests { 426 t.Run(name, func(t *testing.T) { 427 t.Parallel() 428 cpv := &CustomPropertyValue{} 429 err := cpv.UnmarshalJSON([]byte(tc.data)) 430 if (err != nil) != tc.wantErr { 431 t.Errorf("CustomPropertyValue.UnmarshalJSON error = %v, wantErr %v", err, tc.wantErr) 432 return 433 } 434 if !tc.wantErr && !cmp.Equal(tc.want, cpv) { 435 t.Errorf("CustomPropertyValue.UnmarshalJSON expected %+v, got %+v", tc.want, cpv) 436 } 437 }) 438 } 439 } 440 441 func TestOrganizationsService_CreateOrUpdateRepoCustomPropertyValues(t *testing.T) { 442 t.Parallel() 443 client, mux, _ := setup(t) 444 445 mux.HandleFunc("/orgs/o/properties/values", func(w http.ResponseWriter, r *http.Request) { 446 testMethod(t, r, "PATCH") 447 testBody(t, r, `{"repository_names":["repo"],"properties":[{"property_name":"service","value":"string"}]}`+"\n") 448 }) 449 450 ctx := context.Background() 451 _, err := client.Organizations.CreateOrUpdateRepoCustomPropertyValues(ctx, "o", []string{"repo"}, []*CustomPropertyValue{ 452 { 453 PropertyName: "service", 454 Value: Ptr("string"), 455 }, 456 }) 457 if err != nil { 458 t.Errorf("Organizations.CreateOrUpdateCustomPropertyValuesForRepos returned error: %v", err) 459 } 460 461 const methodName = "CreateOrUpdateCustomPropertyValuesForRepos" 462 463 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 464 return client.Organizations.CreateOrUpdateRepoCustomPropertyValues(ctx, "o", nil, nil) 465 }) 466 }