blob: 68b1e3e3cc38b0516c1fcf22ceae9a410cab8e68 [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;
AJ Ross001ea9b2016-08-23 13:40:04 -070019import static javax.servlet.http.HttpServletResponse.SC_OK;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070020
Dave Borowitz4f568702014-05-01 19:54:57 -070021import com.google.common.io.BaseEncoding;
AJ Ross001ea9b2016-08-23 13:40:04 -070022import com.google.common.net.HttpHeaders;
Andrew Bonventre199efc42017-05-10 13:57:39 -070023import com.google.gitiles.FileJsonData.File;
Dave Borowitz3c441502014-09-05 16:06:37 -070024import com.google.gitiles.TreeJsonData.Tree;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070025import com.google.template.soy.data.SoyListData;
26import com.google.template.soy.data.restricted.StringData;
Dave Borowitz3b744b12016-08-19 16:11:10 -040027import java.util.List;
28import java.util.Map;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070029import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
30import org.eclipse.jgit.dircache.DirCacheEntry;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070031import org.eclipse.jgit.lib.FileMode;
32import org.eclipse.jgit.lib.ObjectId;
33import org.eclipse.jgit.revwalk.RevBlob;
Dave Borowitz2387b142014-05-02 16:56:27 -070034import org.eclipse.jgit.revwalk.RevCommit;
Dave Borowitz228f3572014-05-02 14:26:25 -070035import org.eclipse.jgit.revwalk.RevTree;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070036import org.junit.Test;
Dave Borowitz3dc854f2014-11-04 16:19:37 -080037import org.junit.runner.RunWith;
38import org.junit.runners.JUnit4;
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070039
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070040/** Tests for {@PathServlet}. */
41@SuppressWarnings("unchecked")
Dave Borowitz3dc854f2014-11-04 16:19:37 -080042@RunWith(JUnit4.class)
Nodir Turakulov4bc26002015-08-18 18:24:37 -070043public class PathServletTest extends ServletTest {
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070044 @Test
45 public void rootTreeHtml() throws Exception {
46 repo.branch("master").commit().add("foo", "contents").create();
47
48 Map<String, ?> data = buildData("/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040049 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070050 List<Map<String, ?>> entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040051 assertThat(entries).hasSize(1);
52 assertThat(entries.get(0).get("name")).isEqualTo("foo");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070053 }
54
55 @Test
56 public void subTreeHtml() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -040057 repo.branch("master")
58 .commit()
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070059 .add("foo/bar", "bar contents")
60 .add("baz", "baz contents")
61 .create();
62
63 Map<String, ?> data = buildData("/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040064 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070065 List<Map<String, ?>> entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040066 assertThat(entries).hasSize(2);
Pontus Jaensson4c5c8d22021-11-10 12:46:16 +010067 assertThat(entries.get(0).get("name")).isEqualTo("foo/");
68 assertThat(entries.get(1).get("name")).isEqualTo("baz");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070069
70 data = buildData("/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040071 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070072 entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040073 assertThat(entries).hasSize(1);
74 assertThat(entries.get(0).get("name")).isEqualTo("bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070075
76 data = buildData("/repo/+/master/foo/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040077 assertThat(data).containsEntry("type", "TREE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070078 entries = getTreeEntries(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040079 assertThat(entries).hasSize(1);
80 assertThat(entries.get(0).get("name")).isEqualTo("bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070081 }
82
83 @Test
84 public void fileHtml() throws Exception {
85 repo.branch("master").commit().add("foo", "foo\ncontents\n").create();
86
87 Map<String, ?> data = buildData("/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040088 assertThat(data).containsEntry("type", "REGULAR_FILE");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070089
90 SoyListData lines = (SoyListData) getBlobData(data).get("lines");
Dave Borowitzfde41fd2015-09-16 15:14:38 -040091 assertThat(lines.length()).isEqualTo(2);
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070092
93 SoyListData spans = lines.getListData(0);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040094 assertThat(spans.length()).isEqualTo(1);
95 assertThat(spans.getMapData(0).get("classes")).isEqualTo(StringData.forValue("pln"));
96 assertThat(spans.getMapData(0).get("text")).isEqualTo(StringData.forValue("foo"));
Dave Borowitzb7fd3f32014-05-01 12:31:25 -070097
98 spans = lines.getListData(1);
Dave Borowitzfde41fd2015-09-16 15:14:38 -040099 assertThat(spans.length()).isEqualTo(1);
100 assertThat(spans.getMapData(0).get("classes")).isEqualTo(StringData.forValue("pln"));
101 assertThat(spans.getMapData(0).get("text")).isEqualTo(StringData.forValue("contents"));
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700102 }
103
104 @Test
Ronald Bhuleskarc9208e52019-07-10 17:44:08 -0700105 public void fileWithMaxLines() throws Exception {
106 int MAX_LINE_COUNT = 50000;
107 StringBuilder contentBuilder = new StringBuilder();
108 for (int i = 1; i < MAX_LINE_COUNT; i++) {
109 contentBuilder.append("\n");
110 }
111 repo.branch("master").commit().add("bar", contentBuilder.toString()).create();
112
113 Map<String, ?> data = buildData("/repo/+/master/bar");
114 SoyListData lines = (SoyListData) getBlobData(data).get("lines");
115 assertThat(lines.length()).isEqualTo(MAX_LINE_COUNT - 1);
116 }
117
118 @Test
119 public void fileLargerThanSupportedLines() throws Exception {
120 int MAX_LINE_COUNT = 50000;
121 StringBuilder contentBuilder = new StringBuilder();
122 for (int i = 1; i <= MAX_LINE_COUNT; i++) {
123 contentBuilder.append("\n");
124 }
125 repo.branch("master").commit().add("largebar", contentBuilder.toString()).create();
126
127 Map<String, ?> data = buildData("/repo/+/master/largebar");
128 SoyListData lines = (SoyListData) getBlobData(data).get("lines");
129 assertThat(lines).isNull();
130 }
131
132 @Test
Luca Milanesiobeb12ac2019-11-18 12:14:38 -0800133 public void largeFileHtml() throws Exception {
134 int largeContentSize = BlobSoyData.MAX_FILE_SIZE + 1;
135 repo.branch("master").commit().add("foo", generateContent(largeContentSize)).create();
136
137 Map<String, ?> data = (Map<String, ?>) buildData("/repo/+/master/foo").get("data");
138 assertThat(data).containsEntry("lines", null);
139 assertThat(data).containsEntry("size", "" + largeContentSize);
140 }
141
142 private static String generateContent(int contentSize) {
143 char[] str = new char[contentSize];
144 for (int i = 0; i < contentSize; i++) {
145 str[i] = (char) ('0' + (i % 78));
146 }
147 return new String(str);
148 }
149
150 @Test
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700151 public void symlinkHtml() throws Exception {
Sven Selberg5eb94392020-08-06 13:51:50 +0200152 testSymlink("foo", "bar", "foo");
153 }
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700154
Sven Selberg5eb94392020-08-06 13:51:50 +0200155 @Test
156 public void relativeSymlinkHtml() throws Exception {
157 testSymlink("foo/bar", "foo/baz", "./bar");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700158 }
159
160 @Test
161 public void gitlinkHtml() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400162 String gitmodules =
163 "[submodule \"gitiles\"]\n"
164 + " path = gitiles\n"
165 + " url = https://gerrit.googlesource.com/gitiles\n";
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700166 final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
Dave Borowitzcf38c032016-05-02 11:06:23 -0400167 repo.branch("master")
168 .commit()
169 .add(".gitmodules", gitmodules)
170 .edit(
171 new PathEdit("gitiles") {
172 @Override
173 public void apply(DirCacheEntry ent) {
174 ent.setFileMode(FileMode.GITLINK);
175 ent.setObjectId(ObjectId.fromString(gitilesSha));
176 }
177 })
178 .create();
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700179
180 Map<String, ?> data = buildData("/repo/+/master/gitiles");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400181 assertThat(data).containsEntry("type", "GITLINK");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700182
183 Map<String, ?> linkData = getBlobData(data);
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400184 assertThat(linkData).containsEntry("sha", gitilesSha);
185 assertThat(linkData).containsEntry("remoteUrl", "https://gerrit.googlesource.com/gitiles");
186 assertThat(linkData).containsEntry("httpUrl", "https://gerrit.googlesource.com/gitiles");
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700187 }
188
Dave Borowitz4f568702014-05-01 19:54:57 -0700189 @Test
190 public void blobText() throws Exception {
191 repo.branch("master").commit().add("foo", "contents").create();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700192 String text = buildBlob("/repo/+/master/foo", "100644");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400193 assertThat(text).isEqualTo("contents");
Dave Borowitz4f568702014-05-01 19:54:57 -0700194 }
195
196 @Test
Andrew Bonventre199efc42017-05-10 13:57:39 -0700197 public void fileJson() throws Exception {
198 RevBlob blob = repo.blob("contents");
199 repo.branch("master").commit().add("path/to/file", blob).create();
200
201 File file = buildJson(File.class, "/repo/+/master/path/to/file");
202
203 assertThat(file.id).isEqualTo(blob.name());
204 assertThat(file.repo).isEqualTo("repo");
205 assertThat(file.revision).isEqualTo("master");
206 assertThat(file.path).isEqualTo("path/to/file");
207 }
208
209 @Test
Dave Borowitz4f568702014-05-01 19:54:57 -0700210 public void symlinkText() throws Exception {
211 final RevBlob link = repo.blob("foo");
Dave Borowitzcf38c032016-05-02 11:06:23 -0400212 repo.branch("master")
213 .commit()
214 .edit(
215 new PathEdit("baz") {
216 @Override
217 public void apply(DirCacheEntry ent) {
218 ent.setFileMode(FileMode.SYMLINK);
219 ent.setObjectId(link);
220 }
221 })
222 .create();
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700223 String text = buildBlob("/repo/+/master/baz", "120000");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400224 assertThat(text).isEqualTo("foo");
Dave Borowitz228f3572014-05-02 14:26:25 -0700225 }
226
227 @Test
228 public void treeText() throws Exception {
229 RevBlob blob = repo.blob("contents");
230 RevTree tree = repo.tree(repo.file("foo/bar", blob));
231 repo.branch("master").commit().setTopLevelTree(tree).create();
232
233 String expected = "040000 tree " + repo.get(tree, "foo").name() + "\tfoo\n";
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400234 assertThat(buildBlob("/repo/+/master/", "040000")).isEqualTo(expected);
Dave Borowitz228f3572014-05-02 14:26:25 -0700235
236 expected = "100644 blob " + blob.name() + "\tbar\n";
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400237 assertThat(buildBlob("/repo/+/master/foo", "040000")).isEqualTo(expected);
238 assertThat(buildBlob("/repo/+/master/foo/", "040000")).isEqualTo(expected);
Dave Borowitz228f3572014-05-02 14:26:25 -0700239 }
240
241 @Test
242 public void treeTextEscaped() throws Exception {
243 RevBlob blob = repo.blob("contents");
244 repo.branch("master").commit().add("foo\nbar\rbaz", blob).create();
245
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400246 assertThat(buildBlob("/repo/+/master/", "040000"))
247 .isEqualTo("100644 blob " + blob.name() + "\t\"foo\\nbar\\rbaz\"\n");
Dave Borowitz4f568702014-05-01 19:54:57 -0700248 }
249
250 @Test
251 public void nonBlobText() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400252 String gitmodules =
253 "[submodule \"gitiles\"]\n"
254 + " path = gitiles\n"
255 + " url = https://gerrit.googlesource.com/gitiles\n";
Dave Borowitz4f568702014-05-01 19:54:57 -0700256 final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
Dave Borowitzcf38c032016-05-02 11:06:23 -0400257 repo.branch("master")
258 .commit()
Dave Borowitz4f568702014-05-01 19:54:57 -0700259 .add("foo/bar", "contents")
260 .add(".gitmodules", gitmodules)
Dave Borowitzcf38c032016-05-02 11:06:23 -0400261 .edit(
262 new PathEdit("gitiles") {
263 @Override
264 public void apply(DirCacheEntry ent) {
265 ent.setFileMode(FileMode.GITLINK);
266 ent.setObjectId(ObjectId.fromString(gitilesSha));
267 }
268 })
269 .create();
Dave Borowitz4f568702014-05-01 19:54:57 -0700270
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700271 assertNotFound("/repo/+/master/nonexistent", "format=text");
272 assertNotFound("/repo/+/master/gitiles", "format=text");
Dave Borowitz4f568702014-05-01 19:54:57 -0700273 }
274
Dave Borowitz2387b142014-05-02 16:56:27 -0700275 @Test
Han-Wen Nienhuys8aefdb82016-05-02 16:49:35 +0200276 public void treeJsonSizes() throws Exception {
277 RevCommit c = repo.parseBody(repo.branch("master").commit().add("baz", "01234567").create());
278
279 Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
280
281 assertThat(tree.id).isEqualTo(c.getTree().name());
282 assertThat(tree.entries).hasSize(1);
283 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
284 assertThat(tree.entries.get(0).type).isEqualTo("blob");
285 assertThat(tree.entries.get(0).name).isEqualTo("baz");
286 assertThat(tree.entries.get(0).size).isEqualTo(8);
287 }
288
289 @Test
290 public void treeJsonLinkTarget() throws Exception {
291 final ObjectId targetID = repo.blob("target");
292 RevCommit c =
293 repo.parseBody(
294 repo.branch("master")
295 .commit()
296 .edit(
297 new PathEdit("link") {
298 @Override
299 public void apply(DirCacheEntry ent) {
300 ent.setFileMode(FileMode.SYMLINK);
301 ent.setObjectId(targetID);
302 }
303 })
304 .create());
305
306 Tree tree = buildJson(Tree.class, "/repo/+/master/", "long=1");
307
308 assertThat(tree.id).isEqualTo(c.getTree().name());
309 assertThat(tree.entries).hasSize(1);
310
311 TreeJsonData.Entry e = tree.entries.get(0);
312 assertThat(e.mode).isEqualTo(0120000);
313 assertThat(e.type).isEqualTo("blob");
314 assertThat(e.name).isEqualTo("link");
315 assertThat(e.id).isEqualTo(targetID.name());
316 assertThat(e.target).isEqualTo("target");
317 }
318
319 @Test
Han-Wen Nienhuys0dc93872016-05-03 15:21:42 +0200320 public void treeJsonRecursive() throws Exception {
321 RevCommit c =
322 repo.parseBody(
323 repo.branch("master")
324 .commit()
325 .add("foo/baz/bar/a", "bar contents")
326 .add("foo/baz/bar/b", "bar contents")
327 .add("baz", "baz contents")
328 .create());
329 Tree tree = buildJson(Tree.class, "/repo/+/master/", "recursive=1");
330
331 assertThat(tree.id).isEqualTo(c.getTree().name());
332 assertThat(tree.entries).hasSize(3);
333
334 assertThat(tree.entries.get(0).name).isEqualTo("baz");
335 assertThat(tree.entries.get(1).name).isEqualTo("foo/baz/bar/a");
336 assertThat(tree.entries.get(2).name).isEqualTo("foo/baz/bar/b");
337
338 tree = buildJson(Tree.class, "/repo/+/master/foo/baz", "recursive=1");
339
340 assertThat(tree.entries).hasSize(2);
341
342 assertThat(tree.entries.get(0).name).isEqualTo("bar/a");
343 assertThat(tree.entries.get(1).name).isEqualTo("bar/b");
344 }
345
346 @Test
Dave Borowitz2387b142014-05-02 16:56:27 -0700347 public void treeJson() throws Exception {
Dave Borowitzcf38c032016-05-02 11:06:23 -0400348 RevCommit c =
349 repo.parseBody(
350 repo.branch("master")
351 .commit()
352 .add("foo/bar", "bar contents")
353 .add("baz", "baz contents")
354 .create());
Dave Borowitz2387b142014-05-02 16:56:27 -0700355
Dave Borowitza774f592015-10-26 11:41:27 -0400356 Tree tree = buildJson(Tree.class, "/repo/+/master/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400357 assertThat(tree.id).isEqualTo(c.getTree().name());
358 assertThat(tree.entries).hasSize(2);
359 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
360 assertThat(tree.entries.get(0).type).isEqualTo("blob");
361 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "baz").name());
362 assertThat(tree.entries.get(0).name).isEqualTo("baz");
363 assertThat(tree.entries.get(1).mode).isEqualTo(040000);
364 assertThat(tree.entries.get(1).type).isEqualTo("tree");
365 assertThat(tree.entries.get(1).id).isEqualTo(repo.get(c.getTree(), "foo").name());
366 assertThat(tree.entries.get(1).name).isEqualTo("foo");
Dave Borowitz2387b142014-05-02 16:56:27 -0700367
Dave Borowitza774f592015-10-26 11:41:27 -0400368 tree = buildJson(Tree.class, "/repo/+/master/foo");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400369 assertThat(tree.id).isEqualTo(repo.get(c.getTree(), "foo").name());
370 assertThat(tree.entries).hasSize(1);
371 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
372 assertThat(tree.entries.get(0).type).isEqualTo("blob");
373 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "foo/bar").name());
374 assertThat(tree.entries.get(0).name).isEqualTo("bar");
Dave Borowitz2387b142014-05-02 16:56:27 -0700375
Dave Borowitza774f592015-10-26 11:41:27 -0400376 tree = buildJson(Tree.class, "/repo/+/master/foo/");
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400377 assertThat(tree.id).isEqualTo(repo.get(c.getTree(), "foo").name());
378 assertThat(tree.entries).hasSize(1);
379 assertThat(tree.entries.get(0).mode).isEqualTo(0100644);
380 assertThat(tree.entries.get(0).type).isEqualTo("blob");
381 assertThat(tree.entries.get(0).id).isEqualTo(repo.get(c.getTree(), "foo/bar").name());
382 assertThat(tree.entries.get(0).name).isEqualTo("bar");
Dave Borowitz2387b142014-05-02 16:56:27 -0700383 }
384
AJ Ross001ea9b2016-08-23 13:40:04 -0700385 @Test
386 public void allowOrigin() throws Exception {
387 repo.branch("master").commit().add("foo", "contents").create();
388 FakeHttpServletResponse res = buildText("/repo/+/master/foo");
389 assertThat(res.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN))
390 .isEqualTo("http://localhost");
391 }
392
393 @Test
394 public void rejectOrigin() throws Exception {
395 repo.branch("master").commit().add("foo", "contents").create();
David Pursehouseccaa85d2017-05-30 10:47:27 +0900396 FakeHttpServletResponse res =
397 buildResponse("/repo/+/master/foo", "format=text", SC_OK, "http://notlocalhost");
AJ Ross001ea9b2016-08-23 13:40:04 -0700398 assertThat(res.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo("text/plain");
David Pursehouseccaa85d2017-05-30 10:47:27 +0900399 assertThat(res.getHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)).isEqualTo(null);
AJ Ross001ea9b2016-08-23 13:40:04 -0700400 }
401
Sven Selberg5eb94392020-08-06 13:51:50 +0200402 private void testSymlink(String linkTarget, String linkName, String linkContent)
403 throws Exception {
404 final RevBlob linkBlob = repo.blob(linkContent);
405 repo.branch("master")
406 .commit()
407 .add(linkTarget, "contents")
408 .edit(
409 new PathEdit(linkName) {
410 @Override
411 public void apply(DirCacheEntry ent) {
412 ent.setFileMode(FileMode.SYMLINK);
413 ent.setObjectId(linkBlob);
414 }
415 })
416 .create();
417
418 Map<String, ?> data = buildData("/repo/+/master/" + linkName);
419 assertThat(data).containsEntry("type", "SYMLINK");
420 assertThat(getBlobData(data)).containsEntry("target", linkContent);
421 assertThat(getBlobData(data)).containsEntry("targetUrl", "/b/repo/+/master/" + linkTarget);
422 }
423
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700424 private Map<String, ?> getBlobData(Map<String, ?> data) {
425 return ((Map<String, Map<String, ?>>) data).get("data");
426 }
427
428 private List<Map<String, ?>> getTreeEntries(Map<String, ?> data) {
429 return ((Map<String, List<Map<String, ?>>>) data.get("data")).get("entries");
430 }
431
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700432 private String buildBlob(String path, String expectedMode) throws Exception {
433 FakeHttpServletResponse res = buildText(path);
Dave Borowitzfde41fd2015-09-16 15:14:38 -0400434 assertThat(res.getHeader(PathServlet.MODE_HEADER)).isEqualTo(expectedMode);
Nodir Turakulov4bc26002015-08-18 18:24:37 -0700435 String base64 = res.getActualBodyString();
436 return new String(BaseEncoding.base64().decode(base64), UTF_8);
Dave Borowitz228f3572014-05-02 14:26:25 -0700437 }
Dave Borowitzb7fd3f32014-05-01 12:31:25 -0700438}