| // Copyright 2026 Google Inc. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| package com.google.gitiles; | |
| import static com.google.common.truth.Truth.assertThat; | |
| import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; | |
| import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; | |
| import static javax.servlet.http.HttpServletResponse.SC_OK; | |
| import java.util.List; | |
| import org.junit.Test; | |
| public class GrepServletTest extends ServletTest { | |
| @Test | |
| public void grepJsonSearchesRepositoryRoot() throws Exception { | |
| repo.branch("master") | |
| .commit() | |
| .add("dir/a.txt", "alpha\nneedle here\n") | |
| .add("dir/b.txt", "needle too\n") | |
| .add("dir/c.txt", "no match\n") | |
| .create(); | |
| GrepResult result = buildJson(GrepResult.class, "/repo/+grep/master", "s=needle"); | |
| assertThat(result.matches).hasSize(2); | |
| assertThat(result.matches.get(0).path).isEqualTo("dir/a.txt"); | |
| assertThat(result.matches.get(0).lineNumber).isEqualTo(2); | |
| assertThat(result.matches.get(0).line).isEqualTo("needle here"); | |
| assertThat(result.matches.get(1).path).isEqualTo("dir/b.txt"); | |
| } | |
| @Test | |
| public void grepJsonCanSearchDirectoryPath() throws Exception { | |
| repo.branch("master") | |
| .commit() | |
| .add("src/a.txt", "needle\n") | |
| .add("test/a.txt", "needle\n") | |
| .create(); | |
| GrepResult result = buildJson(GrepResult.class, "/repo/+grep/master/src", "s=needle"); | |
| assertThat(result.matches).hasSize(1); | |
| assertThat(result.matches.get(0).path).isEqualTo("src/a.txt"); | |
| } | |
| @Test | |
| public void grepHtmlShowsSearchForm() throws Exception { | |
| repo.branch("master").commit().add("foo", "contents").create(); | |
| FakeHttpServletResponse res = buildResponse("/repo/+grep/master", "format=html", SC_OK); | |
| assertThat(res.getActualBodyString()).contains("name=\"s\""); | |
| assertThat(res.getActualBodyString()).contains("Search"); | |
| } | |
| @Test | |
| public void grepHtmlSearchesFileContents() throws Exception { | |
| repo.branch("master") | |
| .commit() | |
| .add("dir/a.txt", "alpha\nneedle here\n") | |
| .add("dir/b.txt", "no match\n") | |
| .create(); | |
| FakeHttpServletResponse res = | |
| buildResponse("/repo/+grep/master", "format=html&s=needle", SC_OK); | |
| assertThat(res.getActualBodyString()).contains("dir/a.txt"); | |
| assertThat(res.getActualBodyString()).contains("2: needle here"); | |
| assertThat(res.getActualBodyString()).contains("#2"); | |
| assertThat(res.getActualBodyString()).doesNotContain("dir/b.txt"); | |
| } | |
| @Test | |
| public void grepJsonDoesNotSearchNonExistingPathPrefix() throws Exception { | |
| repo.branch("master").commit().add("src/a.txt", "needle\n").create(); | |
| buildResponse("/repo/+grep/master/sr", "s=needle&format=JSON", SC_NOT_FOUND); | |
| } | |
| @Test | |
| public void grepJsonLimitsMatches() throws Exception { | |
| var commit = repo.branch("master").commit(); | |
| for (int i = 0; i < GrepServlet.MAX_MATCHES + 1; i++) { | |
| commit.add(String.format("file%04d.txt", i), "needle\n"); | |
| } | |
| commit.create(); | |
| GrepResult result = buildJson(GrepResult.class, "/repo/+grep/master", "s=needle"); | |
| assertThat(result.matches).hasSize(GrepServlet.MAX_MATCHES); | |
| } | |
| @Test | |
| public void grepJsonRequiresSubstring() throws Exception { | |
| repo.branch("master").commit().add("foo", "contents").create(); | |
| buildResponse("/repo/+grep/master", "format=JSON", SC_BAD_REQUEST); | |
| } | |
| private static class GrepResult { | |
| List<Match> matches; | |
| } | |
| private static class Match { | |
| String path; | |
| int lineNumber; | |
| String line; | |
| } | |
| } |