// Copyright (C) 2015 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.doc;

import static com.google.common.truth.Truth.assertThat;

import com.google.gitiles.ServletTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {DocServlet}. */
@RunWith(JUnit4.class)
public class DocServletTest extends ServletTest {
  @Test
  public void simpleReadmeDoc() throws Exception {
    String title = "DocServletTest simpleDoc";
    String url = "http://daringfireball.net/projects/markdown/syntax";
    String markdown =
        "# " + title + "\n" + "\n" + "Tests the rendering of " + "[Markdown](" + url + ").";
    repo.branch("master").commit().add("README.md", markdown).create();

    String html = buildHtml("/repo/+doc/master/README.md");
    assertThat(html).contains("<title>" + title + "</title>");
    assertThat(html).contains(title + "</h1>");
    assertThat(html).contains("<a href=\"" + url + "\">Markdown</a>");
  }

  @Test
  public void includesNavbar() throws Exception {
    String navbar =
        "# Site Title\n"
            + "\n"
            + "[home]: index.md\n"
            + "[logo]: logo.png\n"
            + "\n"
            + "* [Home][home]\n"
            + "* [README](README.md)\n"
            + "[extensions]: blocknote\n";
    repo.branch("master")
        .commit()
        .add("README.md", "# page\n\nof information.")
        .add("navbar.md", navbar)
        .create();

    String html = buildHtml("/repo/+doc/master/README.md");
    assertThat(html).contains("<title>Site Title - page</title>");
    assertThat(html).contains("Header-anchorLogo");
    assertThat(html).contains("<span class=\"Header-anchorTitle\">Site Title</span>");
    assertThat(html).contains("<li><a href=\"/b/repo/+/master/index.md\">Home</a></li>");
    assertThat(html).contains("<li><a href=\"/b/repo/+/master/README.md\">README</a></li>");
    assertThat(html).doesNotContain("extensions");
    assertThat(html)
        .contains("<h1><a class=\"h\" name=\"page\" href=\"#page\"><span></span></a>page</h1>");
  }

  @Test
  public void simpleSubNavbar() throws Exception {
    String rootNavbar = "# Site Title\n\n* [Home](index.md)\n* [README](README.md)\n";
    String subNavbar = "# Subdir Title\n\n* [Sub Home](index.md)\n* [Sub README](README.md)\n";
    repo.branch("master")
        .commit()
        .add("README.md", "# page\n\nof information.")
        .add("navbar.md", rootNavbar)
        .add("subdir/README.md", "# subdir page\n\nof information.")
        .add("subdir/navbar.md", subNavbar)
        .create();

    String rootReadmeHtml = buildHtml("/repo/+doc/master/README.md");
    assertThat(rootReadmeHtml).contains("<title>Site Title - page</title>");

    assertThat(rootReadmeHtml).contains("<span class=\"Header-anchorTitle\">Site Title</span>");
    assertThat(rootReadmeHtml).contains("<li><a href=\"/b/repo/+/master/index.md\">Home</a></li>");
    assertThat(rootReadmeHtml)
        .contains("<li><a href=\"/b/repo/+/master/README.md\">README</a></li>");
    assertThat(rootReadmeHtml)
        .contains("<h1><a class=\"h\" name=\"page\" href=\"#page\"><span></span></a>page</h1>");

    String subdirReadmeHtml = buildHtml("/repo/+doc/master/subdir/README.md");
    assertThat(subdirReadmeHtml).contains("<title>Subdir Title - subdir page</title>");

    assertThat(subdirReadmeHtml).contains("<span class=\"Header-anchorTitle\">Subdir Title</span>");
    assertThat(subdirReadmeHtml)
        .contains("<li><a href=\"/b/repo/+/master/subdir/index.md\">Sub Home</a></li>");
    assertThat(subdirReadmeHtml)
        .contains("<li><a href=\"/b/repo/+/master/subdir/README.md\">Sub README</a></li>");
    assertThat(subdirReadmeHtml)
        .contains(
            "<h1><a class=\"h\" name=\"subdir-page\" href=\"#subdir-page\"><span></span>"
                + "</a>subdir page</h1>");
    assertThat(subdirReadmeHtml)
        .doesNotContain("<li><a href=\"/b/repo/+/master/index.md\">Home</a></li>");
    assertThat(subdirReadmeHtml)
        .doesNotContain("<li><a href=\"/b/repo/+/master/README.md\">README</a></li>");
  }

  @Test
  public void dropsHtml() throws Exception {
    String markdown =
        "# B. Ad\n"
            + "\n"
            + "<script>window.alert();</script>\n"
            + "\n"
            + "Non-HTML <b>is fine</b>.";
    repo.branch("master").commit().add("index.md", markdown).create();

    String html = buildHtml("/repo/+doc/master/");
    assertThat(html).contains("B. Ad</h1>");
    assertThat(html).contains("Non-HTML is fine.");

    assertThat(html).doesNotContain("window.alert");
    assertThat(html).doesNotContain("<script>");
  }

  @Test
  public void namedAnchor() throws Exception {
    String markdown = "# Section {#debug}\n" + "# Other <a name=\"OLD-SCHOOL\"></a>\n";
    repo.branch("master").commit().add("index.md", markdown).create();
    String html = buildHtml("/repo/+doc/master/");
    assertThat(html)
        .contains(
            "<h1>"
                + "<a class=\"h\" name=\"debug\" href=\"#debug\"><span></span></a>"
                + "Section</h1>");
    assertThat(html)
        .contains(
            "<h1>"
                + "<a class=\"h\" name=\"OLD-SCHOOL\" href=\"#OLD-SCHOOL\"><span></span></a>"
                + "<a class=\"h\" name=\"old-school\" href=\"#old-school\"><span></span></a>"
                + "Other</h1>");
  }

  @Test
  public void incompleteHtmlIsLiteral() throws Exception {
    String markdown = "Incomplete <html is literal.";
    repo.branch("master").commit().add("index.md", markdown).create();

    String html = buildHtml("/repo/+doc/master/index.md");
    assertThat(html).contains("Incomplete &lt;html is literal.");
  }

  @Test
  public void noteInList() throws Exception {
    String markdown =
        "+ one\n\n" + "    ***aside\n" + "    remember this\n" + "    ***\n" + "\n" + "+ two\n";
    repo.branch("master").commit().add("index.md", markdown).create();

    String html = buildHtml("/repo/+/master/index.md");
    System.out.println(html);
    assertThat(html)
        .contains(
            "<ul><li><p>one</p><div class=\"aside\">remember this</div>"
                + "</li><li><p>two</p></li></ul>");
  }

  @Test
  public void relativeLink() throws Exception {
    repo.branch("master").commit().add("A/B/README.md", "[c](../../C)").create();

    String html = buildHtml("/repo/+doc/master/A/B/README.md");
    assertThat(html).contains("<a href=\"/b/repo/+/master/C\">c</a>");
  }

  @Test
  public void absoluteLink() throws Exception {
    repo.branch("master").commit().add("README.md", "[c](/x)").create();

    String html = buildHtml("/repo/+doc/master/README.md");
    assertThat(html).contains("<a href=\"/b/repo/+/master/x\">c</a>");
  }

  @Test
  public void gitUrlLink() throws Exception {
    repo.branch("master").commit().add("README.md", "[c](git://example.com/repo.git)").create();

    String html = buildHtml("/repo/+doc/master/README.md");
    assertThat(html).contains("<a href=\"git://example.com/repo.git\">c</a>");
  }

  @Test
  public void invalidGitUrlLink() throws Exception {
    repo.branch("master").commit().add("README.md", "[c](git://example.com/repo/..)").create();

    String html = buildHtml("/repo/+doc/master/README.md");
    assertThat(html).contains("<a href=\"about:invalid#zSoyz\">c</a>");
  }
}
