go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/common/api/gitiles/rest_test.go (about) 1 // Copyright 2017 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package gitiles 16 17 import ( 18 "context" 19 "fmt" 20 "net/http" 21 "net/http/httptest" 22 "sort" 23 "testing" 24 25 "go.chromium.org/luci/common/proto/git" 26 "go.chromium.org/luci/common/proto/gitiles" 27 28 . "github.com/smartystreets/goconvey/convey" 29 . "go.chromium.org/luci/common/testing/assertions" 30 ) 31 32 func TestLog(t *testing.T) { 33 t.Parallel() 34 ctx := context.Background() 35 36 Convey("Log with bad project", t, func() { 37 srv, c := newMockClient(func(w http.ResponseWriter, r *http.Request) {}) 38 defer srv.Close() 39 _, err := c.Log(ctx, &gitiles.LogRequest{}) 40 So(err, ShouldErrLike, "project is required") 41 }) 42 43 Convey("Log w/o pages", t, func() { 44 srv, c := newMockClient(func(w http.ResponseWriter, r *http.Request) { 45 w.WriteHeader(200) 46 w.Header().Set("Content-Type", "application/json") 47 fmt.Fprintf(w, ")]}'\n{\"log\": [%s, %s]}\n", fakeCommit1Str, fakeCommit2Str) 48 }) 49 defer srv.Close() 50 51 Convey("Return All", func() { 52 res, err := c.Log(ctx, &gitiles.LogRequest{ 53 Project: "repo", 54 Committish: "8de6836858c99e48f3c58164ab717bda728e95dd", 55 ExcludeAncestorsOf: "master", 56 PageSize: 10, 57 }) 58 So(err, ShouldBeNil) 59 So(len(res.Log), ShouldEqual, 2) 60 So(res.Log[0].Author.Name, ShouldEqual, "Author 1") 61 So(res.Log[1].Id, ShouldEqual, "dc1dbf1aa56e4dd4cbfaab61c4d30a35adce5f40") 62 }) 63 }) 64 } 65 66 func TestRefs(t *testing.T) { 67 t.Parallel() 68 ctx := context.Background() 69 70 Convey("bad project", t, func() { 71 c := &client{BaseURL: "https://a.googlesource.com/a"} 72 _, err := c.Refs(ctx, &gitiles.RefsRequest{ 73 RefsPath: gitiles.AllRefs, 74 }) 75 So(err, ShouldErrLike, `project is required`) 76 }) 77 78 Convey("bad RefsPath", t, func() { 79 c := &client{BaseURL: "https://a.googlesource.com/a"} 80 _, err := c.Refs(ctx, &gitiles.RefsRequest{ 81 Project: "repo", 82 RefsPath: "bad", 83 }) 84 So(err, ShouldErrLike, `refsPath must be "refs" or start with "refs/"`) 85 }) 86 87 Convey("Refs All", t, func() { 88 srv, c := newMockClient(func(w http.ResponseWriter, r *http.Request) { 89 w.WriteHeader(200) 90 w.Header().Set("Content-Type", "application/json") 91 fmt.Fprintln(w, `)]}' 92 { 93 "refs/heads/master": { "value": "deadbeef" }, 94 "refs/heads/infra/config": { "value": "0000beef" }, 95 "refs/changes/01/123001/1": { "value": "123dead001beef1" }, 96 "refs/other/ref": { "value": "ba6" }, 97 "123deadbeef123": { "target": "f00" }, 98 "HEAD": { 99 "value": "deadbeef", 100 "target": "refs/heads/master" 101 } 102 } 103 `) 104 }) 105 defer srv.Close() 106 107 res, err := c.Refs(ctx, &gitiles.RefsRequest{ 108 Project: "repo", 109 RefsPath: gitiles.AllRefs, 110 }) 111 So(err, ShouldBeNil) 112 So(res.Revisions, ShouldResemble, map[string]string{ 113 "HEAD": "refs/heads/master", 114 "refs/heads/master": "deadbeef", 115 "refs/heads/infra/config": "0000beef", 116 "refs/other/ref": "ba6", 117 "refs/changes/01/123001/1": "123dead001beef1", 118 // Skipping "123dead001beef1" which has no value. 119 }) 120 }) 121 Convey("Refs heads", t, func() { 122 srv, c := newMockClient(func(w http.ResponseWriter, r *http.Request) { 123 w.WriteHeader(200) 124 w.Header().Set("Content-Type", "application/json") 125 fmt.Fprintln(w, `)]}' 126 { 127 "master": { "value": "deadbeef" }, 128 "infra/config": { "value": "0000beef" } 129 } 130 `) 131 }) 132 defer srv.Close() 133 134 res, err := c.Refs(ctx, &gitiles.RefsRequest{ 135 Project: "repo", 136 RefsPath: gitiles.Branches, 137 }) 138 So(err, ShouldBeNil) 139 So(res.Revisions, ShouldResemble, map[string]string{ 140 "refs/heads/master": "deadbeef", 141 "refs/heads/infra/config": "0000beef", 142 }) 143 }) 144 } 145 146 func TestProjects(t *testing.T) { 147 t.Parallel() 148 ctx := context.Background() 149 150 Convey("List Projects", t, func() { 151 srv, c := newMockClient(func(w http.ResponseWriter, r *http.Request) { 152 w.WriteHeader(200) 153 w.Header().Set("Content-Type", "application/json") 154 fmt.Fprintln(w, `)]}' 155 { 156 "All-Projects": { 157 "name": "All-Projects", 158 "clone_url": "https://foo.googlesource.com/All-Projects", 159 "description": "foo" 160 }, 161 "bar": { 162 "name": "bar", 163 "clone_url": "https://foo.googlesource.com/bar", 164 "description": "bar description" 165 } 166 } 167 `) 168 }) 169 defer srv.Close() 170 171 res, err := c.Projects(ctx, &gitiles.ProjectsRequest{}) 172 So(err, ShouldBeNil) 173 // Sort project to make it deterministic 174 sort.Strings(res.Projects) 175 So(res.Projects, ShouldResemble, []string{ 176 "All-Projects", 177 "bar", 178 }) 179 }) 180 } 181 func TestList(t *testing.T) { 182 t.Parallel() 183 ctx := context.Background() 184 185 Convey("ListFiles", t, func() { 186 srv, c := newMockClient(func(w http.ResponseWriter, r *http.Request) { 187 w.WriteHeader(200) 188 w.Header().Set("Content-Type", "application/json") 189 fmt.Fprintln(w, `)]}' 190 { 191 "id": "860c9c8901a8de14bf9f6210257f2400ac19d11e", 192 "entries": [ 193 { 194 "mode": 33188, 195 "type": "blob", 196 "id": "7e5b457d492b50762386611fc7f1302f23b313cf", 197 "name": "foo.txt" 198 }, 199 { 200 "mode": 33188, 201 "type": "blob", 202 "id": "a07e845539145d1fb697c20b75689b25e266d6d6", 203 "name": "bar.txt" 204 }, 205 { 206 "mode": 33188, 207 "type": "tree", 208 "id": "b90e845539145d1fb697c20b75689b25e266d6c3", 209 "name": "directory" 210 }, 211 { 212 "mode": 33188, 213 "type": "random type", 214 "id": "k93b845539145d1fb697c20b75689b25e266d6q1", 215 "name": "new" 216 } 217 ] 218 } 219 `) 220 }) 221 defer srv.Close() 222 223 res, err := c.ListFiles(ctx, &gitiles.ListFilesRequest{ 224 Project: "project", 225 Committish: "main", 226 Path: "path/to/dir", 227 }) 228 So(err, ShouldBeNil) 229 So(res.Files, ShouldResemble, []*git.File{ 230 { 231 Mode: 33188, 232 Id: "7e5b457d492b50762386611fc7f1302f23b313cf", 233 Path: "foo.txt", 234 Type: git.File_BLOB, 235 }, 236 { 237 Mode: 33188, 238 Id: "a07e845539145d1fb697c20b75689b25e266d6d6", 239 Path: "bar.txt", 240 Type: git.File_BLOB, 241 }, 242 { 243 Mode: 33188, 244 Id: "b90e845539145d1fb697c20b75689b25e266d6c3", 245 Path: "directory", 246 Type: git.File_TREE, 247 }, 248 { 249 Mode: 33188, 250 Id: "k93b845539145d1fb697c20b75689b25e266d6q1", 251 Path: "new", 252 Type: git.File_UNKNOWN, 253 }, 254 }) 255 }) 256 } 257 258 func newMockClient(handler func(w http.ResponseWriter, r *http.Request)) (*httptest.Server, gitiles.GitilesClient) { 259 srv := httptest.NewServer(http.HandlerFunc(handler)) 260 return srv, &client{BaseURL: srv.URL} 261 } 262 263 var ( 264 fakeCommit1Str = `{ 265 "commit": "0b2c5409e58a71c691b05454b55cc5580cc822d1", 266 "tree": "3c6f95bc757698cd6aca3c49f88f640fd145ea69", 267 "parents": [ "dc1dbf1aa56e4dd4cbfaab61c4d30a35adce5f40" ], 268 "author": { 269 "name": "Author 1", 270 "email": "author1@example.com", 271 "time": "Mon Jul 17 15:02:43 2017 -0800" 272 }, 273 "committer": { 274 "name": "Commit Bot", 275 "email": "commit-bot@chromium.org", 276 "time": "Mon Jul 17 15:02:43 2017 +0000" 277 }, 278 "message": "Import wpt@d96d68ed964f9bfc2bb248c2d2fab7a8870dc685\\n\\nCr-Commit-Position: refs/heads/master@{#487078}" 279 }` 280 fakeCommit2Str = `{ 281 "commit": "dc1dbf1aa56e4dd4cbfaab61c4d30a35adce5f40", 282 "tree": "1ba2335c07915c31597b97a8d824aecc85a996f6", 283 "parents": ["8de6836858c99e48f3c58164ab717bda728e95dd"], 284 "author": { 285 "name": "Author 2", 286 "email": "author-2@example.com", 287 "time": "Mon Jul 17 15:01:13 2017" 288 }, 289 "committer": { 290 "name": "Commit Bot", 291 "email": "commit-bot@chromium.org", 292 "time": "Mon Jul 17 15:01:13 2017" 293 }, 294 "message": "[Web Payments] User weak ptr in Payment Request\u0027s error callback\\n\\nBug: 742329\\nReviewed-on: https://chromium-review.googlesource.com/570982\\nCr-Commit-Position: refs/heads/master@{#487077}" 295 }` 296 )