зеркало из https://github.com/golang/pkgsite.git
internal/pagecheck: add checks for overview pages
Change-Id: I643e59f9eb13f9b9abbf8c30daedb2264a3a65e3 Reviewed-on: https://team-review.git.corp.google.com/c/golang/discovery/+/602822 Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Родитель
cfef41cecc
Коммит
c77f28bf03
|
@ -17,7 +17,7 @@ import (
|
|||
"golang.org/x/discovery/internal"
|
||||
"golang.org/x/discovery/internal/middleware"
|
||||
"golang.org/x/discovery/internal/postgres"
|
||||
"golang.org/x/discovery/internal/stdlib"
|
||||
"golang.org/x/discovery/internal/source"
|
||||
"golang.org/x/discovery/internal/testing/htmlcheck"
|
||||
"golang.org/x/discovery/internal/testing/pagecheck"
|
||||
"golang.org/x/discovery/internal/testing/sample"
|
||||
|
@ -47,6 +47,18 @@ func TestHTMLInjection(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestServer checks the contents of served pages by looking for
|
||||
// strings and elements in the parsed HTML response body.
|
||||
//
|
||||
// Other than search and static content, our pages vary along five dimensions:
|
||||
//
|
||||
// 1. module / package / directory
|
||||
// 2. stdlib / other (since the standard library is a special case in several ways)
|
||||
// 3. redistributable / non-redistributable
|
||||
// 4. versioned / unversioned URL (whether the URL for the page contains "@version")
|
||||
// 5. the tab (overview / doc / imports / ...)
|
||||
//
|
||||
// We aim to test all combinations of these.
|
||||
func TestServer(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testTimeout)
|
||||
defer cancel()
|
||||
|
@ -58,6 +70,7 @@ func TestServer(t *testing.T) {
|
|||
v.ModulePath = modulePath
|
||||
v.Version = version
|
||||
v.Packages = pkgs
|
||||
v.SourceInfo = source.NewGitHubInfo(sample.RepositoryURL, "", version)
|
||||
if err := testDB.InsertVersion(ctx, v); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -88,7 +101,7 @@ func TestServer(t *testing.T) {
|
|||
pkgCmdGo := sample.Package()
|
||||
pkgCmdGo.Name = "main"
|
||||
pkgCmdGo.Path = "cmd/go"
|
||||
mustInsertVersion(stdlib.ModulePath, "v1.13.0", []*internal.Package{pkgCmdGo})
|
||||
mustInsertVersion("std", "v1.13.0", []*internal.Package{pkgCmdGo})
|
||||
|
||||
s, err := NewServer(testDB, nil, "../../content/static", false)
|
||||
if err != nil {
|
||||
|
@ -338,11 +351,14 @@ func TestServer(t *testing.T) {
|
|||
wantStatusCode: http.StatusOK,
|
||||
want: in("",
|
||||
pagecheck.PackageHeader(pkgV100, versioned),
|
||||
in(".Overview-sourceCodeLink a",
|
||||
href("github.com/valid_module_name"),
|
||||
text("github.com/valid_module_name")),
|
||||
in(".Overview-readmeContent", text("readme")),
|
||||
in(".Overview-readmeSource", text("Source: github.com/valid_module_name@v1.0.0/README.md"))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: "/mod/github.com/valid_module_name@v1.0.0",
|
||||
ModuleLinkText: pkgV100.ModulePath,
|
||||
RepoURL: "https://github.com/valid_module_name",
|
||||
PackageURL: "https://github.com/valid_module_name/tree/v1.0.0/foo",
|
||||
ReadmeContent: "readme",
|
||||
ReadmeSource: "github.com/valid_module_name@v1.0.0/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "package@version readme tab nonredistributable",
|
||||
|
@ -436,19 +452,13 @@ func TestServer(t *testing.T) {
|
|||
wantStatusCode: http.StatusOK,
|
||||
want: in("",
|
||||
pagecheck.DirectoryHeader(dir, unversioned),
|
||||
in(".Overview-module",
|
||||
text("Module"),
|
||||
in("a",
|
||||
href("/mod/github.com/valid_module_name"),
|
||||
text("github.com/valid_module_name"))),
|
||||
in(".Overview-sourceCodeLink",
|
||||
text("Repository"),
|
||||
in("a",
|
||||
href("github.com/valid_module_name"),
|
||||
attr("target", "_blank"),
|
||||
text("github.com/valid_module_name"))),
|
||||
in(".Overview-readmeContent", text("readme")),
|
||||
in(".Overview-readmeSource", text("Source: github.com/valid_module_name@v1.0.0/README.md"))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: "/mod/github.com/valid_module_name",
|
||||
ModuleLinkText: dir.ModulePath,
|
||||
RepoURL: "https://github.com/valid_module_name",
|
||||
ReadmeContent: "readme",
|
||||
ReadmeSource: "github.com/valid_module_name@v1.0.0/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "directory licenses",
|
||||
|
@ -481,21 +491,13 @@ func TestServer(t *testing.T) {
|
|||
wantStatusCode: http.StatusOK,
|
||||
want: in("",
|
||||
pagecheck.DirectoryHeader(dirCmd, versioned),
|
||||
|
||||
in(".Overview-module",
|
||||
text("Standard Library"),
|
||||
in("a",
|
||||
href("/std@go1.13"),
|
||||
text("Standard Library"))),
|
||||
in(".Overview-sourceCodeLink",
|
||||
text("Repository"),
|
||||
in("a",
|
||||
href("github.com/valid_module_name"),
|
||||
attr("target", "_blank"),
|
||||
text("github.com/valid_module_name"))),
|
||||
in(".Overview-readmeContent", text("readme")),
|
||||
in(".Overview-readmeSource",
|
||||
text(`^Source: go.googlesource.com/go/\+/refs/tags/go1.13/README.md$`))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: "/std@go1.13",
|
||||
ModuleLinkText: "Standard Library",
|
||||
ReadmeContent: "readme",
|
||||
RepoURL: "https://github.com/valid_module_name", // wrong, but hard to change
|
||||
ReadmeSource: "go.googlesource.com/go/+/refs/tags/go1.13/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "stdlib directory licenses",
|
||||
|
@ -513,7 +515,13 @@ func TestServer(t *testing.T) {
|
|||
// Fall back to the latest version, show readme tab by default.
|
||||
want: in("",
|
||||
pagecheck.ModuleHeader(mod, unversioned),
|
||||
in(".Overview-readmeContent", text(`readme`))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: "/mod/" + sample.ModulePath,
|
||||
ModuleLinkText: sample.ModulePath,
|
||||
ReadmeContent: "readme",
|
||||
RepoURL: "https://github.com/valid_module_name",
|
||||
ReadmeSource: "github.com/valid_module_name@v1.0.0/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "module overview",
|
||||
|
@ -523,10 +531,13 @@ func TestServer(t *testing.T) {
|
|||
// Fall back to the latest version, show readme tab by default.
|
||||
want: in("",
|
||||
pagecheck.ModuleHeader(mod, unversioned),
|
||||
in(".Overview-module a",
|
||||
href("/mod/"+sample.ModulePath),
|
||||
text("^"+sample.ModulePath+"$")),
|
||||
in(".Overview-readmeContent", text(`readme`))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: "/mod/" + sample.ModulePath,
|
||||
ModuleLinkText: sample.ModulePath,
|
||||
ReadmeContent: "readme",
|
||||
RepoURL: "https://github.com/valid_module_name",
|
||||
ReadmeSource: "github.com/valid_module_name@v1.0.0/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "module overview pseudoversion latest",
|
||||
|
@ -558,10 +569,13 @@ func TestServer(t *testing.T) {
|
|||
wantStatusCode: http.StatusOK,
|
||||
want: in("",
|
||||
pagecheck.ModuleHeader(mod, versioned),
|
||||
in(".Overview-module a",
|
||||
href(fmt.Sprintf("/mod/%s@%s", sample.ModulePath, sample.VersionString)),
|
||||
text("^"+sample.ModulePath+"$")),
|
||||
in(".Overview-readmeContent", text(`readme`))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: fmt.Sprintf("/mod/%s@%s", sample.ModulePath, sample.VersionString),
|
||||
ModuleLinkText: sample.ModulePath,
|
||||
ReadmeContent: "readme",
|
||||
RepoURL: "https://github.com/valid_module_name",
|
||||
ReadmeSource: "github.com/valid_module_name@v1.0.0/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "module@version overview tab, pseudoversion",
|
||||
|
@ -569,10 +583,13 @@ func TestServer(t *testing.T) {
|
|||
wantStatusCode: http.StatusOK,
|
||||
want: in("",
|
||||
pagecheck.ModuleHeader(modPseudo, versioned),
|
||||
in(".Overview-module a",
|
||||
href(fmt.Sprintf("/mod/%s@%s", sample.ModulePath, pseudoVersion)),
|
||||
text("^"+sample.ModulePath+"$")),
|
||||
in(".Overview-readmeContent", text(`readme`))),
|
||||
pagecheck.OverviewDetails(&pagecheck.Overview{
|
||||
ModuleLink: fmt.Sprintf("/mod/%s@%s", sample.ModulePath, pseudoVersion),
|
||||
ModuleLinkText: sample.ModulePath,
|
||||
ReadmeContent: "readme",
|
||||
RepoURL: "https://github.com/valid_module_name",
|
||||
ReadmeSource: "github.com/valid_module_name@" + pseudoVersion + "/README.md",
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: "module@version packages tab",
|
||||
|
|
|
@ -24,6 +24,8 @@ type Checker func(*html.Node) error
|
|||
//
|
||||
// Calling In(selector), with no checkers, just checks for the presence of
|
||||
// a node matching the selector. (For the negation, see NotIn.)
|
||||
//
|
||||
// A nil Checker is valid and always succeeds.
|
||||
func In(selector string, checkers ...Checker) Checker {
|
||||
sel := mustParseSelector(selector)
|
||||
return func(n *html.Node) error {
|
||||
|
@ -103,6 +105,9 @@ func NotIn(selector string) Checker {
|
|||
// check calls all the Checkers on n, returning the error of the first one to fail.
|
||||
func check(n *html.Node, Checkers []Checker) error {
|
||||
for _, m := range Checkers {
|
||||
if m == nil {
|
||||
continue
|
||||
}
|
||||
if err := m(n); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -30,6 +30,16 @@ type Page struct {
|
|||
ModuleURL string // the relative module URL
|
||||
}
|
||||
|
||||
// Overview describes the contents of the overview tab.
|
||||
type Overview struct {
|
||||
ModuleLink string // relative link to module page
|
||||
ModuleLinkText string
|
||||
RepoURL string
|
||||
PackageURL string
|
||||
ReadmeContent string
|
||||
ReadmeSource string
|
||||
}
|
||||
|
||||
var (
|
||||
in = htmlcheck.In
|
||||
inAt = htmlcheck.InAt
|
||||
|
@ -108,6 +118,26 @@ func LicenseDetails(ltype, bodySubstring, source string) htmlcheck.Checker {
|
|||
exactText("Source: "+source)))
|
||||
}
|
||||
|
||||
// OverviewDetails checks the details section of an overview tab.
|
||||
func OverviewDetails(ov *Overview) htmlcheck.Checker {
|
||||
var pkg htmlcheck.Checker
|
||||
if ov.PackageURL != "" {
|
||||
pkg = inAt(".Overview-sourceCodeLink a", 1,
|
||||
href(ov.PackageURL),
|
||||
exactText(ov.PackageURL))
|
||||
}
|
||||
return in("",
|
||||
in("div.Overview-module > a",
|
||||
href(ov.ModuleLink),
|
||||
exactText(ov.ModuleLinkText)),
|
||||
inAt(".Overview-sourceCodeLink a", 0,
|
||||
href(ov.RepoURL),
|
||||
exactText(ov.RepoURL)),
|
||||
pkg,
|
||||
in(".Overview-readmeContent", text(ov.ReadmeContent)),
|
||||
in(".Overview-readmeSource", exactText("Source: "+ov.ReadmeSource)))
|
||||
}
|
||||
|
||||
// versionBadge checks the latest-version badge on a header.
|
||||
func versionBadge(p *Page) htmlcheck.Checker {
|
||||
class := "DetailsHeader-"
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
// These sample values can be used to construct test cases.
|
||||
var (
|
||||
ModulePath = "github.com/valid_module_name"
|
||||
RepositoryURL = "github.com/valid_module_name"
|
||||
RepositoryURL = "https://github.com/valid_module_name"
|
||||
VersionString = "v1.0.0"
|
||||
CommitTime = NowTruncated()
|
||||
LicenseMetadata = []*license.Metadata{
|
||||
|
|
Загрузка…
Ссылка в новой задаче