github.com/google/go-github/v49@v49.1.0/github/issues_milestones_test.go (about) 1 // Copyright 2014 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 TestIssuesService_ListMilestones(t *testing.T) { 19 client, mux, _, teardown := setup() 20 defer teardown() 21 22 mux.HandleFunc("/repos/o/r/milestones", func(w http.ResponseWriter, r *http.Request) { 23 testMethod(t, r, "GET") 24 testFormValues(t, r, values{ 25 "state": "closed", 26 "sort": "due_date", 27 "direction": "asc", 28 "page": "2", 29 }) 30 fmt.Fprint(w, `[{"number":1}]`) 31 }) 32 33 opt := &MilestoneListOptions{"closed", "due_date", "asc", ListOptions{Page: 2}} 34 ctx := context.Background() 35 milestones, _, err := client.Issues.ListMilestones(ctx, "o", "r", opt) 36 if err != nil { 37 t.Errorf("IssuesService.ListMilestones returned error: %v", err) 38 } 39 40 want := []*Milestone{{Number: Int(1)}} 41 if !cmp.Equal(milestones, want) { 42 t.Errorf("IssuesService.ListMilestones returned %+v, want %+v", milestones, want) 43 } 44 45 const methodName = "ListMilestones" 46 testBadOptions(t, methodName, func() (err error) { 47 _, _, err = client.Issues.ListMilestones(ctx, "\n", "\n", opt) 48 return err 49 }) 50 51 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 52 got, resp, err := client.Issues.ListMilestones(ctx, "o", "r", opt) 53 if got != nil { 54 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 55 } 56 return resp, err 57 }) 58 } 59 60 func TestIssuesService_ListMilestones_invalidOwner(t *testing.T) { 61 client, _, _, teardown := setup() 62 defer teardown() 63 64 ctx := context.Background() 65 _, _, err := client.Issues.ListMilestones(ctx, "%", "r", nil) 66 testURLParseError(t, err) 67 } 68 69 func TestIssuesService_GetMilestone(t *testing.T) { 70 client, mux, _, teardown := setup() 71 defer teardown() 72 73 mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) { 74 testMethod(t, r, "GET") 75 fmt.Fprint(w, `{"number":1}`) 76 }) 77 78 ctx := context.Background() 79 milestone, _, err := client.Issues.GetMilestone(ctx, "o", "r", 1) 80 if err != nil { 81 t.Errorf("IssuesService.GetMilestone returned error: %v", err) 82 } 83 84 want := &Milestone{Number: Int(1)} 85 if !cmp.Equal(milestone, want) { 86 t.Errorf("IssuesService.GetMilestone returned %+v, want %+v", milestone, want) 87 } 88 89 const methodName = "GetMilestone" 90 testBadOptions(t, methodName, func() (err error) { 91 _, _, err = client.Issues.GetMilestone(ctx, "\n", "\n", -1) 92 return err 93 }) 94 95 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 96 got, resp, err := client.Issues.GetMilestone(ctx, "o", "r", 1) 97 if got != nil { 98 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 99 } 100 return resp, err 101 }) 102 } 103 104 func TestIssuesService_GetMilestone_invalidOwner(t *testing.T) { 105 client, _, _, teardown := setup() 106 defer teardown() 107 108 ctx := context.Background() 109 _, _, err := client.Issues.GetMilestone(ctx, "%", "r", 1) 110 testURLParseError(t, err) 111 } 112 113 func TestIssuesService_CreateMilestone(t *testing.T) { 114 client, mux, _, teardown := setup() 115 defer teardown() 116 117 input := &Milestone{Title: String("t")} 118 119 mux.HandleFunc("/repos/o/r/milestones", func(w http.ResponseWriter, r *http.Request) { 120 v := new(Milestone) 121 json.NewDecoder(r.Body).Decode(v) 122 123 testMethod(t, r, "POST") 124 if !cmp.Equal(v, input) { 125 t.Errorf("Request body = %+v, want %+v", v, input) 126 } 127 128 fmt.Fprint(w, `{"number":1}`) 129 }) 130 131 ctx := context.Background() 132 milestone, _, err := client.Issues.CreateMilestone(ctx, "o", "r", input) 133 if err != nil { 134 t.Errorf("IssuesService.CreateMilestone returned error: %v", err) 135 } 136 137 want := &Milestone{Number: Int(1)} 138 if !cmp.Equal(milestone, want) { 139 t.Errorf("IssuesService.CreateMilestone returned %+v, want %+v", milestone, want) 140 } 141 142 const methodName = "CreateMilestone" 143 testBadOptions(t, methodName, func() (err error) { 144 _, _, err = client.Issues.CreateMilestone(ctx, "\n", "\n", input) 145 return err 146 }) 147 148 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 149 got, resp, err := client.Issues.CreateMilestone(ctx, "o", "r", input) 150 if got != nil { 151 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 152 } 153 return resp, err 154 }) 155 } 156 157 func TestIssuesService_CreateMilestone_invalidOwner(t *testing.T) { 158 client, _, _, teardown := setup() 159 defer teardown() 160 161 ctx := context.Background() 162 _, _, err := client.Issues.CreateMilestone(ctx, "%", "r", nil) 163 testURLParseError(t, err) 164 } 165 166 func TestIssuesService_EditMilestone(t *testing.T) { 167 client, mux, _, teardown := setup() 168 defer teardown() 169 170 input := &Milestone{Title: String("t")} 171 172 mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) { 173 v := new(Milestone) 174 json.NewDecoder(r.Body).Decode(v) 175 176 testMethod(t, r, "PATCH") 177 if !cmp.Equal(v, input) { 178 t.Errorf("Request body = %+v, want %+v", v, input) 179 } 180 181 fmt.Fprint(w, `{"number":1}`) 182 }) 183 184 ctx := context.Background() 185 milestone, _, err := client.Issues.EditMilestone(ctx, "o", "r", 1, input) 186 if err != nil { 187 t.Errorf("IssuesService.EditMilestone returned error: %v", err) 188 } 189 190 want := &Milestone{Number: Int(1)} 191 if !cmp.Equal(milestone, want) { 192 t.Errorf("IssuesService.EditMilestone returned %+v, want %+v", milestone, want) 193 } 194 195 const methodName = "EditMilestone" 196 testBadOptions(t, methodName, func() (err error) { 197 _, _, err = client.Issues.EditMilestone(ctx, "\n", "\n", -1, input) 198 return err 199 }) 200 201 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 202 got, resp, err := client.Issues.EditMilestone(ctx, "o", "r", 1, input) 203 if got != nil { 204 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 205 } 206 return resp, err 207 }) 208 } 209 210 func TestIssuesService_EditMilestone_invalidOwner(t *testing.T) { 211 client, _, _, teardown := setup() 212 defer teardown() 213 214 ctx := context.Background() 215 _, _, err := client.Issues.EditMilestone(ctx, "%", "r", 1, nil) 216 testURLParseError(t, err) 217 } 218 219 func TestIssuesService_DeleteMilestone(t *testing.T) { 220 client, mux, _, teardown := setup() 221 defer teardown() 222 223 mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) { 224 testMethod(t, r, "DELETE") 225 }) 226 227 ctx := context.Background() 228 _, err := client.Issues.DeleteMilestone(ctx, "o", "r", 1) 229 if err != nil { 230 t.Errorf("IssuesService.DeleteMilestone returned error: %v", err) 231 } 232 233 const methodName = "DeleteMilestone" 234 testBadOptions(t, methodName, func() (err error) { 235 _, err = client.Issues.DeleteMilestone(ctx, "\n", "\n", -1) 236 return err 237 }) 238 239 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 240 return client.Issues.DeleteMilestone(ctx, "o", "r", 1) 241 }) 242 } 243 244 func TestIssuesService_DeleteMilestone_invalidOwner(t *testing.T) { 245 client, _, _, teardown := setup() 246 defer teardown() 247 248 ctx := context.Background() 249 _, err := client.Issues.DeleteMilestone(ctx, "%", "r", 1) 250 testURLParseError(t, err) 251 } 252 253 func TestMilestone_Marshal(t *testing.T) { 254 testJSONMarshal(t, &Milestone{}, "{}") 255 256 u := &Milestone{ 257 URL: String("url"), 258 HTMLURL: String("hurl"), 259 LabelsURL: String("lurl"), 260 ID: Int64(1), 261 Number: Int(1), 262 State: String("state"), 263 Title: String("title"), 264 Description: String("desc"), 265 Creator: &User{ 266 Login: String("l"), 267 ID: Int64(1), 268 URL: String("u"), 269 AvatarURL: String("a"), 270 GravatarID: String("g"), 271 Name: String("n"), 272 Company: String("c"), 273 Blog: String("b"), 274 Location: String("l"), 275 Email: String("e"), 276 Hireable: Bool(true), 277 Bio: String("b"), 278 TwitterUsername: String("tu"), 279 PublicRepos: Int(1), 280 Followers: Int(1), 281 Following: Int(1), 282 CreatedAt: &Timestamp{referenceTime}, 283 SuspendedAt: &Timestamp{referenceTime}, 284 }, 285 OpenIssues: Int(1), 286 ClosedIssues: Int(1), 287 CreatedAt: &referenceTime, 288 UpdatedAt: &referenceTime, 289 ClosedAt: &referenceTime, 290 DueOn: &referenceTime, 291 NodeID: String("nid"), 292 } 293 294 want := `{ 295 "url": "url", 296 "html_url": "hurl", 297 "labels_url": "lurl", 298 "id": 1, 299 "number": 1, 300 "state": "state", 301 "title": "title", 302 "description": "desc", 303 "creator": { 304 "login": "l", 305 "id": 1, 306 "avatar_url": "a", 307 "gravatar_id": "g", 308 "name": "n", 309 "company": "c", 310 "blog": "b", 311 "location": "l", 312 "email": "e", 313 "hireable": true, 314 "bio": "b", 315 "twitter_username": "tu", 316 "public_repos": 1, 317 "followers": 1, 318 "following": 1, 319 "created_at": ` + referenceTimeStr + `, 320 "suspended_at": ` + referenceTimeStr + `, 321 "url": "u" 322 }, 323 "open_issues": 1, 324 "closed_issues": 1, 325 "created_at": ` + referenceTimeStr + `, 326 "updated_at": ` + referenceTimeStr + `, 327 "closed_at": ` + referenceTimeStr + `, 328 "due_on": ` + referenceTimeStr + `, 329 "node_id": "nid" 330 }` 331 332 testJSONMarshal(t, u, want) 333 }