blob: 947fbd78aaa5d9531e6449f19b875198e62f361d [file] [log] [blame]
Dave Borowitzd0b7e182013-01-11 15:55:09 -08001// Copyright 2012 Google Inc. All Rights Reserved.
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
15package com.google.gitiles;
16
Dave Borowitzfde41fd2015-09-16 15:14:38 -040017import static com.google.common.truth.Truth.assertThat;
Dave Borowitz1d94e652014-07-30 12:45:09 -070018import static com.google.gitiles.TestGitilesUrls.URLS;
Dave Borowitzd0b7e182013-01-11 15:55:09 -080019
Dave Borowitz32ec5b92014-07-30 07:43:28 -070020import com.google.common.collect.ImmutableList;
Dave Borowitz1d94e652014-07-30 12:45:09 -070021import com.google.common.collect.ImmutableMap;
Dave Borowitz32ec5b92014-07-30 07:43:28 -070022import com.google.gitiles.RefServlet.RefJsonData;
Dave Borowitz32ec5b92014-07-30 07:43:28 -070023import com.google.gson.reflect.TypeToken;
Dave Borowitz3b744b12016-08-19 16:11:10 -040024import java.io.IOException;
25import java.util.List;
26import java.util.Map;
27import javax.servlet.http.HttpServletRequest;
Dave Borowitzd0b7e182013-01-11 15:55:09 -080028import org.eclipse.jgit.lib.ObjectId;
29import org.eclipse.jgit.lib.Repository;
30import org.eclipse.jgit.revwalk.RevCommit;
31import org.eclipse.jgit.revwalk.RevTag;
Dave Borowitz1d94e652014-07-30 12:45:09 -070032import org.eclipse.jgit.revwalk.RevWalk;
Dave Borowitzd40bdf12014-04-19 19:33:56 -070033import org.junit.Test;
Dave Borowitz3dc854f2014-11-04 16:19:37 -080034import org.junit.runner.RunWith;
35import org.junit.runners.JUnit4;
Dave Borowitzd40bdf12014-04-19 19:33:56 -070036
Nodir Turakulov08cdc232015-08-28 12:02:16 -070037/** Tests for {@link RefServlet}. */
Dave Borowitz3dc854f2014-11-04 16:19:37 -080038@RunWith(JUnit4.class)
Nodir Turakulov4bc26002015-08-18 18:24:37 -070039public class RefServletTest extends ServletTest {
Dave Borowitz1d94e652014-07-30 12:45:09 -070040 private void setUpSimpleRefs() throws Exception {
Dave Borowitzd0b7e182013-01-11 15:55:09 -080041 RevCommit commit = repo.branch("refs/heads/master").commit().create();
42 repo.update("refs/heads/branch", commit);
43 repo.update("refs/tags/ctag", commit);
44 RevTag tag = repo.tag("atag", commit);
45 repo.update("refs/tags/atag", tag);
Dave Borowitz1d94e652014-07-30 12:45:09 -070046 repo.getRepository().updateRef("HEAD").link("refs/heads/master");
Dave Borowitzd0b7e182013-01-11 15:55:09 -080047 }
48
Dave Borowitzd40bdf12014-04-19 19:33:56 -070049 @Test
50 public void evilRefName() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -070051 setUpSimpleRefs();
Dave Borowitzd0b7e182013-01-11 15:55:09 -080052 String evilRefName = "refs/evil/<script>window.close();</script>/&foo";
Dave Borowitzfde41fd2015-09-16 15:14:38 -040053 assertThat(Repository.isValidRefName(evilRefName)).isTrue();
Dave Borowitzd0b7e182013-01-11 15:55:09 -080054 repo.branch(evilRefName).commit().create();
55
Nodir Turakulov4bc26002015-08-18 18:24:37 -070056 FakeHttpServletResponse res = buildText("/repo/+refs/evil");
Dave Borowitzcf38c032016-05-02 11:06:23 -040057 assertThat(res.getActualBodyString())
58 .isEqualTo(
59 id(evilRefName) + " refs/evil/&lt;script&gt;window.close();&lt;/script&gt;/&amp;foo\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -080060 }
61
Dave Borowitzd40bdf12014-04-19 19:33:56 -070062 @Test
63 public void getRefsTextAll() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -070064 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -070065 FakeHttpServletResponse res = buildText("/repo/+refs");
Dave Borowitzd0b7e182013-01-11 15:55:09 -080066
Dave Borowitzcf38c032016-05-02 11:06:23 -040067 assertThat(res.getActualBodyString())
68 .isEqualTo(
69 id("HEAD")
70 + " HEAD\n"
71 + id("refs/heads/branch")
72 + " refs/heads/branch\n"
73 + id("refs/heads/master")
74 + " refs/heads/master\n"
75 + id("refs/tags/atag")
76 + " refs/tags/atag\n"
77 + peeled("refs/tags/atag")
78 + " refs/tags/atag^{}\n"
79 + id("refs/tags/ctag")
80 + " refs/tags/ctag\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -080081 }
82
Dave Borowitzd40bdf12014-04-19 19:33:56 -070083 @Test
84 public void getRefsTextAllTrailingSlash() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -070085 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -070086 FakeHttpServletResponse res = buildText("/repo/+refs/");
Dave Borowitzd0b7e182013-01-11 15:55:09 -080087
Dave Borowitzcf38c032016-05-02 11:06:23 -040088 assertThat(res.getActualBodyString())
89 .isEqualTo(
90 id("HEAD")
91 + " HEAD\n"
92 + id("refs/heads/branch")
93 + " refs/heads/branch\n"
94 + id("refs/heads/master")
95 + " refs/heads/master\n"
96 + id("refs/tags/atag")
97 + " refs/tags/atag\n"
98 + peeled("refs/tags/atag")
99 + " refs/tags/atag^{}\n"
100 + id("refs/tags/ctag")
101 + " refs/tags/ctag\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800102 }
103
Dave Borowitzd40bdf12014-04-19 19:33:56 -0700104 @Test
105 public void getRefsHeadsText() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700106 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700107 FakeHttpServletResponse res = buildText("/repo/+refs/heads");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800108
Dave Borowitzcf38c032016-05-02 11:06:23 -0400109 assertThat(res.getActualBodyString())
110 .isEqualTo(
111 id("refs/heads/branch")
112 + " refs/heads/branch\n"
113 + id("refs/heads/master")
114 + " refs/heads/master\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800115 }
116
Dave Borowitzd40bdf12014-04-19 19:33:56 -0700117 @Test
118 public void getRefsHeadsTextTrailingSlash() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700119 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700120 FakeHttpServletResponse res = buildText("/repo/+refs/heads/");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800121
Dave Borowitzcf38c032016-05-02 11:06:23 -0400122 assertThat(res.getActualBodyString())
123 .isEqualTo(
124 id("refs/heads/branch")
125 + " refs/heads/branch\n"
126 + id("refs/heads/master")
127 + " refs/heads/master\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800128 }
129
Dave Borowitzd40bdf12014-04-19 19:33:56 -0700130 @Test
131 public void noHeadText() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700132 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700133 FakeHttpServletResponse res = buildText("/repo/+refs/HEAD");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800134
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800135 // /+refs/foo means refs/foo(/*), so this is empty.
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400136 assertThat(res.getActualBodyString()).isEqualTo("");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800137 }
138
Dave Borowitzd40bdf12014-04-19 19:33:56 -0700139 @Test
140 public void singleHeadText() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700141 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700142 FakeHttpServletResponse res = buildText("/repo/+refs/heads/master");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800143
Dave Borowitzcf38c032016-05-02 11:06:23 -0400144 assertThat(res.getActualBodyString())
145 .isEqualTo(id("refs/heads/master") + " refs/heads/master\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800146 }
147
Dave Borowitzd40bdf12014-04-19 19:33:56 -0700148 @Test
Alice Kober-Sotzek53794aa2018-11-07 14:29:47 +0100149 public void singleHeadJson() throws Exception {
150 setUpSimpleRefs();
151 Map<String, RefJsonData> result = buildRefJson("/repo/+refs/heads/master");
152
153 assertThat(result.keySet()).containsExactly("refs/heads/master");
154 RefJsonData master = result.get("refs/heads/master");
155 assertThat(master.value).isEqualTo(id("refs/heads/master"));
156 assertThat(master.peeled).isNull();
157 assertThat(master.target).isNull();
158 }
159
160 @Test
Dave Borowitzd40bdf12014-04-19 19:33:56 -0700161 public void singlePeeledTagText() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700162 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700163 FakeHttpServletResponse res = buildText("/repo/+refs/tags/atag");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800164
Dave Borowitzcf38c032016-05-02 11:06:23 -0400165 assertThat(res.getActualBodyString())
166 .isEqualTo(
167 id("refs/tags/atag")
168 + " refs/tags/atag\n"
169 + peeled("refs/tags/atag")
170 + " refs/tags/atag^{}\n");
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800171 }
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700172
173 @Test
174 public void getRefsJsonAll() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700175 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700176 Map<String, RefJsonData> result = buildRefJson("/repo/+refs");
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700177 List<String> keys = ImmutableList.copyOf(result.keySet());
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400178 assertThat(keys)
179 .containsExactly(
Dave Borowitzcf38c032016-05-02 11:06:23 -0400180 "HEAD", "refs/heads/branch", "refs/heads/master", "refs/tags/atag", "refs/tags/ctag")
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400181 .inOrder();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700182
183 RefJsonData head = result.get(keys.get(0));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400184 assertThat(head.value).isEqualTo(id("HEAD"));
185 assertThat(head.peeled).isNull();
186 assertThat(head.target).isEqualTo("refs/heads/master");
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700187
188 RefJsonData branch = result.get(keys.get(1));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400189 assertThat(branch.value).isEqualTo(id("refs/heads/branch"));
190 assertThat(branch.peeled).isNull();
191 assertThat(branch.target).isNull();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700192
193 RefJsonData master = result.get(keys.get(2));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400194 assertThat(master.value).isEqualTo(id("refs/heads/master"));
195 assertThat(master.peeled).isNull();
196 assertThat(master.target).isNull();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700197
198 RefJsonData atag = result.get(keys.get(3));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400199 assertThat(atag.value).isEqualTo(id("refs/tags/atag"));
200 assertThat(atag.peeled).isEqualTo(peeled("refs/tags/atag"));
201 assertThat(atag.target).isNull();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700202
203 RefJsonData ctag = result.get(keys.get(4));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400204 assertThat(ctag.value).isEqualTo(id("refs/tags/ctag"));
205 assertThat(ctag.peeled).isNull();
206 assertThat(ctag.target).isNull();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700207 }
208
209 @Test
210 public void getRefsHeadsJson() throws Exception {
Dave Borowitz1d94e652014-07-30 12:45:09 -0700211 setUpSimpleRefs();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700212 Map<String, RefJsonData> result = buildRefJson("/repo/+refs/heads");
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700213 List<String> keys = ImmutableList.copyOf(result.keySet());
Dave Borowitzcf38c032016-05-02 11:06:23 -0400214 assertThat(keys).containsExactly("branch", "master").inOrder();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700215
216 RefJsonData branch = result.get(keys.get(0));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400217 assertThat(branch.value).isEqualTo(id("refs/heads/branch"));
218 assertThat(branch.peeled).isNull();
219 assertThat(branch.target).isNull();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700220
221 RefJsonData master = result.get(keys.get(1));
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400222 assertThat(master.value).isEqualTo(id("refs/heads/master"));
223 assertThat(master.peeled).isNull();
224 assertThat(master.target).isNull();
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700225 }
226
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700227 private Map<String, RefJsonData> buildRefJson(String path) throws Exception {
Dave Borowitza774f592015-10-26 11:41:27 -0400228 return buildJson(new TypeToken<Map<String, RefJsonData>>() {}, path);
Dave Borowitz32ec5b92014-07-30 07:43:28 -0700229 }
Dave Borowitz1d94e652014-07-30 12:45:09 -0700230
231 @Test
232 public void emptySoy() throws Exception {
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400233 assertThat(buildBranchesSoyData()).isEmpty();
234 assertThat(buildTagsSoyData()).isEmpty();
Dave Borowitz1d94e652014-07-30 12:45:09 -0700235 }
236
237 @Test
238 public void branchesAndTagsSoy() throws Exception {
239 repo.branch("refs/heads/foo").commit().create();
240 repo.branch("refs/heads/bar").commit().create();
241 repo.branch("refs/tags/baz").commit().create();
242 repo.branch("refs/nope/quux").commit().create();
243
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400244 assertThat(buildBranchesSoyData())
Ivan Frade92b84722019-02-12 14:03:10 -0800245 .containsExactly(
246 ref("/b/test/+/refs/heads/bar", "bar"), ref("/b/test/+/refs/heads/foo", "foo"))
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400247 .inOrder();
Ivan Frade92b84722019-02-12 14:03:10 -0800248 assertThat(buildTagsSoyData()).containsExactly(ref("/b/test/+/refs/tags/baz", "baz")).inOrder();
Dave Borowitz1d94e652014-07-30 12:45:09 -0700249 }
250
251 @Test
252 public void ambiguousBranchSoy() throws Exception {
253 repo.branch("refs/heads/foo").commit().create();
254 repo.branch("refs/heads/bar").commit().create();
255 repo.branch("refs/tags/foo").commit().create();
256
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400257 assertThat(buildBranchesSoyData())
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400258 .containsExactly(
Ivan Frade92b84722019-02-12 14:03:10 -0800259 ref("/b/test/+/refs/heads/bar", "bar"), ref("/b/test/+/refs/heads/foo", "foo"))
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400260 .inOrder();
Ivan Frade92b84722019-02-12 14:03:10 -0800261 assertThat(buildTagsSoyData()).containsExactly(ref("/b/test/+/refs/tags/foo", "foo")).inOrder();
Dave Borowitz1d94e652014-07-30 12:45:09 -0700262 }
263
264 @Test
265 public void ambiguousRelativeToNonBranchOrTagSoy() throws Exception {
266 repo.branch("refs/foo").commit().create();
267 repo.branch("refs/heads/foo").commit().create();
268 repo.branch("refs/tags/foo").commit().create();
269
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400270 assertThat(buildBranchesSoyData())
Dave Borowitzcf38c032016-05-02 11:06:23 -0400271 .containsExactly(ref("/b/test/+/refs/heads/foo", "foo"))
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400272 .inOrder();
Dave Borowitzcf38c032016-05-02 11:06:23 -0400273 assertThat(buildTagsSoyData()).containsExactly(ref("/b/test/+/refs/tags/foo", "foo")).inOrder();
Dave Borowitz1d94e652014-07-30 12:45:09 -0700274 }
275
276 @Test
277 public void refsHeadsSoy() throws Exception {
278 repo.branch("refs/heads/foo").commit().create();
279 repo.branch("refs/heads/refs/heads/foo").commit().create();
280
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400281 assertThat(buildBranchesSoyData())
282 .containsExactly(
Ivan Frade92b84722019-02-12 14:03:10 -0800283 ref("/b/test/+/refs/heads/foo", "foo"),
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400284 ref("/b/test/+/refs/heads/refs/heads/foo", "refs/heads/foo"))
285 .inOrder();
Dave Borowitz1d94e652014-07-30 12:45:09 -0700286 }
287
288 private HttpServletRequest buildSoyRequest() {
289 HttpServletRequest req = FakeHttpServletRequest.newRequest(repo.getRepository());
Dave Borowitzcf38c032016-05-02 11:06:23 -0400290 ViewFilter.setView(
291 req,
292 GitilesView.repositoryIndex()
293 .setHostName(URLS.getHostName(req))
294 .setServletPath(req.getServletPath())
295 .setRepositoryName("test")
296 .build());
Dave Borowitz1d94e652014-07-30 12:45:09 -0700297 return req;
298 }
299
300 private List<?> buildBranchesSoyData() throws Exception {
301 return RefServlet.getBranchesSoyData(buildSoyRequest(), Integer.MAX_VALUE);
302 }
303
304 private List<?> buildTagsSoyData() throws Exception {
Shawn Pearceb5ad0a02015-05-24 20:33:17 -0700305 try (RevWalk rw = new RevWalk(repo.getRepository())) {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400306 return RefServlet.getTagsSoyData(
307 buildSoyRequest(), new TimeCache(TimeCache.defaultBuilder()), rw, Integer.MAX_VALUE);
Dave Borowitz1d94e652014-07-30 12:45:09 -0700308 }
309 }
310
311 private String id(String refName) throws IOException {
Dave Borowitz14cad732016-05-26 17:34:19 -0400312 return ObjectId.toString(repo.getRepository().exactRef(refName).getObjectId());
Dave Borowitz1d94e652014-07-30 12:45:09 -0700313 }
314
315 private String peeled(String refName) throws IOException {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400316 return ObjectId.toString(
David Pursehousedcb3d052018-07-03 14:04:17 +0900317 repo.getRepository()
318 .getRefDatabase()
319 .peel(repo.getRepository().exactRef(refName))
320 .getPeeledObjectId());
Dave Borowitz1d94e652014-07-30 12:45:09 -0700321 }
322
323 private Map<String, String> ref(String url, String name) {
324 return ImmutableMap.of("url", url, "name", name);
325 }
Dave Borowitzd0b7e182013-01-11 15:55:09 -0800326}