...

Source file src/github.com/google/go-github/v55/github/repos_environments_test.go

Documentation: github.com/google/go-github/v55/github

     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  	"encoding/json"
    11  	"fmt"
    12  	"net/http"
    13  	"testing"
    14  
    15  	"github.com/google/go-cmp/cmp"
    16  )
    17  
    18  func TestRequiredReviewer_UnmarshalJSON(t *testing.T) {
    19  	var testCases = map[string]struct {
    20  		data      []byte
    21  		wantRule  []*RequiredReviewer
    22  		wantError bool
    23  	}{
    24  		"User Reviewer": {
    25  			data:      []byte(`[{"type": "User", "reviewer": {"id": 1,"login": "octocat"}}]`),
    26  			wantRule:  []*RequiredReviewer{{Type: String("User"), Reviewer: &User{ID: Int64(1), Login: String("octocat")}}},
    27  			wantError: false,
    28  		},
    29  		"Team Reviewer": {
    30  			data:      []byte(`[{"type": "Team", "reviewer": {"id": 1, "name": "Justice League"}}]`),
    31  			wantRule:  []*RequiredReviewer{{Type: String("Team"), Reviewer: &Team{ID: Int64(1), Name: String("Justice League")}}},
    32  			wantError: false,
    33  		},
    34  		"Both Types Reviewer": {
    35  			data:      []byte(`[{"type": "User", "reviewer": {"id": 1,"login": "octocat"}},{"type": "Team", "reviewer": {"id": 1, "name": "Justice League"}}]`),
    36  			wantRule:  []*RequiredReviewer{{Type: String("User"), Reviewer: &User{ID: Int64(1), Login: String("octocat")}}, {Type: String("Team"), Reviewer: &Team{ID: Int64(1), Name: String("Justice League")}}},
    37  			wantError: false,
    38  		},
    39  		"Empty JSON Object": {
    40  			data:      []byte(`[]`),
    41  			wantRule:  []*RequiredReviewer{},
    42  			wantError: false,
    43  		},
    44  		"Bad JSON Object": {
    45  			data:      []byte(`[badjson: 1]`),
    46  			wantRule:  []*RequiredReviewer{},
    47  			wantError: true,
    48  		},
    49  		"Wrong Type Type in Reviewer Object": {
    50  			data:      []byte(`[{"type": 1, "reviewer": {"id": 1}}]`),
    51  			wantRule:  []*RequiredReviewer{{Type: nil, Reviewer: nil}},
    52  			wantError: true,
    53  		},
    54  		"Wrong ID Type in User Object": {
    55  			data:      []byte(`[{"type": "User", "reviewer": {"id": "string"}}]`),
    56  			wantRule:  []*RequiredReviewer{{Type: String("User"), Reviewer: nil}},
    57  			wantError: true,
    58  		},
    59  		"Wrong ID Type in Team Object": {
    60  			data:      []byte(`[{"type": "Team", "reviewer": {"id": "string"}}]`),
    61  			wantRule:  []*RequiredReviewer{{Type: String("Team"), Reviewer: nil}},
    62  			wantError: true,
    63  		},
    64  		"Wrong Type of Reviewer": {
    65  			data:      []byte(`[{"type": "Cat", "reviewer": {"id": 1,"login": "octocat"}}]`),
    66  			wantRule:  []*RequiredReviewer{{Type: nil, Reviewer: nil}},
    67  			wantError: true,
    68  		},
    69  	}
    70  
    71  	for name, test := range testCases {
    72  		t.Run(name, func(t *testing.T) {
    73  			rule := []*RequiredReviewer{}
    74  			err := json.Unmarshal(test.data, &rule)
    75  			if err != nil && !test.wantError {
    76  				t.Errorf("RequiredReviewer.UnmarshalJSON returned an error when we expected nil")
    77  			}
    78  			if err == nil && test.wantError {
    79  				t.Errorf("RequiredReviewer.UnmarshalJSON returned no error when we expected one")
    80  			}
    81  			if !cmp.Equal(test.wantRule, rule) {
    82  				t.Errorf("RequiredReviewer.UnmarshalJSON expected rule %+v, got %+v", test.wantRule, rule)
    83  			}
    84  		})
    85  	}
    86  }
    87  
    88  func TestCreateUpdateEnvironment_MarshalJSON(t *testing.T) {
    89  	cu := &CreateUpdateEnvironment{}
    90  
    91  	got, err := cu.MarshalJSON()
    92  	if err != nil {
    93  		t.Errorf("MarshalJSON: %v", err)
    94  	}
    95  
    96  	want := `{"wait_timer":0,"reviewers":null,"can_admins_bypass":true,"deployment_branch_policy":null}`
    97  	if string(got) != want {
    98  		t.Errorf("MarshalJSON = %s, want %v", got, want)
    99  	}
   100  }
   101  
   102  func TestRepositoriesService_ListEnvironments(t *testing.T) {
   103  	client, mux, _, teardown := setup()
   104  	defer teardown()
   105  
   106  	mux.HandleFunc("/repos/o/r/environments", func(w http.ResponseWriter, r *http.Request) {
   107  		testMethod(t, r, "GET")
   108  		fmt.Fprint(w, `{"total_count":1, "environments":[{"id":1}, {"id": 2}]}`)
   109  	})
   110  
   111  	opt := &EnvironmentListOptions{
   112  		ListOptions: ListOptions{
   113  			Page:    2,
   114  			PerPage: 2,
   115  		},
   116  	}
   117  	ctx := context.Background()
   118  	environments, _, err := client.Repositories.ListEnvironments(ctx, "o", "r", opt)
   119  	if err != nil {
   120  		t.Errorf("Repositories.ListEnvironments returned error: %v", err)
   121  	}
   122  	want := &EnvResponse{TotalCount: Int(1), Environments: []*Environment{{ID: Int64(1)}, {ID: Int64(2)}}}
   123  	if !cmp.Equal(environments, want) {
   124  		t.Errorf("Repositories.ListEnvironments returned %+v, want %+v", environments, want)
   125  	}
   126  
   127  	const methodName = "ListEnvironments"
   128  	testBadOptions(t, methodName, func() (err error) {
   129  		_, _, err = client.Repositories.ListEnvironments(ctx, "\n", "\n", opt)
   130  		return err
   131  	})
   132  
   133  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   134  		got, resp, err := client.Repositories.ListEnvironments(ctx, "o", "r", opt)
   135  		if got != nil {
   136  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   137  		}
   138  		return resp, err
   139  	})
   140  }
   141  
   142  func TestRepositoriesService_GetEnvironment(t *testing.T) {
   143  	client, mux, _, teardown := setup()
   144  	defer teardown()
   145  
   146  	mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) {
   147  		testMethod(t, r, "GET")
   148  		fmt.Fprint(w, `{"id": 1,"name": "staging", "deployment_branch_policy": {"protected_branches": true,	"custom_branch_policies": false}, "can_admins_bypass": false}`)
   149  	})
   150  
   151  	ctx := context.Background()
   152  	release, resp, err := client.Repositories.GetEnvironment(ctx, "o", "r", "e")
   153  	if err != nil {
   154  		t.Errorf("Repositories.GetEnvironment returned error: %v\n%v", err, resp.Body)
   155  	}
   156  
   157  	want := &Environment{ID: Int64(1), Name: String("staging"), DeploymentBranchPolicy: &BranchPolicy{ProtectedBranches: Bool(true), CustomBranchPolicies: Bool(false)}, CanAdminsBypass: Bool(false)}
   158  	if !cmp.Equal(release, want) {
   159  		t.Errorf("Repositories.GetEnvironment returned %+v, want %+v", release, want)
   160  	}
   161  
   162  	const methodName = "GetEnvironment"
   163  	testBadOptions(t, methodName, func() (err error) {
   164  		_, _, err = client.Repositories.GetEnvironment(ctx, "\n", "\n", "\n")
   165  		return err
   166  	})
   167  
   168  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   169  		got, resp, err := client.Repositories.GetEnvironment(ctx, "o", "r", "e")
   170  		if got != nil {
   171  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   172  		}
   173  		return resp, err
   174  	})
   175  }
   176  
   177  func TestRepositoriesService_CreateEnvironment(t *testing.T) {
   178  	client, mux, _, teardown := setup()
   179  	defer teardown()
   180  
   181  	input := &CreateUpdateEnvironment{
   182  		WaitTimer: Int(30),
   183  	}
   184  
   185  	mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) {
   186  		v := new(CreateUpdateEnvironment)
   187  		json.NewDecoder(r.Body).Decode(v)
   188  
   189  		testMethod(t, r, "PUT")
   190  		want := &CreateUpdateEnvironment{WaitTimer: Int(30), CanAdminsBypass: Bool(true)}
   191  		if !cmp.Equal(v, want) {
   192  			t.Errorf("Request body = %+v, want %+v", v, want)
   193  		}
   194  		fmt.Fprint(w, `{"id": 1, "name": "staging",	"protection_rules": [{"id": 1, "type": "wait_timer", "wait_timer": 30}]}`)
   195  	})
   196  
   197  	ctx := context.Background()
   198  	release, _, err := client.Repositories.CreateUpdateEnvironment(ctx, "o", "r", "e", input)
   199  	if err != nil {
   200  		t.Errorf("Repositories.CreateUpdateEnvironment returned error: %v", err)
   201  	}
   202  
   203  	want := &Environment{ID: Int64(1), Name: String("staging"), ProtectionRules: []*ProtectionRule{{ID: Int64(1), Type: String("wait_timer"), WaitTimer: Int(30)}}}
   204  	if !cmp.Equal(release, want) {
   205  		t.Errorf("Repositories.CreateUpdateEnvironment returned %+v, want %+v", release, want)
   206  	}
   207  
   208  	const methodName = "CreateUpdateEnvironment"
   209  	testBadOptions(t, methodName, func() (err error) {
   210  		_, _, err = client.Repositories.CreateUpdateEnvironment(ctx, "\n", "\n", "\n", input)
   211  		return err
   212  	})
   213  
   214  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   215  		got, resp, err := client.Repositories.CreateUpdateEnvironment(ctx, "o", "r", "e", input)
   216  		if got != nil {
   217  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   218  		}
   219  		return resp, err
   220  	})
   221  }
   222  
   223  func TestRepositoriesService_CreateEnvironment_noEnterprise(t *testing.T) {
   224  	client, mux, _, teardown := setup()
   225  	defer teardown()
   226  
   227  	input := &CreateUpdateEnvironment{}
   228  	callCount := 0
   229  
   230  	mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) {
   231  		v := new(CreateUpdateEnvironment)
   232  		json.NewDecoder(r.Body).Decode(v)
   233  
   234  		testMethod(t, r, "PUT")
   235  		if callCount == 0 {
   236  			w.WriteHeader(http.StatusUnprocessableEntity)
   237  			callCount++
   238  		} else {
   239  			want := &CreateUpdateEnvironment{}
   240  			if !cmp.Equal(v, want) {
   241  				t.Errorf("Request body = %+v, want %+v", v, want)
   242  			}
   243  			fmt.Fprint(w, `{"id": 1, "name": "staging",	"protection_rules": []}`)
   244  		}
   245  	})
   246  
   247  	ctx := context.Background()
   248  	release, _, err := client.Repositories.CreateUpdateEnvironment(ctx, "o", "r", "e", input)
   249  	if err != nil {
   250  		t.Errorf("Repositories.CreateUpdateEnvironment returned error: %v", err)
   251  	}
   252  
   253  	want := &Environment{ID: Int64(1), Name: String("staging"), ProtectionRules: []*ProtectionRule{}}
   254  	if !cmp.Equal(release, want) {
   255  		t.Errorf("Repositories.CreateUpdateEnvironment returned %+v, want %+v", release, want)
   256  	}
   257  }
   258  
   259  func TestRepositoriesService_createNewEnvNoEnterprise(t *testing.T) {
   260  	client, mux, _, teardown := setup()
   261  	defer teardown()
   262  
   263  	input := &CreateUpdateEnvironment{
   264  		DeploymentBranchPolicy: &BranchPolicy{
   265  			ProtectedBranches:    Bool(true),
   266  			CustomBranchPolicies: Bool(false),
   267  		},
   268  	}
   269  
   270  	mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) {
   271  		v := new(createUpdateEnvironmentNoEnterprise)
   272  		json.NewDecoder(r.Body).Decode(v)
   273  
   274  		testMethod(t, r, "PUT")
   275  		want := &createUpdateEnvironmentNoEnterprise{
   276  			DeploymentBranchPolicy: &BranchPolicy{
   277  				ProtectedBranches:    Bool(true),
   278  				CustomBranchPolicies: Bool(false),
   279  			},
   280  		}
   281  		if !cmp.Equal(v, want) {
   282  			t.Errorf("Request body = %+v, want %+v", v, want)
   283  		}
   284  		fmt.Fprint(w, `{"id": 1, "name": "staging",	"protection_rules": [{"id": 1, "node_id": "id", "type": "branch_policy"}], "deployment_branch_policy": {"protected_branches": true, "custom_branch_policies": false}}`)
   285  	})
   286  
   287  	ctx := context.Background()
   288  	release, _, err := client.Repositories.createNewEnvNoEnterprise(ctx, "repos/o/r/environments/e", input)
   289  	if err != nil {
   290  		t.Errorf("Repositories.createNewEnvNoEnterprise returned error: %v", err)
   291  	}
   292  
   293  	want := &Environment{
   294  		ID:   Int64(1),
   295  		Name: String("staging"),
   296  		ProtectionRules: []*ProtectionRule{
   297  			{
   298  				ID:     Int64(1),
   299  				NodeID: String("id"),
   300  				Type:   String("branch_policy"),
   301  			},
   302  		},
   303  		DeploymentBranchPolicy: &BranchPolicy{
   304  			ProtectedBranches:    Bool(true),
   305  			CustomBranchPolicies: Bool(false),
   306  		},
   307  	}
   308  	if !cmp.Equal(release, want) {
   309  		t.Errorf("Repositories.createNewEnvNoEnterprise returned %+v, want %+v", release, want)
   310  	}
   311  
   312  	const methodName = "createNewEnvNoEnterprise"
   313  	testBadOptions(t, methodName, func() (err error) {
   314  		_, _, err = client.Repositories.createNewEnvNoEnterprise(ctx, "\n", input)
   315  		return err
   316  	})
   317  
   318  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   319  		got, resp, err := client.Repositories.createNewEnvNoEnterprise(ctx, "repos/o/r/environments/e", input)
   320  		if got != nil {
   321  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   322  		}
   323  		return resp, err
   324  	})
   325  }
   326  
   327  func TestRepositoriesService_DeleteEnvironment(t *testing.T) {
   328  	client, mux, _, teardown := setup()
   329  	defer teardown()
   330  
   331  	mux.HandleFunc("/repos/o/r/environments/e", func(w http.ResponseWriter, r *http.Request) {
   332  		testMethod(t, r, "DELETE")
   333  	})
   334  
   335  	ctx := context.Background()
   336  	_, err := client.Repositories.DeleteEnvironment(ctx, "o", "r", "e")
   337  	if err != nil {
   338  		t.Errorf("Repositories.DeleteEnvironment returned error: %v", err)
   339  	}
   340  
   341  	const methodName = "DeleteEnvironment"
   342  	testBadOptions(t, methodName, func() (err error) {
   343  		_, err = client.Repositories.DeleteEnvironment(ctx, "\n", "\n", "\n")
   344  		return err
   345  	})
   346  
   347  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   348  		return client.Repositories.DeleteEnvironment(ctx, "o", "r", "e")
   349  	})
   350  }
   351  
   352  func TestRepoEnvironment_Marshal(t *testing.T) {
   353  	testJSONMarshal(t, &EnvResponse{}, "{}")
   354  
   355  	repoEnv := &EnvResponse{
   356  		TotalCount: Int(1),
   357  		Environments: []*Environment{
   358  			{
   359  				Owner:           String("me"),
   360  				Repo:            String("se"),
   361  				EnvironmentName: String("dev"),
   362  				WaitTimer:       Int(123),
   363  				Reviewers: []*EnvReviewers{
   364  					{
   365  						Type: String("main"),
   366  						ID:   Int64(1),
   367  					},
   368  					{
   369  						Type: String("rev"),
   370  						ID:   Int64(2),
   371  					},
   372  				},
   373  				DeploymentBranchPolicy: &BranchPolicy{
   374  					ProtectedBranches:    Bool(false),
   375  					CustomBranchPolicies: Bool(false),
   376  				},
   377  				ID:        Int64(2),
   378  				NodeID:    String("star"),
   379  				Name:      String("eg"),
   380  				URL:       String("https://hey.in"),
   381  				HTMLURL:   String("htmlurl"),
   382  				CreatedAt: &Timestamp{referenceTime},
   383  				UpdatedAt: &Timestamp{referenceTime},
   384  				ProtectionRules: []*ProtectionRule{
   385  					{
   386  						ID:        Int64(21),
   387  						NodeID:    String("mnb"),
   388  						Type:      String("ewq"),
   389  						WaitTimer: Int(9090),
   390  					},
   391  				},
   392  			},
   393  		},
   394  	}
   395  
   396  	want := `{
   397  		"total_count":1,
   398  		"environments":[
   399  		   {
   400  			  "owner":"me",
   401  			  "repo":"se",
   402  			  "environment_name":"dev",
   403  			  "wait_timer":123,
   404  			  "reviewers":[
   405  				 {
   406  					"type":"main",
   407  					"id":1
   408  				 },
   409  				 {
   410  					"type":"rev",
   411  					"id":2
   412  				 }
   413  			  ],
   414  			  "deployment_branch_policy":{
   415  				 "protected_branches":false,
   416  				 "custom_branch_policies":false
   417  			  },
   418  			  "id":2,
   419  			  "node_id":"star",
   420  			  "name":"eg",
   421  			  "url":"https://hey.in",
   422  			  "html_url":"htmlurl",
   423  			  "created_at":` + referenceTimeStr + `,
   424  			  "updated_at":` + referenceTimeStr + `,
   425  			  "protection_rules":[
   426  				 {
   427  					"id":21,
   428  					"node_id":"mnb",
   429  					"type":"ewq",
   430  					"wait_timer":9090
   431  				 }
   432  			  ]
   433  		   }
   434  		]
   435  	 }`
   436  
   437  	testJSONMarshal(t, repoEnv, want)
   438  }
   439  
   440  func TestEnvReviewers_Marshal(t *testing.T) {
   441  	testJSONMarshal(t, &EnvReviewers{}, "{}")
   442  
   443  	repoEnv := &EnvReviewers{
   444  		Type: String("main"),
   445  		ID:   Int64(1),
   446  	}
   447  
   448  	want := `{
   449  		"type":"main",
   450  		"id":1
   451  	}`
   452  
   453  	testJSONMarshal(t, repoEnv, want)
   454  }
   455  
   456  func TestEnvironment_Marshal(t *testing.T) {
   457  	testJSONMarshal(t, &Environment{}, "{}")
   458  
   459  	repoEnv := &Environment{
   460  		Owner:           String("o"),
   461  		Repo:            String("r"),
   462  		EnvironmentName: String("e"),
   463  		WaitTimer:       Int(123),
   464  		Reviewers: []*EnvReviewers{
   465  			{
   466  				Type: String("main"),
   467  				ID:   Int64(1),
   468  			},
   469  			{
   470  				Type: String("rev"),
   471  				ID:   Int64(2),
   472  			},
   473  		},
   474  		DeploymentBranchPolicy: &BranchPolicy{
   475  			ProtectedBranches:    Bool(false),
   476  			CustomBranchPolicies: Bool(false),
   477  		},
   478  		ID:        Int64(2),
   479  		NodeID:    String("star"),
   480  		Name:      String("eg"),
   481  		URL:       String("https://hey.in"),
   482  		HTMLURL:   String("htmlurl"),
   483  		CreatedAt: &Timestamp{referenceTime},
   484  		UpdatedAt: &Timestamp{referenceTime},
   485  		ProtectionRules: []*ProtectionRule{
   486  			{
   487  				ID:        Int64(21),
   488  				NodeID:    String("mnb"),
   489  				Type:      String("ewq"),
   490  				WaitTimer: Int(9090),
   491  			},
   492  		},
   493  	}
   494  
   495  	want := `{
   496  		"owner":"o",
   497  		"repo":"r",
   498  		"environment_name":"e",
   499  		"wait_timer":123,
   500  		"reviewers":[
   501  			{
   502  				"type":"main",
   503  				"id":1
   504  			},
   505  			{
   506  				"type":"rev",
   507  				"id":2
   508  			}
   509  		],
   510  		"deployment_branch_policy":{
   511  			"protected_branches":false,
   512  			"custom_branch_policies":false
   513  		},
   514  		"id":2,
   515  		"node_id":"star",
   516  		"name":"eg",
   517  		"url":"https://hey.in",
   518  		"html_url":"htmlurl",
   519  		"created_at":` + referenceTimeStr + `,
   520  		"updated_at":` + referenceTimeStr + `,
   521  		"protection_rules":[
   522  			{
   523  				"id":21,
   524  				"node_id":"mnb",
   525  				"type":"ewq",
   526  				"wait_timer":9090
   527  			}
   528  		]
   529  	}`
   530  
   531  	testJSONMarshal(t, repoEnv, want)
   532  }
   533  
   534  func TestBranchPolicy_Marshal(t *testing.T) {
   535  	testJSONMarshal(t, &BranchPolicy{}, "{}")
   536  
   537  	bp := &BranchPolicy{
   538  		ProtectedBranches:    Bool(false),
   539  		CustomBranchPolicies: Bool(false),
   540  	}
   541  
   542  	want := `{
   543  		"protected_branches": false,
   544  		"custom_branch_policies": false
   545  	}`
   546  
   547  	testJSONMarshal(t, bp, want)
   548  }
   549  

View as plain text