blob: 1eac476f92dbca23e0455747697a90bd25d59d0d [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;
24
25import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
26import org.eclipse.jgit.dircache.DirCacheEntry;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070027import org.eclipse.jgit.lib.FileMode;
28import org.eclipse.jgit.lib.ObjectId;
29import org.eclipse.jgit.revwalk.RevBlob;
Dave Borowitz2387b142014-05-02 16:56:27 -070030import org.eclipse.jgit.revwalk.RevCommit;
Dave Borowitz228f3572014-05-02 14:26:25 -070031import org.eclipse.jgit.revwalk.RevTree;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070032import org.junit.Test;
Dave Borowitz3dc854f2014-11-04 16:19:37 -080033import org.junit.runner.RunWith;
34import org.junit.runners.JUnit4;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070035
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070036import java.util.List;
37import java.util.Map;
38
39/** Tests for {@PathServlet}. */
40@SuppressWarnings("unchecked")
Dave Borowitz3dc854f2014-11-04 16:19:37 -080041@RunWith(JUnit4.class)
Nodir Turakulov4bc26002015-08-18 18:24:37 -070042public class PathServletTest extends ServletTest {
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070043 @Test
44 public void rootTreeHtml() throws Exception {
45 repo.branch("master").commit().add("foo", "contents").create();
46
47 Map<String, ?> data = buildData("/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040048 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070049 List<Map<String, ?>> entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040050 assertThat(entries).hasSize(1);
51 assertThat(entries.get(0).get("name")).isEqualTo("foo");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070052 }
53
54 @Test
55 public void subTreeHtml() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -040056 repo.branch("master")
57 .commit()
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070058 .add("foo/bar", "bar contents")
59 .add("baz", "baz contents")
60 .create();
61
62 Map<String, ?> data = buildData("/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040063 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070064 List<Map<String, ?>> entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040065 assertThat(entries).hasSize(2);
66 assertThat(entries.get(0).get("name")).isEqualTo("baz");
67 assertThat(entries.get(1).get("name")).isEqualTo("foo/");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070068
69 data = buildData("/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040070 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070071 entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040072 assertThat(entries).hasSize(1);
73 assertThat(entries.get(0).get("name")).isEqualTo("bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070074
75 data = buildData("/repo/+/master/foo/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040076 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070077 entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040078 assertThat(entries).hasSize(1);
79 assertThat(entries.get(0).get("name")).isEqualTo("bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070080 }
81
82 @Test
83 public void fileHtml() throws Exception {
84 repo.branch("master").commit().add("foo", "foo\ncontents\n").create();
85
86 Map<String, ?> data = buildData("/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040087 assertThat(data).containsEntry("type", "REGULAR_FILE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070088
89 SoyListData lines = (SoyListData) getBlobData(data).get("lines");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040090 assertThat(lines.length()).isEqualTo(2);
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070091
92 SoyListData spans = lines.getListData(0);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040093 assertThat(spans.length()).isEqualTo(1);
94 assertThat(spans.getMapData(0).get("classes")).isEqualTo(StringData.forValue("pln"));
95 assertThat(spans.getMapData(0).get("text")).isEqualTo(StringData.forValue("foo"));
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070096
97 spans = lines.getListData(1);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040098 assertThat(spans.length()).isEqualTo(1);
99 assertThat(spans.getMapData(0).get("classes")).isEqualTo(StringData.forValue("pln"));
100 assertThat(spans.getMapData(0).get("text")).isEqualTo(StringData.forValue("contents"));
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700101 }
102
103 @Test
104 public void symlinkHtml() throws Exception {
105 final RevBlob link = repo.blob("foo");
Dave Borowitzcf38c032016-05-02 11:06:23 -0400106 repo.branch("master")
107 .commit()
108 .add("foo", "contents")
109 .edit(
110 new PathEdit("bar") {
111 @Override
112 public void apply(DirCacheEntry ent) {
113 ent.setFileMode(FileMode.SYMLINK);
114 ent.setObjectId(link);
115 }
116 })
117 .create();
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700118
119 Map<String, ?> data = buildData("/repo/+/master/bar");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400120 assertThat(data).containsEntry("type", "SYMLINK");
121 assertThat(getBlobData(data)).containsEntry("target", "foo");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700122 }
123
124 @Test
125 public void gitlinkHtml() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400126 String gitmodules =
127 "[submodule \"gitiles\"]\n"
128 + " path = gitiles\n"
129 + " url = https://gerrit.googlesource.com/gitiles\n";
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700130 final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
Dave Borowitzcf38c032016-05-02 11:06:23 -0400131 repo.branch("master")
132 .commit()
133 .add(".gitmodules", gitmodules)
134 .edit(
135 new PathEdit("gitiles") {
136 @Override
137 public void apply(DirCacheEntry ent) {
138 ent.setFileMode(FileMode.GITLINK);
139 ent.setObjectId(ObjectId.fromString(gitilesSha));
140 }
141 })
142 .create();
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700143
144 Map<String, ?> data = buildData("/repo/+/master/gitiles");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400145 assertThat(data).containsEntry("type", "GITLINK");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700146
147 Map<String, ?> linkData = getBlobData(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400148 assertThat(linkData).containsEntry("sha", gitilesSha);
149 assertThat(linkData).containsEntry("remoteUrl", "https://gerrit.googlesource.com/gitiles");
150 assertThat(linkData).containsEntry("httpUrl", "https://gerrit.googlesource.com/gitiles");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700151 }
152
Dave Borowitz4f568702014-05-01 19:54:57 -0700153 @Test
154 public void blobText() throws Exception {
155 repo.branch("master").commit().add("foo", "contents").create();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700156 String text = buildBlob("/repo/+/master/foo", "100644");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400157 assertThat(text).isEqualTo("contents");
Dave Borowitz4f568702014-05-01 19:54:57 -0700158 }
159
160 @Test
161 public void symlinkText() throws Exception {
162 final RevBlob link = repo.blob("foo");
Dave Borowitzcf38c032016-05-02 11:06:23 -0400163 repo.branch("master")
164 .commit()
165 .edit(
166 new PathEdit("baz") {
167 @Override
168 public void apply(DirCacheEntry ent) {
169 ent.setFileMode(FileMode.SYMLINK);
170 ent.setObjectId(link);
171 }
172 })
173 .create();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700174 String text = buildBlob("/repo/+/master/baz", "120000");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400175 assertThat(text).isEqualTo("foo");
Dave Borowitz228f3572014-05-02 14:26:25 -0700176 }
177
178 @Test
179 public void treeText() throws Exception {
180 RevBlob blob = repo.blob("contents");
181 RevTree tree = repo.tree(repo.file("foo/bar", blob));
182 repo.branch("master").commit().setTopLevelTree(tree).create();
183
184 String expected = "040000 tree " + repo.get(tree, "foo").name() + "\tfoo\n";
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400185 assertThat(buildBlob("/repo/+/master/", "040000")).isEqualTo(expected);
Dave Borowitz228f3572014-05-02 14:26:25 -0700186
187 expected = "100644 blob " + blob.name() + "\tbar\n";
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400188 assertThat(buildBlob("/repo/+/master/foo", "040000")).isEqualTo(expected);
189 assertThat(buildBlob("/repo/+/master/foo/", "040000")).isEqualTo(expected);
Dave Borowitz228f3572014-05-02 14:26:25 -0700190 }
191
192 @Test
193 public void treeTextEscaped() throws Exception {
194 RevBlob blob = repo.blob("contents");
195 repo.branch("master").commit().add("foo\nbar\rbaz", blob).create();
196
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400197 assertThat(buildBlob("/repo/+/master/", "040000"))
198 .isEqualTo("100644 blob " + blob.name() + "\t\"foo\\nbar\\rbaz\"\n");
Dave Borowitz4f568702014-05-01 19:54:57 -0700199 }
200
201 @Test
202 public void nonBlobText() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400203 String gitmodules =
204 "[submodule \"gitiles\"]\n"
205 + " path = gitiles\n"
206 + " url = https://gerrit.googlesource.com/gitiles\n";
Dave Borowitz4f568702014-05-01 19:54:57 -0700207 final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
Dave Borowitzcf38c032016-05-02 11:06:23 -0400208 repo.branch("master")
209 .commit()
Dave Borowitz4f568702014-05-01 19:54:57 -0700210 .add("foo/bar", "contents")
211 .add(".gitmodules", gitmodules)
Dave Borowitzcf38c032016-05-02 11:06:23 -0400212 .edit(
213 new PathEdit("gitiles") {
214 @Override
215 public void apply(DirCacheEntry ent) {
216 ent.setFileMode(FileMode.GITLINK);
217 ent.setObjectId(ObjectId.fromString(gitilesSha));
218 }
219 })
220 .create();
Dave Borowitz4f568702014-05-01 19:54:57 -0700221
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700222 assertNotFound("/repo/+/master/nonexistent", "format=text");
223 assertNotFound("/repo/+/master/gitiles", "format=text");
Dave Borowitz4f568702014-05-01 19:54:57 -0700224 }
225
Dave Borowitz2387b142014-05-02 16:56:27 -0700226 @Test
Han-Wen Nienhuys8aefdb82016-05-02 16:49:35 +0200227 public void treeJsonSizes() throws Exception {
228 RevCommit c = repo.parseBody(repo.branch("master").commit().add("baz", "01234567").create());
229
230 Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
231
232 assertThat(tree.id).isEqualTo(c.getTree().name());
233 assertThat(tree.entries).hasSize(1);
234 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
235 assertThat(tree.entries.get(0).type).isEqualTo("blob");
236 assertThat(tree.entries.get(0).name).isEqualTo("baz");
237 assertThat(tree.entries.get(0).size).isEqualTo(8);
238 }
239
240 @Test
241 public void treeJsonLinkTarget() throws Exception {
242 final ObjectId targetID = repo.blob("target");
243 RevCommit c =
244 repo.parseBody(
245 repo.branch("master")
246 .commit()
247 .edit(
248 new PathEdit("link") {
249 @Override
250 public void apply(DirCacheEntry ent) {
251 ent.setFileMode(FileMode.SYMLINK);
252 ent.setObjectId(targetID);
253 }
254 })
255 .create());
256
257 Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
258
259 assertThat(tree.id).isEqualTo(c.getTree().name());
260 assertThat(tree.entries).hasSize(1);
261
262 TreeJsonData.Entry e = tree.entries.get(0);
263 assertThat(e.mode).isEqualTo(0120000);
264 assertThat(e.type).isEqualTo("blob");
265 assertThat(e.name).isEqualTo("link");
266 assertThat(e.id).isEqualTo(targetID.name());
267 assertThat(e.target).isEqualTo("target");
268 }
269
270 @Test
Dave Borowitz2387b142014-05-02 16:56:27 -0700271 public void treeJson() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400272 RevCommit c =
273 repo.parseBody(
274 repo.branch("master")
275 .commit()
276 .add("foo/bar", "bar contents")
277 .add("baz", "baz contents")
278 .create());
Dave Borowitz2387b142014-05-02 16:56:27 -0700279
Dave Borowitza774f592015-10-26 11:41:27 -0400280 Tree tree = buildJson(Tree.class, "/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400281 assertThat(tree.id).isEqualTo(c.getTree().name());
282 assertThat(tree.entries).hasSize(2);
283 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
284 assertThat(tree.entries.get(0).type).isEqualTo("blob");
285 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "baz").name());
286 assertThat(tree.entries.get(0).name).isEqualTo("baz");
287 assertThat(tree.entries.get(1).mode).isEqualTo(040000);
288 assertThat(tree.entries.get(1).type).isEqualTo("tree");
289 assertThat(tree.entries.get(1).id).isEqualTo(repo.get(c.getTree(), "foo").name());
290 assertThat(tree.entries.get(1).name).isEqualTo("foo");
Dave Borowitz2387b142014-05-02 16:56:27 -0700291
Dave Borowitza774f592015-10-26 11:41:27 -0400292 tree = buildJson(Tree.class, "/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400293 assertThat(tree.id).isEqualTo(repo.get(c.getTree(), "foo").name());
294 assertThat(tree.entries).hasSize(1);
295 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
296 assertThat(tree.entries.get(0).type).isEqualTo("blob");
297 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "foo/bar").name());
298 assertThat(tree.entries.get(0).name).isEqualTo("bar");
Dave Borowitz2387b142014-05-02 16:56:27 -0700299
Dave Borowitza774f592015-10-26 11:41:27 -0400300 tree = buildJson(Tree.class, "/repo/+/master/foo/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400301 assertThat(tree.id).isEqualTo(repo.get(c.getTree(), "foo").name());
302 assertThat(tree.entries).hasSize(1);
303 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
304 assertThat(tree.entries.get(0).type).isEqualTo("blob");
305 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "foo/bar").name());
306 assertThat(tree.entries.get(0).name).isEqualTo("bar");
Dave Borowitz2387b142014-05-02 16:56:27 -0700307 }
308
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700309 private Map<String, ?> getBlobData(Map<String, ?> data) {
310 return ((Map<String, Map<String, ?>>) data).get("data");
311 }
312
313 private List<Map<String, ?>> getTreeEntries(Map<String, ?> data) {
314 return ((Map<String, List<Map<String, ?>>>) data.get("data")).get("entries");
315 }
316
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700317 private String buildBlob(String path, String expectedMode) throws Exception {
318 FakeHttpServletResponse res = buildText(path);
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400319 assertThat(res.getHeader(PathServlet.MODE_HEADER)).isEqualTo(expectedMode);
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700320 String base64 = res.getActualBodyString();
321 return new String(BaseEncoding.base64().decode(base64), UTF_8);
Dave Borowitz228f3572014-05-02 14:26:25 -0700322 }
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700323}