blob: b492ed3f09f9f4bfdd3a4cbad4caa37a796075a8 [file] [log] [blame]
Dave Borowitzb7fd3f32014-05-01 12:31:25 -07001// Copyright (C) 2014 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 Borowitz4f568702014-05-01 19:54:57 -070018import static java.nio.charset.StandardCharsets.UTF_8;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070019
Dave Borowitz4f568702014-05-01 19:54:57 -070020import com.google.common.io.BaseEncoding;
Dave Borowitz3c441502014-09-05 16:06:37 -070021import com.google.gitiles.TreeJsonData.Tree;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070022import com.google.template.soy.data.SoyListData;
23import com.google.template.soy.data.restricted.StringData;
Dave Borowitz3b744b12016-08-19 16:11:10 -040024import java.util.List;
25import java.util.Map;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070026import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
27import org.eclipse.jgit.dircache.DirCacheEntry;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070028import org.eclipse.jgit.lib.FileMode;
29import org.eclipse.jgit.lib.ObjectId;
30import org.eclipse.jgit.revwalk.RevBlob;
Dave Borowitz2387b142014-05-02 16:56:27 -070031import org.eclipse.jgit.revwalk.RevCommit;
Dave Borowitz228f3572014-05-02 14:26:25 -070032import org.eclipse.jgit.revwalk.RevTree;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070033import org.junit.Test;
Dave Borowitz3dc854f2014-11-04 16:19:37 -080034import org.junit.runner.RunWith;
35import org.junit.runners.JUnit4;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070036
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070037/** Tests for {@PathServlet}. */
38@SuppressWarnings("unchecked")
Dave Borowitz3dc854f2014-11-04 16:19:37 -080039@RunWith(JUnit4.class)
Nodir Turakulov4bc26002015-08-18 18:24:37 -070040public class PathServletTest extends ServletTest {
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070041 @Test
42 public void rootTreeHtml() throws Exception {
43 repo.branch("master").commit().add("foo", "contents").create();
44
45 Map<String, ?> data = buildData("/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040046 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070047 List<Map<String, ?>> entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040048 assertThat(entries).hasSize(1);
49 assertThat(entries.get(0).get("name")).isEqualTo("foo");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070050 }
51
52 @Test
53 public void subTreeHtml() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -040054 repo.branch("master")
55 .commit()
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070056 .add("foo/bar", "bar contents")
57 .add("baz", "baz contents")
58 .create();
59
60 Map<String, ?> data = buildData("/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040061 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070062 List<Map<String, ?>> entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040063 assertThat(entries).hasSize(2);
64 assertThat(entries.get(0).get("name")).isEqualTo("baz");
65 assertThat(entries.get(1).get("name")).isEqualTo("foo/");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070066
67 data = buildData("/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040068 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070069 entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040070 assertThat(entries).hasSize(1);
71 assertThat(entries.get(0).get("name")).isEqualTo("bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070072
73 data = buildData("/repo/+/master/foo/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040074 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070075 entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040076 assertThat(entries).hasSize(1);
77 assertThat(entries.get(0).get("name")).isEqualTo("bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070078 }
79
80 @Test
81 public void fileHtml() throws Exception {
82 repo.branch("master").commit().add("foo", "foo\ncontents\n").create();
83
84 Map<String, ?> data = buildData("/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040085 assertThat(data).containsEntry("type", "REGULAR_FILE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070086
87 SoyListData lines = (SoyListData) getBlobData(data).get("lines");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040088 assertThat(lines.length()).isEqualTo(2);
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070089
90 SoyListData spans = lines.getListData(0);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040091 assertThat(spans.length()).isEqualTo(1);
92 assertThat(spans.getMapData(0).get("classes")).isEqualTo(StringData.forValue("pln"));
93 assertThat(spans.getMapData(0).get("text")).isEqualTo(StringData.forValue("foo"));
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070094
95 spans = lines.getListData(1);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040096 assertThat(spans.length()).isEqualTo(1);
97 assertThat(spans.getMapData(0).get("classes")).isEqualTo(StringData.forValue("pln"));
98 assertThat(spans.getMapData(0).get("text")).isEqualTo(StringData.forValue("contents"));
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070099 }
100
101 @Test
102 public void symlinkHtml() throws Exception {
103 final RevBlob link = repo.blob("foo");
Dave Borowitzcf38c032016-05-02 11:06:23 -0400104 repo.branch("master")
105 .commit()
106 .add("foo", "contents")
107 .edit(
108 new PathEdit("bar") {
109 @Override
110 public void apply(DirCacheEntry ent) {
111 ent.setFileMode(FileMode.SYMLINK);
112 ent.setObjectId(link);
113 }
114 })
115 .create();
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700116
117 Map<String, ?> data = buildData("/repo/+/master/bar");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400118 assertThat(data).containsEntry("type", "SYMLINK");
119 assertThat(getBlobData(data)).containsEntry("target", "foo");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700120 }
121
122 @Test
123 public void gitlinkHtml() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400124 String gitmodules =
125 "[submodule \"gitiles\"]\n"
126 + " path = gitiles\n"
127 + " url = https://gerrit.googlesource.com/gitiles\n";
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700128 final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
Dave Borowitzcf38c032016-05-02 11:06:23 -0400129 repo.branch("master")
130 .commit()
131 .add(".gitmodules", gitmodules)
132 .edit(
133 new PathEdit("gitiles") {
134 @Override
135 public void apply(DirCacheEntry ent) {
136 ent.setFileMode(FileMode.GITLINK);
137 ent.setObjectId(ObjectId.fromString(gitilesSha));
138 }
139 })
140 .create();
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700141
142 Map<String, ?> data = buildData("/repo/+/master/gitiles");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400143 assertThat(data).containsEntry("type", "GITLINK");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700144
145 Map<String, ?> linkData = getBlobData(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400146 assertThat(linkData).containsEntry("sha", gitilesSha);
147 assertThat(linkData).containsEntry("remoteUrl", "https://gerrit.googlesource.com/gitiles");
148 assertThat(linkData).containsEntry("httpUrl", "https://gerrit.googlesource.com/gitiles");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700149 }
150
Dave Borowitz4f568702014-05-01 19:54:57 -0700151 @Test
152 public void blobText() throws Exception {
153 repo.branch("master").commit().add("foo", "contents").create();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700154 String text = buildBlob("/repo/+/master/foo", "100644");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400155 assertThat(text).isEqualTo("contents");
Dave Borowitz4f568702014-05-01 19:54:57 -0700156 }
157
158 @Test
159 public void symlinkText() throws Exception {
160 final RevBlob link = repo.blob("foo");
Dave Borowitzcf38c032016-05-02 11:06:23 -0400161 repo.branch("master")
162 .commit()
163 .edit(
164 new PathEdit("baz") {
165 @Override
166 public void apply(DirCacheEntry ent) {
167 ent.setFileMode(FileMode.SYMLINK);
168 ent.setObjectId(link);
169 }
170 })
171 .create();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700172 String text = buildBlob("/repo/+/master/baz", "120000");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400173 assertThat(text).isEqualTo("foo");
Dave Borowitz228f3572014-05-02 14:26:25 -0700174 }
175
176 @Test
177 public void treeText() throws Exception {
178 RevBlob blob = repo.blob("contents");
179 RevTree tree = repo.tree(repo.file("foo/bar", blob));
180 repo.branch("master").commit().setTopLevelTree(tree).create();
181
182 String expected = "040000 tree " + repo.get(tree, "foo").name() + "\tfoo\n";
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400183 assertThat(buildBlob("/repo/+/master/", "040000")).isEqualTo(expected);
Dave Borowitz228f3572014-05-02 14:26:25 -0700184
185 expected = "100644 blob " + blob.name() + "\tbar\n";
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400186 assertThat(buildBlob("/repo/+/master/foo", "040000")).isEqualTo(expected);
187 assertThat(buildBlob("/repo/+/master/foo/", "040000")).isEqualTo(expected);
Dave Borowitz228f3572014-05-02 14:26:25 -0700188 }
189
190 @Test
191 public void treeTextEscaped() throws Exception {
192 RevBlob blob = repo.blob("contents");
193 repo.branch("master").commit().add("foo\nbar\rbaz", blob).create();
194
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400195 assertThat(buildBlob("/repo/+/master/", "040000"))
196 .isEqualTo("100644 blob " + blob.name() + "\t\"foo\\nbar\\rbaz\"\n");
Dave Borowitz4f568702014-05-01 19:54:57 -0700197 }
198
199 @Test
200 public void nonBlobText() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400201 String gitmodules =
202 "[submodule \"gitiles\"]\n"
203 + " path = gitiles\n"
204 + " url = https://gerrit.googlesource.com/gitiles\n";
Dave Borowitz4f568702014-05-01 19:54:57 -0700205 final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
Dave Borowitzcf38c032016-05-02 11:06:23 -0400206 repo.branch("master")
207 .commit()
Dave Borowitz4f568702014-05-01 19:54:57 -0700208 .add("foo/bar", "contents")
209 .add(".gitmodules", gitmodules)
Dave Borowitzcf38c032016-05-02 11:06:23 -0400210 .edit(
211 new PathEdit("gitiles") {
212 @Override
213 public void apply(DirCacheEntry ent) {
214 ent.setFileMode(FileMode.GITLINK);
215 ent.setObjectId(ObjectId.fromString(gitilesSha));
216 }
217 })
218 .create();
Dave Borowitz4f568702014-05-01 19:54:57 -0700219
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700220 assertNotFound("/repo/+/master/nonexistent", "format=text");
221 assertNotFound("/repo/+/master/gitiles", "format=text");
Dave Borowitz4f568702014-05-01 19:54:57 -0700222 }
223
Dave Borowitz2387b142014-05-02 16:56:27 -0700224 @Test
Han-Wen Nienhuys8aefdb82016-05-02 16:49:35 +0200225 public void treeJsonSizes() throws Exception {
226 RevCommit c = repo.parseBody(repo.branch("master").commit().add("baz", "01234567").create());
227
228 Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
229
230 assertThat(tree.id).isEqualTo(c.getTree().name());
231 assertThat(tree.entries).hasSize(1);
232 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
233 assertThat(tree.entries.get(0).type).isEqualTo("blob");
234 assertThat(tree.entries.get(0).name).isEqualTo("baz");
235 assertThat(tree.entries.get(0).size).isEqualTo(8);
236 }
237
238 @Test
239 public void treeJsonLinkTarget() throws Exception {
240 final ObjectId targetID = repo.blob("target");
241 RevCommit c =
242 repo.parseBody(
243 repo.branch("master")
244 .commit()
245 .edit(
246 new PathEdit("link") {
247 @Override
248 public void apply(DirCacheEntry ent) {
249 ent.setFileMode(FileMode.SYMLINK);
250 ent.setObjectId(targetID);
251 }
252 })
253 .create());
254
255 Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
256
257 assertThat(tree.id).isEqualTo(c.getTree().name());
258 assertThat(tree.entries).hasSize(1);
259
260 TreeJsonData.Entry e = tree.entries.get(0);
261 assertThat(e.mode).isEqualTo(0120000);
262 assertThat(e.type).isEqualTo("blob");
263 assertThat(e.name).isEqualTo("link");
264 assertThat(e.id).isEqualTo(targetID.name());
265 assertThat(e.target).isEqualTo("target");
266 }
267
268 @Test
Han-Wen Nienhuys0dc93872016-05-03 15:21:42 +0200269 public void treeJsonRecursive() throws Exception {
270 RevCommit c =
271 repo.parseBody(
272 repo.branch("master")
273 .commit()
274 .add("foo/baz/bar/a", "bar contents")
275 .add("foo/baz/bar/b", "bar contents")
276 .add("baz", "baz contents")
277 .create());
278 Tree tree = buildJson(Tree.class, "/repo/+/master/", "recursive=1");
279
280 assertThat(tree.id).isEqualTo(c.getTree().name());
281 assertThat(tree.entries).hasSize(3);
282
283 assertThat(tree.entries.get(0).name).isEqualTo("baz");
284 assertThat(tree.entries.get(1).name).isEqualTo("foo/baz/bar/a");
285 assertThat(tree.entries.get(2).name).isEqualTo("foo/baz/bar/b");
286
287 tree = buildJson(Tree.class, "/repo/+/master/foo/baz", "recursive=1");
288
289 assertThat(tree.entries).hasSize(2);
290
291 assertThat(tree.entries.get(0).name).isEqualTo("bar/a");
292 assertThat(tree.entries.get(1).name).isEqualTo("bar/b");
293 }
294
295 @Test
Dave Borowitz2387b142014-05-02 16:56:27 -0700296 public void treeJson() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400297 RevCommit c =
298 repo.parseBody(
299 repo.branch("master")
300 .commit()
301 .add("foo/bar", "bar contents")
302 .add("baz", "baz contents")
303 .create());
Dave Borowitz2387b142014-05-02 16:56:27 -0700304
Dave Borowitza774f592015-10-26 11:41:27 -0400305 Tree tree = buildJson(Tree.class, "/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400306 assertThat(tree.id).isEqualTo(c.getTree().name());
307 assertThat(tree.entries).hasSize(2);
308 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
309 assertThat(tree.entries.get(0).type).isEqualTo("blob");
310 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "baz").name());
311 assertThat(tree.entries.get(0).name).isEqualTo("baz");
312 assertThat(tree.entries.get(1).mode).isEqualTo(040000);
313 assertThat(tree.entries.get(1).type).isEqualTo("tree");
314 assertThat(tree.entries.get(1).id).isEqualTo(repo.get(c.getTree(), "foo").name());
315 assertThat(tree.entries.get(1).name).isEqualTo("foo");
Dave Borowitz2387b142014-05-02 16:56:27 -0700316
Dave Borowitza774f592015-10-26 11:41:27 -0400317 tree = buildJson(Tree.class, "/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400318 assertThat(tree.id).isEqualTo(repo.get(c.getTree(), "foo").name());
319 assertThat(tree.entries).hasSize(1);
320 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
321 assertThat(tree.entries.get(0).type).isEqualTo("blob");
322 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "foo/bar").name());
323 assertThat(tree.entries.get(0).name).isEqualTo("bar");
Dave Borowitz2387b142014-05-02 16:56:27 -0700324
Dave Borowitza774f592015-10-26 11:41:27 -0400325 tree = buildJson(Tree.class, "/repo/+/master/foo/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400326 assertThat(tree.id).isEqualTo(repo.get(c.getTree(), "foo").name());
327 assertThat(tree.entries).hasSize(1);
328 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
329 assertThat(tree.entries.get(0).type).isEqualTo("blob");
330 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "foo/bar").name());
331 assertThat(tree.entries.get(0).name).isEqualTo("bar");
Dave Borowitz2387b142014-05-02 16:56:27 -0700332 }
333
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700334 private Map<String, ?> getBlobData(Map<String, ?> data) {
335 return ((Map<String, Map<String, ?>>) data).get("data");
336 }
337
338 private List<Map<String, ?>> getTreeEntries(Map<String, ?> data) {
339 return ((Map<String, List<Map<String, ?>>>) data.get("data")).get("entries");
340 }
341
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700342 private String buildBlob(String path, String expectedMode) throws Exception {
343 FakeHttpServletResponse res = buildText(path);
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400344 assertThat(res.getHeader(PathServlet.MODE_HEADER)).isEqualTo(expectedMode);
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700345 String base64 = res.getActualBodyString();
346 return new String(BaseEncoding.base64().decode(base64), UTF_8);
Dave Borowitz228f3572014-05-02 14:26:25 -0700347 }
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700348}