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