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

     1  // Copyright 2013 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 TestRepositoriesService_CreateHook(t *testing.T) {
    19  	t.Parallel()
    20  	client, mux, _ := setup(t)
    21  
    22  	input := &Hook{CreatedAt: &Timestamp{referenceTime}}
    23  
    24  	mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) {
    25  		v := new(createHookRequest)
    26  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
    27  
    28  		testMethod(t, r, "POST")
    29  		want := &createHookRequest{Name: "web"}
    30  		if !cmp.Equal(v, want) {
    31  			t.Errorf("Request body = %+v, want %+v", v, want)
    32  		}
    33  
    34  		fmt.Fprint(w, `{"id":1}`)
    35  	})
    36  
    37  	ctx := context.Background()
    38  	hook, _, err := client.Repositories.CreateHook(ctx, "o", "r", input)
    39  	if err != nil {
    40  		t.Errorf("Repositories.CreateHook returned error: %v", err)
    41  	}
    42  
    43  	want := &Hook{ID: Ptr(int64(1))}
    44  	if !cmp.Equal(hook, want) {
    45  		t.Errorf("Repositories.CreateHook returned %+v, want %+v", hook, want)
    46  	}
    47  
    48  	const methodName = "CreateHook"
    49  	testBadOptions(t, methodName, func() (err error) {
    50  		_, _, err = client.Repositories.CreateHook(ctx, "\n", "\n", input)
    51  		return err
    52  	})
    53  
    54  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    55  		got, resp, err := client.Repositories.CreateHook(ctx, "o", "r", input)
    56  		if got != nil {
    57  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    58  		}
    59  		return resp, err
    60  	})
    61  }
    62  
    63  func TestRepositoriesService_ListHooks(t *testing.T) {
    64  	t.Parallel()
    65  	client, mux, _ := setup(t)
    66  
    67  	mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) {
    68  		testMethod(t, r, "GET")
    69  		testFormValues(t, r, values{"page": "2"})
    70  		fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
    71  	})
    72  
    73  	opt := &ListOptions{Page: 2}
    74  
    75  	ctx := context.Background()
    76  	hooks, _, err := client.Repositories.ListHooks(ctx, "o", "r", opt)
    77  	if err != nil {
    78  		t.Errorf("Repositories.ListHooks returned error: %v", err)
    79  	}
    80  
    81  	want := []*Hook{{ID: Ptr(int64(1))}, {ID: Ptr(int64(2))}}
    82  	if !cmp.Equal(hooks, want) {
    83  		t.Errorf("Repositories.ListHooks returned %+v, want %+v", hooks, want)
    84  	}
    85  
    86  	const methodName = "ListHooks"
    87  	testBadOptions(t, methodName, func() (err error) {
    88  		_, _, err = client.Repositories.ListHooks(ctx, "\n", "\n", opt)
    89  		return err
    90  	})
    91  
    92  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
    93  		got, resp, err := client.Repositories.ListHooks(ctx, "o", "r", opt)
    94  		if got != nil {
    95  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
    96  		}
    97  		return resp, err
    98  	})
    99  }
   100  
   101  func TestRepositoriesService_ListHooks_invalidOwner(t *testing.T) {
   102  	t.Parallel()
   103  	client, _, _ := setup(t)
   104  
   105  	ctx := context.Background()
   106  	_, _, err := client.Repositories.ListHooks(ctx, "%", "%", nil)
   107  	testURLParseError(t, err)
   108  }
   109  
   110  func TestRepositoriesService_ListHooks_403_code_no_rate_limit(t *testing.T) {
   111  	t.Parallel()
   112  	testErrorResponseForStatusCode(t, http.StatusForbidden)
   113  }
   114  
   115  func TestRepositoriesService_ListHooks_404_code(t *testing.T) {
   116  	t.Parallel()
   117  	testErrorResponseForStatusCode(t, http.StatusNotFound)
   118  }
   119  
   120  func TestRepositoriesService_GetHook(t *testing.T) {
   121  	t.Parallel()
   122  	client, mux, _ := setup(t)
   123  
   124  	mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
   125  		testMethod(t, r, "GET")
   126  		fmt.Fprint(w, `{"id":1}`)
   127  	})
   128  
   129  	ctx := context.Background()
   130  	hook, _, err := client.Repositories.GetHook(ctx, "o", "r", 1)
   131  	if err != nil {
   132  		t.Errorf("Repositories.GetHook returned error: %v", err)
   133  	}
   134  
   135  	want := &Hook{ID: Ptr(int64(1))}
   136  	if !cmp.Equal(hook, want) {
   137  		t.Errorf("Repositories.GetHook returned %+v, want %+v", hook, want)
   138  	}
   139  
   140  	const methodName = "GetHook"
   141  	testBadOptions(t, methodName, func() (err error) {
   142  		_, _, err = client.Repositories.GetHook(ctx, "\n", "\n", -1)
   143  		return err
   144  	})
   145  
   146  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   147  		got, resp, err := client.Repositories.GetHook(ctx, "o", "r", 1)
   148  		if got != nil {
   149  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   150  		}
   151  		return resp, err
   152  	})
   153  }
   154  
   155  func TestRepositoriesService_GetHook_invalidOwner(t *testing.T) {
   156  	t.Parallel()
   157  	client, _, _ := setup(t)
   158  
   159  	ctx := context.Background()
   160  	_, _, err := client.Repositories.GetHook(ctx, "%", "%", 1)
   161  	testURLParseError(t, err)
   162  }
   163  
   164  func TestRepositoriesService_EditHook(t *testing.T) {
   165  	t.Parallel()
   166  	client, mux, _ := setup(t)
   167  
   168  	input := &Hook{}
   169  
   170  	mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
   171  		v := new(Hook)
   172  		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
   173  
   174  		testMethod(t, r, "PATCH")
   175  		if !cmp.Equal(v, input) {
   176  			t.Errorf("Request body = %+v, want %+v", v, input)
   177  		}
   178  
   179  		fmt.Fprint(w, `{"id":1}`)
   180  	})
   181  
   182  	ctx := context.Background()
   183  	hook, _, err := client.Repositories.EditHook(ctx, "o", "r", 1, input)
   184  	if err != nil {
   185  		t.Errorf("Repositories.EditHook returned error: %v", err)
   186  	}
   187  
   188  	want := &Hook{ID: Ptr(int64(1))}
   189  	if !cmp.Equal(hook, want) {
   190  		t.Errorf("Repositories.EditHook returned %+v, want %+v", hook, want)
   191  	}
   192  
   193  	const methodName = "EditHook"
   194  	testBadOptions(t, methodName, func() (err error) {
   195  		_, _, err = client.Repositories.EditHook(ctx, "\n", "\n", -1, input)
   196  		return err
   197  	})
   198  
   199  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   200  		got, resp, err := client.Repositories.EditHook(ctx, "o", "r", 1, input)
   201  		if got != nil {
   202  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   203  		}
   204  		return resp, err
   205  	})
   206  }
   207  
   208  func TestRepositoriesService_EditHook_invalidOwner(t *testing.T) {
   209  	t.Parallel()
   210  	client, _, _ := setup(t)
   211  
   212  	ctx := context.Background()
   213  	_, _, err := client.Repositories.EditHook(ctx, "%", "%", 1, nil)
   214  	testURLParseError(t, err)
   215  }
   216  
   217  func TestRepositoriesService_DeleteHook(t *testing.T) {
   218  	t.Parallel()
   219  	client, mux, _ := setup(t)
   220  
   221  	mux.HandleFunc("/repos/o/r/hooks/1", func(_ http.ResponseWriter, r *http.Request) {
   222  		testMethod(t, r, "DELETE")
   223  	})
   224  
   225  	ctx := context.Background()
   226  	_, err := client.Repositories.DeleteHook(ctx, "o", "r", 1)
   227  	if err != nil {
   228  		t.Errorf("Repositories.DeleteHook returned error: %v", err)
   229  	}
   230  
   231  	const methodName = "DeleteHook"
   232  	testBadOptions(t, methodName, func() (err error) {
   233  		_, err = client.Repositories.DeleteHook(ctx, "\n", "\n", -1)
   234  		return err
   235  	})
   236  
   237  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   238  		return client.Repositories.DeleteHook(ctx, "o", "r", 1)
   239  	})
   240  }
   241  
   242  func TestRepositoriesService_DeleteHook_invalidOwner(t *testing.T) {
   243  	t.Parallel()
   244  	client, _, _ := setup(t)
   245  
   246  	ctx := context.Background()
   247  	_, err := client.Repositories.DeleteHook(ctx, "%", "%", 1)
   248  	testURLParseError(t, err)
   249  }
   250  
   251  func TestRepositoriesService_PingHook(t *testing.T) {
   252  	t.Parallel()
   253  	client, mux, _ := setup(t)
   254  
   255  	mux.HandleFunc("/repos/o/r/hooks/1/pings", func(_ http.ResponseWriter, r *http.Request) {
   256  		testMethod(t, r, "POST")
   257  	})
   258  
   259  	ctx := context.Background()
   260  	_, err := client.Repositories.PingHook(ctx, "o", "r", 1)
   261  	if err != nil {
   262  		t.Errorf("Repositories.PingHook returned error: %v", err)
   263  	}
   264  
   265  	const methodName = "PingHook"
   266  	testBadOptions(t, methodName, func() (err error) {
   267  		_, err = client.Repositories.PingHook(ctx, "\n", "\n", -1)
   268  		return err
   269  	})
   270  
   271  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   272  		return client.Repositories.PingHook(ctx, "o", "r", 1)
   273  	})
   274  }
   275  
   276  func TestRepositoriesService_TestHook(t *testing.T) {
   277  	t.Parallel()
   278  	client, mux, _ := setup(t)
   279  
   280  	mux.HandleFunc("/repos/o/r/hooks/1/tests", func(_ http.ResponseWriter, r *http.Request) {
   281  		testMethod(t, r, "POST")
   282  	})
   283  
   284  	ctx := context.Background()
   285  	_, err := client.Repositories.TestHook(ctx, "o", "r", 1)
   286  	if err != nil {
   287  		t.Errorf("Repositories.TestHook returned error: %v", err)
   288  	}
   289  
   290  	const methodName = "TestHook"
   291  	testBadOptions(t, methodName, func() (err error) {
   292  		_, err = client.Repositories.TestHook(ctx, "\n", "\n", -1)
   293  		return err
   294  	})
   295  
   296  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   297  		return client.Repositories.TestHook(ctx, "o", "r", 1)
   298  	})
   299  }
   300  
   301  func TestRepositoriesService_TestHook_invalidOwner(t *testing.T) {
   302  	t.Parallel()
   303  	client, _, _ := setup(t)
   304  
   305  	ctx := context.Background()
   306  	_, err := client.Repositories.TestHook(ctx, "%", "%", 1)
   307  	testURLParseError(t, err)
   308  }
   309  
   310  func TestBranchWebHookPayload_Marshal(t *testing.T) {
   311  	t.Parallel()
   312  	testJSONMarshal(t, &WebHookPayload{}, "{}")
   313  
   314  	v := &WebHookPayload{
   315  		Action: Ptr("action"),
   316  		After:  Ptr("after"),
   317  		Before: Ptr("before"),
   318  		Commits: []*WebHookCommit{
   319  			{
   320  				Added: []string{"1", "2", "3"},
   321  				Author: &WebHookAuthor{
   322  					Email: Ptr("abc@gmail.com"),
   323  					Name:  Ptr("abc"),
   324  					Login: Ptr("abc_12"),
   325  				},
   326  				Committer: &WebHookAuthor{
   327  					Email: Ptr("abc@gmail.com"),
   328  					Name:  Ptr("abc"),
   329  					Login: Ptr("abc_12"),
   330  				},
   331  				ID:       Ptr("1"),
   332  				Message:  Ptr("WebHookCommit"),
   333  				Modified: []string{"abc", "efg", "erd"},
   334  				Removed:  []string{"cmd", "rti", "duv"},
   335  			},
   336  		},
   337  		Compare: Ptr("compare"),
   338  		Created: Ptr(true),
   339  		Forced:  Ptr(false),
   340  		HeadCommit: &WebHookCommit{
   341  			Added: []string{"1", "2", "3"},
   342  			Author: &WebHookAuthor{
   343  				Email: Ptr("abc@gmail.com"),
   344  				Name:  Ptr("abc"),
   345  				Login: Ptr("abc_12"),
   346  			},
   347  			Committer: &WebHookAuthor{
   348  				Email: Ptr("abc@gmail.com"),
   349  				Name:  Ptr("abc"),
   350  				Login: Ptr("abc_12"),
   351  			},
   352  			ID:       Ptr("1"),
   353  			Message:  Ptr("WebHookCommit"),
   354  			Modified: []string{"abc", "efg", "erd"},
   355  			Removed:  []string{"cmd", "rti", "duv"},
   356  		},
   357  		Installation: &Installation{
   358  			ID: Ptr(int64(12)),
   359  		},
   360  		Organization: &Organization{
   361  			ID: Ptr(int64(22)),
   362  		},
   363  		Pusher: &CommitAuthor{
   364  			Login: Ptr("rd@yahoo.com"),
   365  		},
   366  		Repo: &PushEventRepository{
   367  			ID:     Ptr(int64(321)),
   368  			NodeID: Ptr("node_321"),
   369  		},
   370  		Sender: &User{
   371  			Login: Ptr("st@gmail.com"),
   372  			ID:    Ptr(int64(202)),
   373  		},
   374  	}
   375  
   376  	want := `{
   377  		"action": "action",
   378  		"after":  "after",
   379  		"before": "before",
   380  		"commits": [
   381  			{
   382  			"added":   ["1", "2", "3"],
   383  			"author":{
   384  				"email": "abc@gmail.com",
   385  				"name": "abc",
   386  				"username": "abc_12"
   387  			},
   388  			"committer": {
   389  				"email": "abc@gmail.com",
   390  				"name": "abc",
   391  				"username": "abc_12"
   392  			},
   393  			"id":       "1",
   394  			"message":  "WebHookCommit",
   395  			"modified": ["abc", "efg", "erd"],
   396  			"removed":  ["cmd", "rti", "duv"]
   397  			}
   398  		],
   399  		"compare": "compare",
   400  		"created": true,
   401  		"forced":  false,
   402  		"head_commit": {
   403  			"added":   ["1", "2", "3"],
   404  		"author":{
   405  			"email": "abc@gmail.com",
   406  			"name": "abc",
   407  			"username": "abc_12"
   408  		},
   409  		"committer": {
   410  			"email": "abc@gmail.com",
   411  			"name": "abc",
   412  			"username": "abc_12"
   413  		},
   414  		"id":       "1",
   415  		"message":  "WebHookCommit",
   416  		"modified": ["abc", "efg", "erd"],
   417  		"removed":  ["cmd", "rti", "duv"]
   418  		},
   419  		"installation": {
   420  			"id": 12
   421  		},
   422  		"organization": {
   423  			"id" : 22
   424  		},
   425  		"pusher":{
   426  			"username": "rd@yahoo.com"
   427  		},
   428  		"repository":{
   429  			"id": 321,
   430  			"node_id": "node_321"
   431  		},
   432  		"sender":{
   433  			"login": "st@gmail.com",
   434  			"id": 202
   435  		}
   436  	}`
   437  
   438  	testJSONMarshal(t, v, want)
   439  }
   440  
   441  func TestBranchWebHookAuthor_Marshal(t *testing.T) {
   442  	t.Parallel()
   443  	testJSONMarshal(t, &WebHookAuthor{}, "{}")
   444  
   445  	v := &WebHookAuthor{
   446  		Email: Ptr("abc@gmail.com"),
   447  		Name:  Ptr("abc"),
   448  		Login: Ptr("abc_12"),
   449  	}
   450  
   451  	want := `{
   452  			"email": "abc@gmail.com",
   453  			"name": "abc",
   454  			"username": "abc_12"
   455  	}`
   456  
   457  	testJSONMarshal(t, v, want)
   458  }
   459  
   460  func TestBranchWebHookCommit_Marshal(t *testing.T) {
   461  	t.Parallel()
   462  	testJSONMarshal(t, &WebHookCommit{}, "{}")
   463  
   464  	v := &WebHookCommit{
   465  		Added: []string{"1", "2", "3"},
   466  		Author: &WebHookAuthor{
   467  			Email: Ptr("abc@gmail.com"),
   468  			Name:  Ptr("abc"),
   469  			Login: Ptr("abc_12"),
   470  		},
   471  		Committer: &WebHookAuthor{
   472  			Email: Ptr("abc@gmail.com"),
   473  			Name:  Ptr("abc"),
   474  			Login: Ptr("abc_12"),
   475  		},
   476  		ID:       Ptr("1"),
   477  		Message:  Ptr("WebHookCommit"),
   478  		Modified: []string{"abc", "efg", "erd"},
   479  		Removed:  []string{"cmd", "rti", "duv"},
   480  	}
   481  
   482  	want := `{
   483  		"added":   ["1", "2", "3"],
   484  		"author":{
   485  			"email": "abc@gmail.com",
   486  			"name": "abc",
   487  			"username": "abc_12"
   488  		},
   489  		"committer": {
   490  			"email": "abc@gmail.com",
   491  			"name": "abc",
   492  			"username": "abc_12"
   493  		},
   494  		"id":       "1",
   495  		"message":  "WebHookCommit",
   496  		"modified": ["abc", "efg", "erd"],
   497  		"removed":  ["cmd", "rti", "duv"]
   498  	}`
   499  
   500  	testJSONMarshal(t, v, want)
   501  }
   502  
   503  func TestBranchCreateHookRequest_Marshal(t *testing.T) {
   504  	t.Parallel()
   505  	testJSONMarshal(t, &createHookRequest{}, "{}")
   506  
   507  	v := &createHookRequest{
   508  		Name:   "abc",
   509  		Events: []string{"1", "2", "3"},
   510  		Active: Ptr(true),
   511  		Config: &HookConfig{ContentType: Ptr("json")},
   512  	}
   513  
   514  	want := `{
   515  		"name": "abc",
   516  		"active": true,
   517  		"events": ["1","2","3"],
   518  		"config":{
   519  			"content_type": "json"
   520  		}
   521  	}`
   522  
   523  	testJSONMarshal(t, v, want)
   524  }
   525  
   526  func TestBranchHook_Marshal(t *testing.T) {
   527  	t.Parallel()
   528  	testJSONMarshal(t, &Hook{}, "{}")
   529  
   530  	v := &Hook{
   531  		CreatedAt: &Timestamp{referenceTime},
   532  		UpdatedAt: &Timestamp{referenceTime},
   533  		URL:       Ptr("url"),
   534  		ID:        Ptr(int64(1)),
   535  		Type:      Ptr("type"),
   536  		Name:      Ptr("name"),
   537  		TestURL:   Ptr("testurl"),
   538  		PingURL:   Ptr("pingurl"),
   539  		LastResponse: map[string]any{
   540  			"item": "item",
   541  		},
   542  		Config: &HookConfig{ContentType: Ptr("json")},
   543  		Events: []string{"1", "2", "3"},
   544  		Active: Ptr(true),
   545  	}
   546  
   547  	want := `{
   548  		"created_at": ` + referenceTimeStr + `,
   549  		"updated_at": ` + referenceTimeStr + `,
   550  		"url": "url",
   551  		"id": 1,
   552  		"type": "type",
   553  		"name": "name",
   554  		"test_url": "testurl",
   555  		"ping_url": "pingurl",
   556  		"last_response":{
   557  			"item": "item"
   558  		},
   559  		"config":{
   560  			"content_type": "json"
   561  		},
   562  		"events": ["1","2","3"],
   563  		"active": true
   564  	}`
   565  
   566  	testJSONMarshal(t, v, want)
   567  }
   568  
   569  func TestRepositoriesService_Subscribe(t *testing.T) {
   570  	t.Parallel()
   571  	client, mux, _ := setup(t)
   572  
   573  	mux.HandleFunc("/hub", func(_ http.ResponseWriter, r *http.Request) {
   574  		testMethod(t, r, http.MethodPost)
   575  		testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded")
   576  		testFormValues(t, r, values{
   577  			"hub.mode":     "subscribe",
   578  			"hub.topic":    "https://github.com/o/r/events/push",
   579  			"hub.callback": "http://postbin.org/123",
   580  			"hub.secret":   "test secret",
   581  		})
   582  	})
   583  
   584  	ctx := context.Background()
   585  	_, err := client.Repositories.Subscribe(
   586  		ctx,
   587  		"o",
   588  		"r",
   589  		"push",
   590  		"http://postbin.org/123",
   591  		[]byte("test secret"),
   592  	)
   593  	if err != nil {
   594  		t.Errorf("Repositories.Subscribe returned error: %v", err)
   595  	}
   596  
   597  	testNewRequestAndDoFailure(t, "Subscribe", client, func() (*Response, error) {
   598  		return client.Repositories.Subscribe(ctx, "o", "r", "push", "http://postbin.org/123", nil)
   599  	})
   600  }
   601  
   602  func TestRepositoriesService_Unsubscribe(t *testing.T) {
   603  	t.Parallel()
   604  	client, mux, _ := setup(t)
   605  
   606  	mux.HandleFunc("/hub", func(_ http.ResponseWriter, r *http.Request) {
   607  		testMethod(t, r, http.MethodPost)
   608  		testHeader(t, r, "Content-Type", "application/x-www-form-urlencoded")
   609  		testFormValues(t, r, values{
   610  			"hub.mode":     "unsubscribe",
   611  			"hub.topic":    "https://github.com/o/r/events/push",
   612  			"hub.callback": "http://postbin.org/123",
   613  			"hub.secret":   "test secret",
   614  		})
   615  	})
   616  
   617  	ctx := context.Background()
   618  	_, err := client.Repositories.Unsubscribe(
   619  		ctx,
   620  		"o",
   621  		"r",
   622  		"push",
   623  		"http://postbin.org/123",
   624  		[]byte("test secret"),
   625  	)
   626  	if err != nil {
   627  		t.Errorf("Repositories.Unsubscribe returned error: %v", err)
   628  	}
   629  
   630  	testNewRequestAndDoFailure(t, "Unsubscribe", client, func() (*Response, error) {
   631  		return client.Repositories.Unsubscribe(ctx, "o", "r", "push", "http://postbin.org/123", nil)
   632  	})
   633  }