...

Source file src/github.com/google/go-github/v47/github/projects_test.go

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

     1  // Copyright 2016 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  	"strings"
    14  	"testing"
    15  
    16  	"github.com/google/go-cmp/cmp"
    17  )
    18  
    19  func TestProject_Marshal(t *testing.T) {
    20  	testJSONMarshal(t, &Project{}, "{}")
    21  
    22  	u := &Project{
    23  		ID:         Int64(1),
    24  		URL:        String("u"),
    25  		HTMLURL:    String("h"),
    26  		ColumnsURL: String("c"),
    27  		OwnerURL:   String("o"),
    28  		Name:       String("n"),
    29  		Body:       String("b"),
    30  		Number:     Int(1),
    31  		State:      String("s"),
    32  		CreatedAt:  &Timestamp{referenceTime},
    33  		UpdatedAt:  &Timestamp{referenceTime},
    34  		NodeID:     String("n"),
    35  		Creator: &User{
    36  			Login:       String("l"),
    37  			ID:          Int64(1),
    38  			AvatarURL:   String("a"),
    39  			GravatarID:  String("g"),
    40  			Name:        String("n"),
    41  			Company:     String("c"),
    42  			Blog:        String("b"),
    43  			Location:    String("l"),
    44  			Email:       String("e"),
    45  			Hireable:    Bool(true),
    46  			PublicRepos: Int(1),
    47  			Followers:   Int(1),
    48  			Following:   Int(1),
    49  			CreatedAt:   &Timestamp{referenceTime},
    50  			URL:         String("u"),
    51  		},
    52  	}
    53  	want := `{
    54  		"id": 1,
    55  		"url": "u",
    56  		"html_url": "h",
    57  		"columns_url": "c",
    58  		"owner_url": "o",
    59  		"name": "n",
    60  		"body": "b",
    61  		"number": 1,
    62  		"state": "s",
    63  		"created_at": ` + referenceTimeStr + `,
    64  		"updated_at": ` + referenceTimeStr + `,
    65  		"node_id": "n",
    66  		"creator": {
    67  			"login": "l",
    68  			"id": 1,
    69  			"avatar_url": "a",
    70  			"gravatar_id": "g",
    71  			"name": "n",
    72  			"company": "c",
    73  			"blog": "b",
    74  			"location": "l",
    75  			"email": "e",
    76  			"hireable": true,
    77  			"public_repos": 1,
    78  			"followers": 1,
    79  			"following": 1,
    80  			"created_at": ` + referenceTimeStr + `,
    81  			"url": "u"
    82  		}
    83  	}`
    84  	testJSONMarshal(t, u, want)
    85  }
    86  
    87  func TestProjectsService_UpdateProject(t *testing.T) {
    88  	client, mux, _, teardown := setup()
    89  	defer teardown()
    90  
    91  	input := &ProjectOptions{
    92  		Name:    String("Project Name"),
    93  		Body:    String("Project body."),
    94  		State:   String("open"),
    95  		Private: Bool(false),
    96  
    97  		OrganizationPermission: String("read"),
    98  	}
    99  
   100  	mux.HandleFunc("/projects/1", func(w http.ResponseWriter, r *http.Request) {
   101  		testMethod(t, r, "PATCH")
   102  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   103  
   104  		v := &ProjectOptions{}
   105  		json.NewDecoder(r.Body).Decode(v)
   106  		if !cmp.Equal(v, input) {
   107  			t.Errorf("Request body = %+v, want %+v", v, input)
   108  		}
   109  
   110  		fmt.Fprint(w, `{"id":1}`)
   111  	})
   112  
   113  	ctx := context.Background()
   114  	project, _, err := client.Projects.UpdateProject(ctx, 1, input)
   115  	if err != nil {
   116  		t.Errorf("Projects.UpdateProject returned error: %v", err)
   117  	}
   118  
   119  	want := &Project{ID: Int64(1)}
   120  	if !cmp.Equal(project, want) {
   121  		t.Errorf("Projects.UpdateProject returned %+v, want %+v", project, want)
   122  	}
   123  
   124  	const methodName = "UpdateProject"
   125  	testBadOptions(t, methodName, func() (err error) {
   126  		_, _, err = client.Projects.UpdateProject(ctx, -1, input)
   127  		return err
   128  	})
   129  
   130  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   131  		got, resp, err := client.Projects.UpdateProject(ctx, 1, input)
   132  		if got != nil {
   133  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   134  		}
   135  		return resp, err
   136  	})
   137  }
   138  
   139  func TestProjectsService_GetProject(t *testing.T) {
   140  	client, mux, _, teardown := setup()
   141  	defer teardown()
   142  
   143  	mux.HandleFunc("/projects/1", func(w http.ResponseWriter, r *http.Request) {
   144  		testMethod(t, r, "GET")
   145  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   146  		fmt.Fprint(w, `{"id":1}`)
   147  	})
   148  
   149  	ctx := context.Background()
   150  	project, _, err := client.Projects.GetProject(ctx, 1)
   151  	if err != nil {
   152  		t.Errorf("Projects.GetProject returned error: %v", err)
   153  	}
   154  
   155  	want := &Project{ID: Int64(1)}
   156  	if !cmp.Equal(project, want) {
   157  		t.Errorf("Projects.GetProject returned %+v, want %+v", project, want)
   158  	}
   159  
   160  	const methodName = "GetProject"
   161  	testBadOptions(t, methodName, func() (err error) {
   162  		_, _, err = client.Projects.GetProject(ctx, -1)
   163  		return err
   164  	})
   165  
   166  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   167  		got, resp, err := client.Projects.GetProject(ctx, 1)
   168  		if got != nil {
   169  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   170  		}
   171  		return resp, err
   172  	})
   173  }
   174  
   175  func TestProjectsService_DeleteProject(t *testing.T) {
   176  	client, mux, _, teardown := setup()
   177  	defer teardown()
   178  
   179  	mux.HandleFunc("/projects/1", func(w http.ResponseWriter, r *http.Request) {
   180  		testMethod(t, r, "DELETE")
   181  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   182  	})
   183  
   184  	ctx := context.Background()
   185  	_, err := client.Projects.DeleteProject(ctx, 1)
   186  	if err != nil {
   187  		t.Errorf("Projects.DeleteProject returned error: %v", err)
   188  	}
   189  
   190  	const methodName = "DeleteProject"
   191  	testBadOptions(t, methodName, func() (err error) {
   192  		_, err = client.Projects.DeleteProject(ctx, -1)
   193  		return err
   194  	})
   195  
   196  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   197  		return client.Projects.DeleteProject(ctx, 1)
   198  	})
   199  }
   200  
   201  func TestProjectsService_ListProjectColumns(t *testing.T) {
   202  	client, mux, _, teardown := setup()
   203  	defer teardown()
   204  
   205  	wantAcceptHeaders := []string{mediaTypeProjectsPreview}
   206  	mux.HandleFunc("/projects/1/columns", func(w http.ResponseWriter, r *http.Request) {
   207  		testMethod(t, r, "GET")
   208  		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
   209  		testFormValues(t, r, values{"page": "2"})
   210  		fmt.Fprint(w, `[{"id":1}]`)
   211  	})
   212  
   213  	opt := &ListOptions{Page: 2}
   214  	ctx := context.Background()
   215  	columns, _, err := client.Projects.ListProjectColumns(ctx, 1, opt)
   216  	if err != nil {
   217  		t.Errorf("Projects.ListProjectColumns returned error: %v", err)
   218  	}
   219  
   220  	want := []*ProjectColumn{{ID: Int64(1)}}
   221  	if !cmp.Equal(columns, want) {
   222  		t.Errorf("Projects.ListProjectColumns returned %+v, want %+v", columns, want)
   223  	}
   224  
   225  	const methodName = "ListProjectColumns"
   226  	testBadOptions(t, methodName, func() (err error) {
   227  		_, _, err = client.Projects.ListProjectColumns(ctx, -1, opt)
   228  		return err
   229  	})
   230  
   231  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   232  		got, resp, err := client.Projects.ListProjectColumns(ctx, 1, opt)
   233  		if got != nil {
   234  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   235  		}
   236  		return resp, err
   237  	})
   238  }
   239  
   240  func TestProjectsService_GetProjectColumn(t *testing.T) {
   241  	client, mux, _, teardown := setup()
   242  	defer teardown()
   243  
   244  	mux.HandleFunc("/projects/columns/1", func(w http.ResponseWriter, r *http.Request) {
   245  		testMethod(t, r, "GET")
   246  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   247  		fmt.Fprint(w, `{"id":1}`)
   248  	})
   249  
   250  	ctx := context.Background()
   251  	column, _, err := client.Projects.GetProjectColumn(ctx, 1)
   252  	if err != nil {
   253  		t.Errorf("Projects.GetProjectColumn returned error: %v", err)
   254  	}
   255  
   256  	want := &ProjectColumn{ID: Int64(1)}
   257  	if !cmp.Equal(column, want) {
   258  		t.Errorf("Projects.GetProjectColumn returned %+v, want %+v", column, want)
   259  	}
   260  
   261  	const methodName = "GetProjectColumn"
   262  	testBadOptions(t, methodName, func() (err error) {
   263  		_, _, err = client.Projects.GetProjectColumn(ctx, -1)
   264  		return err
   265  	})
   266  
   267  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   268  		got, resp, err := client.Projects.GetProjectColumn(ctx, 1)
   269  		if got != nil {
   270  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   271  		}
   272  		return resp, err
   273  	})
   274  }
   275  
   276  func TestProjectsService_CreateProjectColumn(t *testing.T) {
   277  	client, mux, _, teardown := setup()
   278  	defer teardown()
   279  
   280  	input := &ProjectColumnOptions{Name: "Column Name"}
   281  
   282  	mux.HandleFunc("/projects/1/columns", func(w http.ResponseWriter, r *http.Request) {
   283  		testMethod(t, r, "POST")
   284  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   285  
   286  		v := &ProjectColumnOptions{}
   287  		json.NewDecoder(r.Body).Decode(v)
   288  		if !cmp.Equal(v, input) {
   289  			t.Errorf("Request body = %+v, want %+v", v, input)
   290  		}
   291  
   292  		fmt.Fprint(w, `{"id":1}`)
   293  	})
   294  
   295  	ctx := context.Background()
   296  	column, _, err := client.Projects.CreateProjectColumn(ctx, 1, input)
   297  	if err != nil {
   298  		t.Errorf("Projects.CreateProjectColumn returned error: %v", err)
   299  	}
   300  
   301  	want := &ProjectColumn{ID: Int64(1)}
   302  	if !cmp.Equal(column, want) {
   303  		t.Errorf("Projects.CreateProjectColumn returned %+v, want %+v", column, want)
   304  	}
   305  
   306  	const methodName = "CreateProjectColumn"
   307  	testBadOptions(t, methodName, func() (err error) {
   308  		_, _, err = client.Projects.CreateProjectColumn(ctx, -1, input)
   309  		return err
   310  	})
   311  
   312  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   313  		got, resp, err := client.Projects.CreateProjectColumn(ctx, 1, input)
   314  		if got != nil {
   315  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   316  		}
   317  		return resp, err
   318  	})
   319  }
   320  
   321  func TestProjectsService_UpdateProjectColumn(t *testing.T) {
   322  	client, mux, _, teardown := setup()
   323  	defer teardown()
   324  
   325  	input := &ProjectColumnOptions{Name: "Column Name"}
   326  
   327  	mux.HandleFunc("/projects/columns/1", func(w http.ResponseWriter, r *http.Request) {
   328  		testMethod(t, r, "PATCH")
   329  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   330  
   331  		v := &ProjectColumnOptions{}
   332  		json.NewDecoder(r.Body).Decode(v)
   333  		if !cmp.Equal(v, input) {
   334  			t.Errorf("Request body = %+v, want %+v", v, input)
   335  		}
   336  
   337  		fmt.Fprint(w, `{"id":1}`)
   338  	})
   339  
   340  	ctx := context.Background()
   341  	column, _, err := client.Projects.UpdateProjectColumn(ctx, 1, input)
   342  	if err != nil {
   343  		t.Errorf("Projects.UpdateProjectColumn returned error: %v", err)
   344  	}
   345  
   346  	want := &ProjectColumn{ID: Int64(1)}
   347  	if !cmp.Equal(column, want) {
   348  		t.Errorf("Projects.UpdateProjectColumn returned %+v, want %+v", column, want)
   349  	}
   350  
   351  	const methodName = "UpdateProjectColumn"
   352  	testBadOptions(t, methodName, func() (err error) {
   353  		_, _, err = client.Projects.UpdateProjectColumn(ctx, -1, input)
   354  		return err
   355  	})
   356  
   357  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   358  		got, resp, err := client.Projects.UpdateProjectColumn(ctx, 1, input)
   359  		if got != nil {
   360  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   361  		}
   362  		return resp, err
   363  	})
   364  }
   365  
   366  func TestProjectsService_DeleteProjectColumn(t *testing.T) {
   367  	client, mux, _, teardown := setup()
   368  	defer teardown()
   369  
   370  	mux.HandleFunc("/projects/columns/1", func(w http.ResponseWriter, r *http.Request) {
   371  		testMethod(t, r, "DELETE")
   372  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   373  	})
   374  
   375  	ctx := context.Background()
   376  	_, err := client.Projects.DeleteProjectColumn(ctx, 1)
   377  	if err != nil {
   378  		t.Errorf("Projects.DeleteProjectColumn returned error: %v", err)
   379  	}
   380  
   381  	const methodName = "DeleteProjectColumn"
   382  	testBadOptions(t, methodName, func() (err error) {
   383  		_, err = client.Projects.DeleteProjectColumn(ctx, -1)
   384  		return err
   385  	})
   386  
   387  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   388  		return client.Projects.DeleteProjectColumn(ctx, 1)
   389  	})
   390  }
   391  
   392  func TestProjectsService_MoveProjectColumn(t *testing.T) {
   393  	client, mux, _, teardown := setup()
   394  	defer teardown()
   395  
   396  	input := &ProjectColumnMoveOptions{Position: "after:12345"}
   397  
   398  	mux.HandleFunc("/projects/columns/1/moves", func(w http.ResponseWriter, r *http.Request) {
   399  		testMethod(t, r, "POST")
   400  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   401  
   402  		v := &ProjectColumnMoveOptions{}
   403  		json.NewDecoder(r.Body).Decode(v)
   404  		if !cmp.Equal(v, input) {
   405  			t.Errorf("Request body = %+v, want %+v", v, input)
   406  		}
   407  	})
   408  
   409  	ctx := context.Background()
   410  	_, err := client.Projects.MoveProjectColumn(ctx, 1, input)
   411  	if err != nil {
   412  		t.Errorf("Projects.MoveProjectColumn returned error: %v", err)
   413  	}
   414  
   415  	const methodName = "MoveProjectColumn"
   416  	testBadOptions(t, methodName, func() (err error) {
   417  		_, err = client.Projects.MoveProjectColumn(ctx, -1, input)
   418  		return err
   419  	})
   420  
   421  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   422  		return client.Projects.MoveProjectColumn(ctx, 1, input)
   423  	})
   424  }
   425  
   426  func TestProjectsService_ListProjectCards(t *testing.T) {
   427  	client, mux, _, teardown := setup()
   428  	defer teardown()
   429  
   430  	mux.HandleFunc("/projects/columns/1/cards", func(w http.ResponseWriter, r *http.Request) {
   431  		testMethod(t, r, "GET")
   432  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   433  		testFormValues(t, r, values{
   434  			"archived_state": "all",
   435  			"page":           "2"})
   436  		fmt.Fprint(w, `[{"id":1}]`)
   437  	})
   438  
   439  	opt := &ProjectCardListOptions{
   440  		ArchivedState: String("all"),
   441  		ListOptions:   ListOptions{Page: 2}}
   442  	ctx := context.Background()
   443  	cards, _, err := client.Projects.ListProjectCards(ctx, 1, opt)
   444  	if err != nil {
   445  		t.Errorf("Projects.ListProjectCards returned error: %v", err)
   446  	}
   447  
   448  	want := []*ProjectCard{{ID: Int64(1)}}
   449  	if !cmp.Equal(cards, want) {
   450  		t.Errorf("Projects.ListProjectCards returned %+v, want %+v", cards, want)
   451  	}
   452  
   453  	const methodName = "ListProjectCards"
   454  	testBadOptions(t, methodName, func() (err error) {
   455  		_, _, err = client.Projects.ListProjectCards(ctx, -1, opt)
   456  		return err
   457  	})
   458  
   459  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   460  		got, resp, err := client.Projects.ListProjectCards(ctx, 1, opt)
   461  		if got != nil {
   462  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   463  		}
   464  		return resp, err
   465  	})
   466  }
   467  
   468  func TestProjectsService_GetProjectCard(t *testing.T) {
   469  	client, mux, _, teardown := setup()
   470  	defer teardown()
   471  
   472  	mux.HandleFunc("/projects/columns/cards/1", func(w http.ResponseWriter, r *http.Request) {
   473  		testMethod(t, r, "GET")
   474  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   475  		fmt.Fprint(w, `{"id":1}`)
   476  	})
   477  
   478  	ctx := context.Background()
   479  	card, _, err := client.Projects.GetProjectCard(ctx, 1)
   480  	if err != nil {
   481  		t.Errorf("Projects.GetProjectCard returned error: %v", err)
   482  	}
   483  
   484  	want := &ProjectCard{ID: Int64(1)}
   485  	if !cmp.Equal(card, want) {
   486  		t.Errorf("Projects.GetProjectCard returned %+v, want %+v", card, want)
   487  	}
   488  
   489  	const methodName = "GetProjectCard"
   490  	testBadOptions(t, methodName, func() (err error) {
   491  		_, _, err = client.Projects.GetProjectCard(ctx, -1)
   492  		return err
   493  	})
   494  
   495  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   496  		got, resp, err := client.Projects.GetProjectCard(ctx, 1)
   497  		if got != nil {
   498  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   499  		}
   500  		return resp, err
   501  	})
   502  }
   503  
   504  func TestProjectsService_CreateProjectCard(t *testing.T) {
   505  	client, mux, _, teardown := setup()
   506  	defer teardown()
   507  
   508  	input := &ProjectCardOptions{
   509  		ContentID:   12345,
   510  		ContentType: "Issue",
   511  	}
   512  
   513  	mux.HandleFunc("/projects/columns/1/cards", func(w http.ResponseWriter, r *http.Request) {
   514  		testMethod(t, r, "POST")
   515  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   516  
   517  		v := &ProjectCardOptions{}
   518  		json.NewDecoder(r.Body).Decode(v)
   519  		if !cmp.Equal(v, input) {
   520  			t.Errorf("Request body = %+v, want %+v", v, input)
   521  		}
   522  
   523  		fmt.Fprint(w, `{"id":1}`)
   524  	})
   525  
   526  	ctx := context.Background()
   527  	card, _, err := client.Projects.CreateProjectCard(ctx, 1, input)
   528  	if err != nil {
   529  		t.Errorf("Projects.CreateProjectCard returned error: %v", err)
   530  	}
   531  
   532  	want := &ProjectCard{ID: Int64(1)}
   533  	if !cmp.Equal(card, want) {
   534  		t.Errorf("Projects.CreateProjectCard returned %+v, want %+v", card, want)
   535  	}
   536  
   537  	const methodName = "CreateProjectCard"
   538  	testBadOptions(t, methodName, func() (err error) {
   539  		_, _, err = client.Projects.CreateProjectCard(ctx, -1, input)
   540  		return err
   541  	})
   542  
   543  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   544  		got, resp, err := client.Projects.CreateProjectCard(ctx, 1, input)
   545  		if got != nil {
   546  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   547  		}
   548  		return resp, err
   549  	})
   550  }
   551  
   552  func TestProjectsService_UpdateProjectCard(t *testing.T) {
   553  	client, mux, _, teardown := setup()
   554  	defer teardown()
   555  
   556  	input := &ProjectCardOptions{
   557  		ContentID:   12345,
   558  		ContentType: "Issue",
   559  	}
   560  
   561  	mux.HandleFunc("/projects/columns/cards/1", func(w http.ResponseWriter, r *http.Request) {
   562  		testMethod(t, r, "PATCH")
   563  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   564  
   565  		v := &ProjectCardOptions{}
   566  		json.NewDecoder(r.Body).Decode(v)
   567  		if !cmp.Equal(v, input) {
   568  			t.Errorf("Request body = %+v, want %+v", v, input)
   569  		}
   570  
   571  		fmt.Fprint(w, `{"id":1, "archived":false}`)
   572  	})
   573  
   574  	ctx := context.Background()
   575  	card, _, err := client.Projects.UpdateProjectCard(ctx, 1, input)
   576  	if err != nil {
   577  		t.Errorf("Projects.UpdateProjectCard returned error: %v", err)
   578  	}
   579  
   580  	want := &ProjectCard{ID: Int64(1), Archived: Bool(false)}
   581  	if !cmp.Equal(card, want) {
   582  		t.Errorf("Projects.UpdateProjectCard returned %+v, want %+v", card, want)
   583  	}
   584  
   585  	const methodName = "UpdateProjectCard"
   586  	testBadOptions(t, methodName, func() (err error) {
   587  		_, _, err = client.Projects.UpdateProjectCard(ctx, -1, input)
   588  		return err
   589  	})
   590  
   591  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   592  		got, resp, err := client.Projects.UpdateProjectCard(ctx, 1, input)
   593  		if got != nil {
   594  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   595  		}
   596  		return resp, err
   597  	})
   598  }
   599  
   600  func TestProjectsService_DeleteProjectCard(t *testing.T) {
   601  	client, mux, _, teardown := setup()
   602  	defer teardown()
   603  
   604  	mux.HandleFunc("/projects/columns/cards/1", func(w http.ResponseWriter, r *http.Request) {
   605  		testMethod(t, r, "DELETE")
   606  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   607  	})
   608  
   609  	ctx := context.Background()
   610  	_, err := client.Projects.DeleteProjectCard(ctx, 1)
   611  	if err != nil {
   612  		t.Errorf("Projects.DeleteProjectCard returned error: %v", err)
   613  	}
   614  
   615  	const methodName = "DeleteProjectCard"
   616  	testBadOptions(t, methodName, func() (err error) {
   617  		_, err = client.Projects.DeleteProjectCard(ctx, -1)
   618  		return err
   619  	})
   620  
   621  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   622  		return client.Projects.DeleteProjectCard(ctx, 1)
   623  	})
   624  }
   625  
   626  func TestProjectsService_MoveProjectCard(t *testing.T) {
   627  	client, mux, _, teardown := setup()
   628  	defer teardown()
   629  
   630  	input := &ProjectCardMoveOptions{Position: "after:12345"}
   631  
   632  	mux.HandleFunc("/projects/columns/cards/1/moves", func(w http.ResponseWriter, r *http.Request) {
   633  		testMethod(t, r, "POST")
   634  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   635  
   636  		v := &ProjectCardMoveOptions{}
   637  		json.NewDecoder(r.Body).Decode(v)
   638  		if !cmp.Equal(v, input) {
   639  			t.Errorf("Request body = %+v, want %+v", v, input)
   640  		}
   641  	})
   642  
   643  	ctx := context.Background()
   644  	_, err := client.Projects.MoveProjectCard(ctx, 1, input)
   645  	if err != nil {
   646  		t.Errorf("Projects.MoveProjectCard returned error: %v", err)
   647  	}
   648  
   649  	const methodName = "MoveProjectCard"
   650  	testBadOptions(t, methodName, func() (err error) {
   651  		_, err = client.Projects.MoveProjectCard(ctx, -1, input)
   652  		return err
   653  	})
   654  
   655  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   656  		return client.Projects.MoveProjectCard(ctx, 1, input)
   657  	})
   658  }
   659  
   660  func TestProjectsService_AddProjectCollaborator(t *testing.T) {
   661  	client, mux, _, teardown := setup()
   662  	defer teardown()
   663  
   664  	opt := &ProjectCollaboratorOptions{
   665  		Permission: String("admin"),
   666  	}
   667  
   668  	mux.HandleFunc("/projects/1/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
   669  		testMethod(t, r, "PUT")
   670  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   671  
   672  		v := &ProjectCollaboratorOptions{}
   673  		json.NewDecoder(r.Body).Decode(v)
   674  		if !cmp.Equal(v, opt) {
   675  			t.Errorf("Request body = %+v, want %+v", v, opt)
   676  		}
   677  
   678  		w.WriteHeader(http.StatusNoContent)
   679  	})
   680  
   681  	ctx := context.Background()
   682  	_, err := client.Projects.AddProjectCollaborator(ctx, 1, "u", opt)
   683  	if err != nil {
   684  		t.Errorf("Projects.AddProjectCollaborator returned error: %v", err)
   685  	}
   686  
   687  	const methodName = "AddProjectCollaborator"
   688  	testBadOptions(t, methodName, func() (err error) {
   689  		_, err = client.Projects.AddProjectCollaborator(ctx, -1, "\n", opt)
   690  		return err
   691  	})
   692  
   693  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   694  		return client.Projects.AddProjectCollaborator(ctx, 1, "u", opt)
   695  	})
   696  }
   697  
   698  func TestProjectsService_AddCollaborator_invalidUser(t *testing.T) {
   699  	client, _, _, teardown := setup()
   700  	defer teardown()
   701  
   702  	ctx := context.Background()
   703  	_, err := client.Projects.AddProjectCollaborator(ctx, 1, "%", nil)
   704  	testURLParseError(t, err)
   705  }
   706  
   707  func TestProjectsService_RemoveCollaborator(t *testing.T) {
   708  	client, mux, _, teardown := setup()
   709  	defer teardown()
   710  
   711  	mux.HandleFunc("/projects/1/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
   712  		testMethod(t, r, "DELETE")
   713  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   714  		w.WriteHeader(http.StatusNoContent)
   715  	})
   716  
   717  	ctx := context.Background()
   718  	_, err := client.Projects.RemoveProjectCollaborator(ctx, 1, "u")
   719  	if err != nil {
   720  		t.Errorf("Projects.RemoveProjectCollaborator returned error: %v", err)
   721  	}
   722  
   723  	const methodName = "RemoveProjectCollaborator"
   724  	testBadOptions(t, methodName, func() (err error) {
   725  		_, err = client.Projects.RemoveProjectCollaborator(ctx, -1, "\n")
   726  		return err
   727  	})
   728  
   729  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   730  		return client.Projects.RemoveProjectCollaborator(ctx, 1, "u")
   731  	})
   732  }
   733  
   734  func TestProjectsService_RemoveCollaborator_invalidUser(t *testing.T) {
   735  	client, _, _, teardown := setup()
   736  	defer teardown()
   737  
   738  	ctx := context.Background()
   739  	_, err := client.Projects.RemoveProjectCollaborator(ctx, 1, "%")
   740  	testURLParseError(t, err)
   741  }
   742  
   743  func TestProjectsService_ListCollaborators(t *testing.T) {
   744  	client, mux, _, teardown := setup()
   745  	defer teardown()
   746  
   747  	mux.HandleFunc("/projects/1/collaborators", func(w http.ResponseWriter, r *http.Request) {
   748  		testMethod(t, r, "GET")
   749  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   750  		testFormValues(t, r, values{"page": "2"})
   751  		fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
   752  	})
   753  
   754  	opt := &ListCollaboratorOptions{
   755  		ListOptions: ListOptions{Page: 2},
   756  	}
   757  	ctx := context.Background()
   758  	users, _, err := client.Projects.ListProjectCollaborators(ctx, 1, opt)
   759  	if err != nil {
   760  		t.Errorf("Projects.ListProjectCollaborators returned error: %v", err)
   761  	}
   762  
   763  	want := []*User{{ID: Int64(1)}, {ID: Int64(2)}}
   764  	if !cmp.Equal(users, want) {
   765  		t.Errorf("Projects.ListProjectCollaborators returned %+v, want %+v", users, want)
   766  	}
   767  
   768  	const methodName = "ListProjectCollaborators"
   769  	testBadOptions(t, methodName, func() (err error) {
   770  		_, _, err = client.Projects.ListProjectCollaborators(ctx, -1, opt)
   771  		return err
   772  	})
   773  
   774  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   775  		got, resp, err := client.Projects.ListProjectCollaborators(ctx, 1, opt)
   776  		if got != nil {
   777  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   778  		}
   779  		return resp, err
   780  	})
   781  }
   782  
   783  func TestProjectsService_ListCollaborators_withAffiliation(t *testing.T) {
   784  	client, mux, _, teardown := setup()
   785  	defer teardown()
   786  
   787  	mux.HandleFunc("/projects/1/collaborators", func(w http.ResponseWriter, r *http.Request) {
   788  		testMethod(t, r, "GET")
   789  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   790  		testFormValues(t, r, values{"affiliation": "all", "page": "2"})
   791  		fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
   792  	})
   793  
   794  	opt := &ListCollaboratorOptions{
   795  		ListOptions: ListOptions{Page: 2},
   796  		Affiliation: String("all"),
   797  	}
   798  	ctx := context.Background()
   799  	users, _, err := client.Projects.ListProjectCollaborators(ctx, 1, opt)
   800  	if err != nil {
   801  		t.Errorf("Projects.ListProjectCollaborators returned error: %v", err)
   802  	}
   803  
   804  	want := []*User{{ID: Int64(1)}, {ID: Int64(2)}}
   805  	if !cmp.Equal(users, want) {
   806  		t.Errorf("Projects.ListProjectCollaborators returned %+v, want %+v", users, want)
   807  	}
   808  }
   809  
   810  func TestProjectsService_ReviewProjectCollaboratorPermission(t *testing.T) {
   811  	client, mux, _, teardown := setup()
   812  	defer teardown()
   813  
   814  	mux.HandleFunc("/projects/1/collaborators/u/permission", func(w http.ResponseWriter, r *http.Request) {
   815  		testMethod(t, r, "GET")
   816  		testHeader(t, r, "Accept", mediaTypeProjectsPreview)
   817  		fmt.Fprintf(w, `{"permission":"admin","user":{"login":"u"}}`)
   818  	})
   819  
   820  	ctx := context.Background()
   821  	ppl, _, err := client.Projects.ReviewProjectCollaboratorPermission(ctx, 1, "u")
   822  	if err != nil {
   823  		t.Errorf("Projects.ReviewProjectCollaboratorPermission returned error: %v", err)
   824  	}
   825  
   826  	want := &ProjectPermissionLevel{
   827  		Permission: String("admin"),
   828  		User: &User{
   829  			Login: String("u"),
   830  		},
   831  	}
   832  
   833  	if !cmp.Equal(ppl, want) {
   834  		t.Errorf("Projects.ReviewProjectCollaboratorPermission returned %+v, want %+v", ppl, want)
   835  	}
   836  
   837  	const methodName = "ReviewProjectCollaboratorPermission"
   838  	testBadOptions(t, methodName, func() (err error) {
   839  		_, _, err = client.Projects.ReviewProjectCollaboratorPermission(ctx, -1, "\n")
   840  		return err
   841  	})
   842  
   843  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   844  		got, resp, err := client.Projects.ReviewProjectCollaboratorPermission(ctx, 1, "u")
   845  		if got != nil {
   846  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   847  		}
   848  		return resp, err
   849  	})
   850  }
   851  
   852  func TestProjectOptions_Marshal(t *testing.T) {
   853  	testJSONMarshal(t, &ProjectOptions{}, "{}")
   854  
   855  	u := &ProjectOptions{
   856  		Name:                   String("name"),
   857  		Body:                   String("body"),
   858  		State:                  String("state"),
   859  		OrganizationPermission: String("op"),
   860  		Private:                Bool(false),
   861  	}
   862  
   863  	want := `{
   864  		"name": "name",
   865  		"body": "body",
   866  		"state": "state",
   867  		"organization_permission": "op",
   868  		"private": false
   869  	}`
   870  
   871  	testJSONMarshal(t, u, want)
   872  }
   873  
   874  func TestProjectColumn_Marshal(t *testing.T) {
   875  	testJSONMarshal(t, &ProjectColumn{}, "{}")
   876  
   877  	u := &ProjectColumn{
   878  		ID:         Int64(1),
   879  		Name:       String("name"),
   880  		URL:        String("url"),
   881  		ProjectURL: String("purl"),
   882  		CardsURL:   String("curl"),
   883  		CreatedAt:  &Timestamp{referenceTime},
   884  		UpdatedAt:  &Timestamp{referenceTime},
   885  		NodeID:     String("onidp"),
   886  	}
   887  
   888  	want := `{
   889  		"id": 1,
   890  		"name": "name",
   891  		"url": "url",
   892  		"project_url": "purl",
   893  		"cards_url": "curl",
   894  		"created_at": ` + referenceTimeStr + `,
   895  		"updated_at": ` + referenceTimeStr + `,
   896  		"node_id": "onidp"
   897  	}`
   898  
   899  	testJSONMarshal(t, u, want)
   900  }
   901  
   902  func TestProjectColumnOptions_Marshal(t *testing.T) {
   903  	testJSONMarshal(t, &ProjectColumnOptions{}, "{}")
   904  
   905  	u := &ProjectColumnOptions{
   906  		Name: "name",
   907  	}
   908  
   909  	want := `{
   910  		"name": "name"
   911  	}`
   912  
   913  	testJSONMarshal(t, u, want)
   914  }
   915  
   916  func TestProjectColumnMoveOptions_Marshal(t *testing.T) {
   917  	testJSONMarshal(t, &ProjectColumnMoveOptions{}, "{}")
   918  
   919  	u := &ProjectColumnMoveOptions{
   920  		Position: "pos",
   921  	}
   922  
   923  	want := `{
   924  		"position": "pos"
   925  	}`
   926  
   927  	testJSONMarshal(t, u, want)
   928  }
   929  
   930  func TestProjectCard_Marshal(t *testing.T) {
   931  	testJSONMarshal(t, &ProjectCard{}, "{}")
   932  
   933  	u := &ProjectCard{
   934  		URL:        String("url"),
   935  		ColumnURL:  String("curl"),
   936  		ContentURL: String("conurl"),
   937  		ID:         Int64(1),
   938  		Note:       String("note"),
   939  		Creator: &User{
   940  			Login:           String("l"),
   941  			ID:              Int64(1),
   942  			URL:             String("u"),
   943  			AvatarURL:       String("a"),
   944  			GravatarID:      String("g"),
   945  			Name:            String("n"),
   946  			Company:         String("c"),
   947  			Blog:            String("b"),
   948  			Location:        String("l"),
   949  			Email:           String("e"),
   950  			Hireable:        Bool(true),
   951  			Bio:             String("b"),
   952  			TwitterUsername: String("t"),
   953  			PublicRepos:     Int(1),
   954  			Followers:       Int(1),
   955  			Following:       Int(1),
   956  			CreatedAt:       &Timestamp{referenceTime},
   957  			SuspendedAt:     &Timestamp{referenceTime},
   958  		},
   959  		CreatedAt:          &Timestamp{referenceTime},
   960  		UpdatedAt:          &Timestamp{referenceTime},
   961  		NodeID:             String("nid"),
   962  		Archived:           Bool(true),
   963  		ColumnID:           Int64(1),
   964  		ProjectID:          Int64(1),
   965  		ProjectURL:         String("purl"),
   966  		ColumnName:         String("cn"),
   967  		PreviousColumnName: String("pcn"),
   968  	}
   969  
   970  	want := `{
   971  		"url": "url",
   972  		"column_url": "curl",
   973  		"content_url": "conurl",
   974  		"id": 1,
   975  		"note": "note",
   976  		"creator": {
   977  			"login": "l",
   978  			"id": 1,
   979  			"avatar_url": "a",
   980  			"gravatar_id": "g",
   981  			"name": "n",
   982  			"company": "c",
   983  			"blog": "b",
   984  			"location": "l",
   985  			"email": "e",
   986  			"hireable": true,
   987  			"bio": "b",
   988  			"twitter_username": "t",
   989  			"public_repos": 1,
   990  			"followers": 1,
   991  			"following": 1,
   992  			"created_at": ` + referenceTimeStr + `,
   993  			"suspended_at": ` + referenceTimeStr + `,
   994  			"url": "u"
   995  		},
   996  		"created_at": ` + referenceTimeStr + `,
   997  		"updated_at": ` + referenceTimeStr + `,
   998  		"node_id": "nid",
   999  		"archived": true,
  1000  		"column_id": 1,
  1001  		"project_id": 1,
  1002  		"project_url": "purl",
  1003  		"column_name": "cn",
  1004  		"previous_column_name": "pcn"
  1005  	}`
  1006  
  1007  	testJSONMarshal(t, u, want)
  1008  }
  1009  
  1010  func TestProjectCardOptions_Marshal(t *testing.T) {
  1011  	testJSONMarshal(t, &ProjectCardOptions{}, "{}")
  1012  
  1013  	u := &ProjectCardOptions{
  1014  		Note:        "note",
  1015  		ContentID:   1,
  1016  		ContentType: "ct",
  1017  		Archived:    Bool(false),
  1018  	}
  1019  
  1020  	want := `{
  1021  		"note": "note",
  1022  		"content_id": 1,
  1023  		"content_type": "ct",
  1024  		"archived": false
  1025  	}`
  1026  
  1027  	testJSONMarshal(t, u, want)
  1028  }
  1029  
  1030  func TestProjectCardMoveOptions_Marshal(t *testing.T) {
  1031  	testJSONMarshal(t, &ProjectCardMoveOptions{}, "{}")
  1032  
  1033  	u := &ProjectCardMoveOptions{
  1034  		Position: "pos",
  1035  		ColumnID: 1,
  1036  	}
  1037  
  1038  	want := `{
  1039  		"position": "pos",
  1040  		"column_id": 1
  1041  	}`
  1042  
  1043  	testJSONMarshal(t, u, want)
  1044  }
  1045  
  1046  func TestProjectCollaboratorOptions_Marshal(t *testing.T) {
  1047  	testJSONMarshal(t, &ProjectCollaboratorOptions{}, "{}")
  1048  
  1049  	u := &ProjectCollaboratorOptions{
  1050  		Permission: String("per"),
  1051  	}
  1052  
  1053  	want := `{
  1054  		"permission": "per"
  1055  	}`
  1056  
  1057  	testJSONMarshal(t, u, want)
  1058  }
  1059  
  1060  func TestProjectPermissionLevel_Marshal(t *testing.T) {
  1061  	testJSONMarshal(t, &ProjectPermissionLevel{}, "{}")
  1062  
  1063  	u := &ProjectPermissionLevel{
  1064  		Permission: String("per"),
  1065  		User: &User{
  1066  			Login:           String("l"),
  1067  			ID:              Int64(1),
  1068  			URL:             String("u"),
  1069  			AvatarURL:       String("a"),
  1070  			GravatarID:      String("g"),
  1071  			Name:            String("n"),
  1072  			Company:         String("c"),
  1073  			Blog:            String("b"),
  1074  			Location:        String("l"),
  1075  			Email:           String("e"),
  1076  			Hireable:        Bool(true),
  1077  			Bio:             String("b"),
  1078  			TwitterUsername: String("t"),
  1079  			PublicRepos:     Int(1),
  1080  			Followers:       Int(1),
  1081  			Following:       Int(1),
  1082  			CreatedAt:       &Timestamp{referenceTime},
  1083  			SuspendedAt:     &Timestamp{referenceTime},
  1084  		},
  1085  	}
  1086  
  1087  	want := `{
  1088  		"permission": "per",
  1089  		"user": {
  1090  			"login": "l",
  1091  			"id": 1,
  1092  			"avatar_url": "a",
  1093  			"gravatar_id": "g",
  1094  			"name": "n",
  1095  			"company": "c",
  1096  			"blog": "b",
  1097  			"location": "l",
  1098  			"email": "e",
  1099  			"hireable": true,
  1100  			"bio": "b",
  1101  			"twitter_username": "t",
  1102  			"public_repos": 1,
  1103  			"followers": 1,
  1104  			"following": 1,
  1105  			"created_at": ` + referenceTimeStr + `,
  1106  			"suspended_at": ` + referenceTimeStr + `,
  1107  			"url": "u"
  1108  		}
  1109  	}`
  1110  
  1111  	testJSONMarshal(t, u, want)
  1112  }
  1113  

View as plain text