blob: b9e48905c47df368e28449a5dbf67b4c9174f626 [file] [log] [blame]
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -08001// Copyright 2021 Google LLC. 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
17import static com.google.common.truth.Truth.assertThat;
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080018import static javax.servlet.http.HttpServletResponse.SC_MOVED_TEMPORARILY;
19import static javax.servlet.http.HttpServletResponse.SC_OK;
20
Ronald Bhuleskar57640662021-02-05 11:53:17 -080021import com.google.common.base.Strings;
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080022import com.google.common.net.HttpHeaders;
23import java.util.Optional;
Ronald Bhuleskar57640662021-02-05 11:53:17 -080024import javax.annotation.Nullable;
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080025import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
26import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
27import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
28import org.eclipse.jgit.junit.TestRepository;
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -070029import org.eclipse.jgit.lib.Constants;
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080030import org.eclipse.jgit.lib.Repository;
31import org.eclipse.jgit.revwalk.RevCommit;
32import org.junit.Before;
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080033import org.junit.Test;
34import org.junit.runner.RunWith;
35import org.junit.runners.JUnit4;
36
37/** Tests for BranchRedirect. */
38@RunWith(JUnit4.class)
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -080039public class BranchRedirectTest {
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080040 private static final String MASTER = "refs/heads/master";
41 private static final String MAIN = "refs/heads/main";
42 private static final String DEVELOP = "refs/heads/develop";
43 private static final String FOO = "refs/heads/foo";
44 private static final String BAR = "refs/heads/bar";
45 private static final String ORIGIN = "http://localhost";
46 private static final String QUERY_STRING_HTML = "format=html";
47 private static final String QUERY_STRING_JSON = "format=json";
48
49 private TestRepository<DfsRepository> repo;
50 private GitilesServlet servlet;
51
52 @Before
53 public void setUp() throws Exception {
54 repo = new TestRepository<>(new InMemoryRepository(new DfsRepositoryDescription("repo")));
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -080055 BranchRedirect branchRedirect =
56 new BranchRedirect() {
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080057 @Override
58 protected Optional<String> getRedirectBranch(Repository repo, String sourceBranch) {
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -070059 if (MASTER.equals(toFullBranchName(sourceBranch))) {
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080060 return Optional.of(MAIN);
61 }
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -070062 if (FOO.equals(toFullBranchName(sourceBranch))) {
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080063 return Optional.of(BAR);
64 }
65 return Optional.empty();
66 }
67 };
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -080068 servlet = TestGitilesServlet.create(repo, new GitwebRedirectFilter(), branchRedirect);
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080069 }
70
71 @Test
72 public void show_withoutRedirect() throws Exception {
73 repo.branch("develop").commit().add("foo", "contents").create();
74
75 String path = "/repo/+/refs/heads/develop/foo";
76 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
77 FakeHttpServletResponse res = new FakeHttpServletResponse();
78
79 servlet.service(req, res);
80 assertThat(res.getStatus()).isEqualTo(SC_OK);
81 }
82
83 @Test
84 public void show_withRedirect() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -080085 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
86 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080087
88 String path = "/repo/+/refs/heads/master/foo";
89 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
90 FakeHttpServletResponse res = new FakeHttpServletResponse();
91
92 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -080093 assertThat(res.getActualBodyString()).contains("repo/+/refs/heads/main/foo");
94 assertThat(res.getActualBodyString()).doesNotContain("repo/+/refs/heads/master/foo");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -080095 }
96
97 @Test
Ronald Bhuleskar57640662021-02-05 11:53:17 -080098 public void show_withRedirect_onDefaultFormatType() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -080099 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
100 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskar57640662021-02-05 11:53:17 -0800101
102 String path = "/repo/+/refs/heads/master/foo";
103 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, null);
104 FakeHttpServletResponse res = new FakeHttpServletResponse();
105
106 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800107 assertThat(res.getStatus()).isEqualTo(SC_OK);
108 assertThat(res.getActualBodyString()).contains("repo/+/refs/heads/main/foo");
109 assertThat(res.getActualBodyString()).doesNotContain("repo/+/refs/heads/master/foo");
Ronald Bhuleskar57640662021-02-05 11:53:17 -0800110 }
111
112 @Test
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -0700113 public void show_withRedirect_usingShortRefInUrl() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800114 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
115 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -0700116
117 String path = "/repo/+/master/foo";
118 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
119 FakeHttpServletResponse res = new FakeHttpServletResponse();
120
121 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800122 assertThat(res.getStatus()).isEqualTo(SC_OK);
123 assertThat(res.getActualBodyString()).contains("repo/+/refs/heads/main/foo");
124 assertThat(res.getActualBodyString()).doesNotContain("repo/+/master/foo");
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -0700125 }
126
127 @Test
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800128 public void show_onAutomationRequest() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800129 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
130 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800131
132 String path = "/repo/+/refs/heads/master/foo";
133 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_JSON);
134 FakeHttpServletResponse res = new FakeHttpServletResponse();
135
136 servlet.service(req, res);
137 assertThat(res.getStatus()).isEqualTo(SC_OK);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800138 assertThat(res.getActualBodyString()).contains("\"revision\": \"refs/heads/master\"");
139 assertThat(res.getActualBodyString()).contains("\"path\": \"foo\"");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800140 }
141
142 @Test
143 public void showParent_withRedirect() throws Exception {
144 RevCommit parent = repo.branch(MASTER).commit().add("foo", "contents").create();
145 repo.branch(MASTER).commit().add("bar", "contents").parent(parent).create();
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800146 repo.branch(MAIN).commit().parent(parent).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800147
148 String path = "/repo/+/refs/heads/master^";
149 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
150 FakeHttpServletResponse res = new FakeHttpServletResponse();
151
152 servlet.service(req, res);
153 // It is resolved to the object id by ViewFilter.
154 assertThat(res.getStatus()).isEqualTo(SC_MOVED_TEMPORARILY);
155 assertThat(res.getHeader(HttpHeaders.LOCATION))
156 .isEqualTo("/b/repo/+/" + parent.toObjectId().name() + "?format=html");
157 }
158
159 @Test
160 public void diff_withRedirect_onSingleBranch() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800161 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
162 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800163 repo.branch(DEVELOP).commit().add("foo", "contents").create();
164
165 String path = "/repo/+/refs/heads/master..refs/heads/develop";
166 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
167 FakeHttpServletResponse res = new FakeHttpServletResponse();
168
169 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800170 assertThat(res.getStatus()).isEqualTo(SC_OK);
171 assertThat(res.getActualBodyString())
172 .contains("/b/repo/+/refs/heads/main..refs/heads/develop/?format=html");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800173 }
174
175 @Test
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800176 public void diff_withRedirect_onBothBranch() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800177 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
178 repo.branch(MAIN).commit().parent(master).create();
179 RevCommit foo = repo.branch(FOO).commit().add("foo", "contents").create();
180 repo.branch(BAR).commit().parent(foo).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800181
182 String path = "/repo/+/refs/heads/foo..refs/heads/master";
183 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
184 FakeHttpServletResponse res = new FakeHttpServletResponse();
185
186 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800187 assertThat(res.getStatus()).isEqualTo(SC_OK);
188 assertThat(res.getActualBodyString())
189 .contains("/b/repo/+/refs/heads/bar..refs/heads/main/?format=html");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800190 }
191
192 @Test
193 public void diff_withRedirect() throws Exception {
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800194 RevCommit master = repo.branch(MASTER).commit().add("foo", "contents").create();
195 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800196
197 String path = "/repo/+diff/refs/heads/master^!";
198 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
199 FakeHttpServletResponse res = new FakeHttpServletResponse();
200
201 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800202 assertThat(res.getStatus()).isEqualTo(SC_OK);
203 assertThat(res.getActualBodyString()).contains("/b/repo/+/refs/heads/main%5E%21/?format=html");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800204 }
205
206 @Test
207 public void log_withRedirect() throws Exception {
208 repo.branch(MASTER).commit().add("foo", "contents").create();
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800209 RevCommit main = repo.branch(MAIN).commit().create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800210
211 String path = "/repo/+log/refs/heads/master";
212 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
213 FakeHttpServletResponse res = new FakeHttpServletResponse();
214
215 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800216 assertThat(res.getStatus()).isEqualTo(SC_OK);
217 assertThat(res.getActualBodyString()).contains("Log - refs/heads/main");
218 assertThat(res.getActualBodyString()).contains("/b/repo/+/" + main.toObjectId().getName());
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800219 }
220
221 @Test
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800222 public void diff_withGrandParent_redirect() throws Exception {
223 RevCommit parent1 = repo.branch(MASTER).commit().add("foo", "contents").create();
224 RevCommit parent2 =
225 repo.branch(MASTER).commit().add("bar", "contents").parent(parent1).create();
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800226 RevCommit master = repo.branch(MASTER).commit().add("bar", "contents").parent(parent2).create();
227 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800228
229 String path = "/repo/+diff/refs/heads/master^^..refs/heads/master";
230 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
231 FakeHttpServletResponse res = new FakeHttpServletResponse();
232
233 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800234 assertThat(res.getStatus()).isEqualTo(SC_OK);
235 assertThat(res.getActualBodyString())
236 .contains("/b/repo/+/refs/heads/main%5E%5E..refs/heads/main/?format=html");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800237 }
238
239 @Test
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800240 public void diff_withRelativeParent_redirect() throws Exception {
241 RevCommit parent1 = repo.branch(MASTER).commit().add("foo", "contents").create();
242 RevCommit parent2 =
243 repo.branch(MASTER).commit().add("bar", "contents").parent(parent1).create();
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800244 RevCommit master = repo.branch(MASTER).commit().add("bar", "contents").parent(parent2).create();
245 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800246
247 String path = "/repo/+diff/refs/heads/master~1..refs/heads/master";
248 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
249 FakeHttpServletResponse res = new FakeHttpServletResponse();
250
251 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800252 assertThat(res.getStatus()).isEqualTo(SC_OK);
253 assertThat(res.getActualBodyString()).contains("/b/repo/+/refs/heads/main%5E%21/?format=html");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800254 }
255
256 @Test
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800257 public void diff_withRelativeGrandParent_redirect() throws Exception {
258 RevCommit parent1 = repo.branch(MASTER).commit().add("foo", "contents").create();
259 RevCommit parent2 =
260 repo.branch(MASTER).commit().add("bar", "contents").parent(parent1).create();
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800261 RevCommit master = repo.branch(MASTER).commit().add("bar", "contents").parent(parent2).create();
262 repo.branch(MAIN).commit().parent(master).create();
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800263
264 String path = "/repo/+diff/refs/heads/master~2..refs/heads/master";
265 FakeHttpServletRequest req = newHttpRequest(path, ORIGIN, QUERY_STRING_HTML);
266 FakeHttpServletResponse res = new FakeHttpServletResponse();
267
268 servlet.service(req, res);
Ronald Bhuleskar999a71d2021-11-19 15:24:51 -0800269 assertThat(res.getStatus()).isEqualTo(SC_OK);
270 assertThat(res.getActualBodyString())
271 .contains("/b/repo/+/refs/heads/main%7E2..refs/heads/main/?format=html");
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800272 }
273
Ronald Bhuleskarffc9a332021-05-06 10:20:41 -0700274 private static String toFullBranchName(String sourceBranch) {
275 if (sourceBranch.startsWith(Constants.R_REFS)) {
276 return sourceBranch;
277 }
278 return Constants.R_HEADS + sourceBranch;
279 }
280
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800281 private static FakeHttpServletRequest newHttpRequest(
Ronald Bhuleskar57640662021-02-05 11:53:17 -0800282 String path, String origin, @Nullable String queryString) {
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800283 FakeHttpServletRequest req = FakeHttpServletRequest.newRequest();
284 req.setHeader(HttpHeaders.ORIGIN, origin);
285 req.setPathInfo(path);
Ronald Bhuleskar57640662021-02-05 11:53:17 -0800286 if (!Strings.isNullOrEmpty(queryString)) {
287 req.setQueryString(queryString);
288 }
Ronald Bhuleskarfbe16e82020-12-18 20:15:26 -0800289 return req;
290 }
291}