com.google.gitiles.PathServletTest.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gitiles.PathServletTest.java

Source

// Copyright (C) 2014 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 java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertEquals;

import com.google.common.collect.ImmutableList;
import com.google.common.io.BaseEncoding;
import com.google.common.net.HttpHeaders;
import com.google.gitiles.TreeJsonData.Tree;
import com.google.gson.Gson;
import com.google.template.soy.data.SoyListData;
import com.google.template.soy.data.restricted.StringData;

import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.net.URL;
import java.util.List;
import java.util.Map;

/** Tests for {@PathServlet}. */
@SuppressWarnings("unchecked")
@RunWith(JUnit4.class)
public class PathServletTest {
    private static final Renderer RENDERER = new DefaultRenderer("/+static", ImmutableList.<URL>of(), "Test");

    private TestRepository<DfsRepository> repo;
    private PathServlet servlet;

    @Before
    public void setUp() throws Exception {
        DfsRepository r = new InMemoryRepository(new DfsRepositoryDescription("repo"));
        repo = new TestRepository<>(r);
        servlet = new PathServlet(new TestGitilesAccess(repo.getRepository()), RENDERER, TestGitilesUrls.URLS);
    }

    @Test
    public void rootTreeHtml() throws Exception {
        repo.branch("master").commit().add("foo", "contents").create();

        Map<String, ?> data = buildData("/repo/+/master/");
        assertEquals("TREE", data.get("type"));
        List<Map<String, ?>> entries = getTreeEntries(data);
        assertEquals(1, entries.size());
        assertEquals("foo", entries.get(0).get("name"));
    }

    @Test
    public void subTreeHtml() throws Exception {
        repo.branch("master").commit().add("foo/bar", "bar contents").add("baz", "baz contents").create();

        Map<String, ?> data = buildData("/repo/+/master/");
        assertEquals("TREE", data.get("type"));
        List<Map<String, ?>> entries = getTreeEntries(data);
        assertEquals(2, entries.size());
        assertEquals("baz", entries.get(0).get("name"));
        assertEquals("foo/", entries.get(1).get("name"));

        data = buildData("/repo/+/master/foo");
        assertEquals("TREE", data.get("type"));
        entries = getTreeEntries(data);
        assertEquals(1, entries.size());
        assertEquals("bar", entries.get(0).get("name"));

        data = buildData("/repo/+/master/foo/");
        assertEquals("TREE", data.get("type"));
        entries = getTreeEntries(data);
        assertEquals(1, entries.size());
        assertEquals("bar", entries.get(0).get("name"));
    }

    @Test
    public void fileHtml() throws Exception {
        repo.branch("master").commit().add("foo", "foo\ncontents\n").create();

        Map<String, ?> data = buildData("/repo/+/master/foo");
        assertEquals("REGULAR_FILE", data.get("type"));

        SoyListData lines = (SoyListData) getBlobData(data).get("lines");
        assertEquals(2, lines.length());

        SoyListData spans = lines.getListData(0);
        assertEquals(1, spans.length());
        assertEquals(StringData.forValue("pln"), spans.getMapData(0).get("classes"));
        assertEquals(StringData.forValue("foo"), spans.getMapData(0).get("text"));

        spans = lines.getListData(1);
        assertEquals(1, spans.length());
        assertEquals(StringData.forValue("pln"), spans.getMapData(0).get("classes"));
        assertEquals(StringData.forValue("contents"), spans.getMapData(0).get("text"));
    }

    @Test
    public void symlinkHtml() throws Exception {
        final RevBlob link = repo.blob("foo");
        repo.branch("master").commit().add("foo", "contents").edit(new PathEdit("bar") {
            @Override
            public void apply(DirCacheEntry ent) {
                ent.setFileMode(FileMode.SYMLINK);
                ent.setObjectId(link);
            }
        }).create();

        Map<String, ?> data = buildData("/repo/+/master/bar");
        assertEquals("SYMLINK", data.get("type"));
        assertEquals("foo", getBlobData(data).get("target"));
    }

    @Test
    public void gitlinkHtml() throws Exception {
        String gitmodules = "[submodule \"gitiles\"]\n" + "  path = gitiles\n"
                + "  url = https://gerrit.googlesource.com/gitiles\n";
        final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
        repo.branch("master").commit().add(".gitmodules", gitmodules).edit(new PathEdit("gitiles") {
            @Override
            public void apply(DirCacheEntry ent) {
                ent.setFileMode(FileMode.GITLINK);
                ent.setObjectId(ObjectId.fromString(gitilesSha));
            }
        }).create();

        Map<String, ?> data = buildData("/repo/+/master/gitiles");
        assertEquals("GITLINK", data.get("type"));

        Map<String, ?> linkData = getBlobData(data);
        assertEquals(gitilesSha, linkData.get("sha"));
        assertEquals("https://gerrit.googlesource.com/gitiles", linkData.get("remoteUrl"));
        assertEquals("https://gerrit.googlesource.com/gitiles", linkData.get("httpUrl"));
    }

    @Test
    public void blobText() throws Exception {
        repo.branch("master").commit().add("foo", "contents").create();
        String text = buildText("/repo/+/master/foo?format=TEXT", "100644");
        assertEquals("contents", decodeBase64(text));
    }

    @Test
    public void symlinkText() throws Exception {
        final RevBlob link = repo.blob("foo");
        repo.branch("master").commit().edit(new PathEdit("baz") {
            @Override
            public void apply(DirCacheEntry ent) {
                ent.setFileMode(FileMode.SYMLINK);
                ent.setObjectId(link);
            }
        }).create();
        String text = buildText("/repo/+/master/baz?format=TEXT", "120000");
        assertEquals("foo", decodeBase64(text));
    }

    @Test
    public void treeText() throws Exception {
        RevBlob blob = repo.blob("contents");
        RevTree tree = repo.tree(repo.file("foo/bar", blob));
        repo.branch("master").commit().setTopLevelTree(tree).create();

        String expected = "040000 tree " + repo.get(tree, "foo").name() + "\tfoo\n";
        assertEquals(expected, decodeBase64(buildText("/repo/+/master/?format=TEXT", "040000")));

        expected = "100644 blob " + blob.name() + "\tbar\n";
        assertEquals(expected, decodeBase64(buildText("/repo/+/master/foo?format=TEXT", "040000")));
        assertEquals(expected, decodeBase64(buildText("/repo/+/master/foo/?format=TEXT", "040000")));
    }

    @Test
    public void treeTextEscaped() throws Exception {
        RevBlob blob = repo.blob("contents");
        repo.branch("master").commit().add("foo\nbar\rbaz", blob).create();

        assertEquals("100644 blob " + blob.name() + "\t\"foo\\nbar\\rbaz\"\n",
                decodeBase64(buildText("/repo/+/master/?format=TEXT", "040000")));
    }

    @Test
    public void nonBlobText() throws Exception {
        String gitmodules = "[submodule \"gitiles\"]\n" + "  path = gitiles\n"
                + "  url = https://gerrit.googlesource.com/gitiles\n";
        final String gitilesSha = "2b2f34bba3c2be7e2506ce6b1f040949da350cf9";
        repo.branch("master").commit().add("foo/bar", "contents").add(".gitmodules", gitmodules)
                .edit(new PathEdit("gitiles") {
                    @Override
                    public void apply(DirCacheEntry ent) {
                        ent.setFileMode(FileMode.GITLINK);
                        ent.setObjectId(ObjectId.fromString(gitilesSha));
                    }
                }).create();

        assertNotFound("/repo/+/master/nonexistent?format=TEXT");
        assertNotFound("/repo/+/master/gitiles?format=TEXT");
    }

    @Test
    public void treeJson() throws Exception {
        RevCommit c = repo.parseBody(
                repo.branch("master").commit().add("foo/bar", "bar contents").add("baz", "baz contents").create());

        Tree tree = buildJson("/repo/+/master/?format=JSON", Tree.class);
        assertEquals(c.getTree().name(), tree.id);
        assertEquals(2, tree.entries.size());
        assertEquals(0100644, tree.entries.get(0).mode);
        assertEquals("blob", tree.entries.get(0).type);
        assertEquals(repo.get(c.getTree(), "baz").name(), tree.entries.get(0).id);
        assertEquals("baz", tree.entries.get(0).name);
        assertEquals(040000, tree.entries.get(1).mode);
        assertEquals("tree", tree.entries.get(1).type);
        assertEquals(repo.get(c.getTree(), "foo").name(), tree.entries.get(1).id);
        assertEquals("foo", tree.entries.get(1).name);

        tree = buildJson("/repo/+/master/foo?format=JSON", Tree.class);
        assertEquals(repo.get(c.getTree(), "foo").name(), tree.id);
        assertEquals(1, tree.entries.size());
        assertEquals(0100644, tree.entries.get(0).mode);
        assertEquals("blob", tree.entries.get(0).type);
        assertEquals(repo.get(c.getTree(), "foo/bar").name(), tree.entries.get(0).id);
        assertEquals("bar", tree.entries.get(0).name);

        tree = buildJson("/repo/+/master/foo/?format=JSON", Tree.class);
        assertEquals(repo.get(c.getTree(), "foo").name(), tree.id);
        assertEquals(1, tree.entries.size());
        assertEquals(0100644, tree.entries.get(0).mode);
        assertEquals("blob", tree.entries.get(0).type);
        assertEquals(repo.get(c.getTree(), "foo/bar").name(), tree.entries.get(0).id);
        assertEquals("bar", tree.entries.get(0).name);
    }

    private Map<String, ?> getBlobData(Map<String, ?> data) {
        return ((Map<String, Map<String, ?>>) data).get("data");
    }

    private List<Map<String, ?>> getTreeEntries(Map<String, ?> data) {
        return ((Map<String, List<Map<String, ?>>>) data.get("data")).get("entries");
    }

    private TestViewFilter.Result service(String pathAndQuery) throws Exception {
        TestViewFilter.Result res = TestViewFilter.service(repo, pathAndQuery);
        assertEquals(200, res.getResponse().getStatus());
        assertEquals(GitilesView.Type.PATH, res.getView().getType());
        servlet.service(res.getRequest(), res.getResponse());
        return res;
    }

    private void assertNotFound(String pathAndQuery) throws Exception {
        assertEquals(404, service(pathAndQuery).getResponse().getStatus());
    }

    private String buildText(String pathAndQuery, String expectedMode) throws Exception {
        TestViewFilter.Result res = service(pathAndQuery);
        assertEquals("text/plain", res.getResponse().getHeader(HttpHeaders.CONTENT_TYPE));
        assertEquals(expectedMode, res.getResponse().getHeader(PathServlet.MODE_HEADER));
        return res.getResponse().getActualBodyString();
    }

    private <T> T buildJson(String pathAndQuery, Class<T> clazz) throws Exception {
        TestViewFilter.Result res = service(pathAndQuery);
        assertEquals("application/json", res.getResponse().getHeader(HttpHeaders.CONTENT_TYPE));
        String body = res.getResponse().getActualBodyString();
        String magic = ")]}'\n";
        assertEquals(magic, body.substring(0, magic.length()));
        return new Gson().fromJson(body.substring(magic.length()), clazz);
    }

    private Map<String, ?> buildData(String pathAndQuery) throws Exception {
        // Render the page through Soy to ensure templates are valid, then return
        // the Soy data for introspection.
        return BaseServlet.getData(service(pathAndQuery).getRequest());
    }

    private static String decodeBase64(String in) {
        return new String(BaseEncoding.base64().decode(in), UTF_8);
    }
}