Skip to content

Commit

Permalink
internal/frontend: test redirect banner
Browse files Browse the repository at this point in the history
Verify that a redirect banner is added when appropriate,
and is not cached.

For golang/go#44210

Change-Id: Ib9b8cd8c67502724aeb0dbc79b1d5ce6784a67a3
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/292449
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
  • Loading branch information
jba committed Feb 17, 2021
1 parent 72b59e4 commit 365e265
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 13 deletions.
4 changes: 2 additions & 2 deletions internal/frontend/badge_test.go
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestBadgeHandler_ServeSVG(t *testing.T) {
_, handler, _ := newTestServer(t, nil)
_, handler, _ := newTestServer(t, nil, nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, httptest.NewRequest("GET", "/badge/net/http", nil))
if got, want := w.Result().Header.Get("Content-Type"), "image/svg+xml"; got != want {
Expand All @@ -20,7 +20,7 @@ func TestBadgeHandler_ServeSVG(t *testing.T) {
}

func TestBadgeHandler_ServeBadgeTool(t *testing.T) {
_, handler, _ := newTestServer(t, nil)
_, handler, _ := newTestServer(t, nil, nil)

tests := []struct {
url string
Expand Down
6 changes: 3 additions & 3 deletions internal/frontend/fetch_test.go
Expand Up @@ -79,7 +79,7 @@ func TestFetch(t *testing.T) {
},
} {
t.Run(test.name, func(t *testing.T) {
s, _, teardown := newTestServer(t, testModulesForProxy)
s, _, teardown := newTestServer(t, testModulesForProxy, nil)
defer teardown()

ctx, cancel := context.WithTimeout(context.Background(), testFetchTimeout)
Expand Down Expand Up @@ -143,7 +143,7 @@ func TestFetchErrors(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), test.fetchTimeout)
defer cancel()

s, _, teardown := newTestServer(t, testModulesForProxy)
s, _, teardown := newTestServer(t, testModulesForProxy, nil)
defer teardown()
got, err := s.fetchAndPoll(ctx, s.getDataSource(ctx), test.modulePath, test.fullPath, test.version)

Expand Down Expand Up @@ -180,7 +180,7 @@ func TestFetchPathAlreadyExists(t *testing.T) {
t.Fatal(err)
}

s, _, teardown := newTestServer(t, testModulesForProxy)
s, _, teardown := newTestServer(t, testModulesForProxy, nil)
defer teardown()
got, _ := s.fetchAndPoll(ctx, s.getDataSource(ctx), sample.ModulePath, sample.PackagePath, sample.VersionString)
if got != test.want {
Expand Down
65 changes: 57 additions & 8 deletions internal/frontend/server_test.go
Expand Up @@ -6,7 +6,9 @@ package frontend

import (
"context"
"errors"
"fmt"
"io"
"net/http"
"net/http/httptest"
"os"
Expand All @@ -15,6 +17,8 @@ import (
"testing"
"time"

"github.com/alicebob/miniredis/v2"
"github.com/go-redis/redis/v8"
"github.com/google/safehtml/template"
"github.com/jba/templatecheck"
"golang.org/x/net/html"
Expand All @@ -41,7 +45,7 @@ func TestMain(m *testing.M) {
}

func TestHTMLInjection(t *testing.T) {
_, handler, _ := newTestServer(t, nil)
_, handler, _ := newTestServer(t, nil, nil)
w := httptest.NewRecorder()
handler.ServeHTTP(w, httptest.NewRequest("GET", "/<em>UHOH</em>", nil))
if strings.Contains(w.Body.String(), "<em>") {
Expand Down Expand Up @@ -1168,7 +1172,7 @@ func testServer(t *testing.T, testCases []serverTestCase, experimentNames ...str
if err := testDB.InsertExcludedPrefix(ctx, excludedModulePath, "testuser", "testreason"); err != nil {
t.Fatal(err)
}
_, handler, _ := newTestServer(t, nil, experimentNames...)
_, handler, _ := newTestServer(t, nil, nil, experimentNames...)

experimentsSet := experiment.NewSet(experimentNames...)

Expand Down Expand Up @@ -1218,7 +1222,7 @@ func isSubset(subset, set *experiment.Set) bool {
}

func TestServerErrors(t *testing.T) {
_, handler, _ := newTestServer(t, nil)
_, handler, _ := newTestServer(t, nil, nil)
for _, test := range []struct {
name, path string
wantCode int
Expand Down Expand Up @@ -1287,7 +1291,13 @@ func TestServer404Redirect(t *testing.T) {
t.Fatal(err)
}

_, handler, _ := newTestServer(t, nil)
rs, err := miniredis.Run()
if err != nil {
t.Fatal(err)
}
defer rs.Close()

_, handler, _ := newTestServer(t, nil, redis.NewClient(&redis.Options{Addr: rs.Addr()}))

for _, test := range []struct {
name, path, flash string
Expand All @@ -1304,7 +1314,8 @@ func TestServer404Redirect(t *testing.T) {
if w.Code != http.StatusFound {
t.Errorf("%q: got status code = %d, want %d", test.path, w.Code, http.StatusFound)
}
c := findCookie(cookie.AlternativeModuleFlash, w.Result().Cookies())
res := w.Result()
c := findCookie(cookie.AlternativeModuleFlash, res.Cookies())
if c == nil && test.flash != "" {
t.Error("got no flash cookie, expected one")
} else if c != nil {
Expand All @@ -1313,9 +1324,28 @@ func TestServer404Redirect(t *testing.T) {
t.Fatal(err)
}
if val != test.flash {
t.Errorf("got cookie value %q, want %q", val, test.flash)
t.Fatalf("got cookie value %q, want %q", val, test.flash)
}
// If we have a cookie, then following the redirect URL with the cookie
// should serve a "redirected from" banner.
loc := res.Header.Get("Location")
r := httptest.NewRequest("GET", loc, nil)
r.AddCookie(c)
w = httptest.NewRecorder()
handler.ServeHTTP(w, r)
if err := checkBanner(w.Result().Body, val); err != nil {
t.Fatalf("banner: %v", err)
}
// Visiting the same page again without the cookie should not
// display the banner.
r = httptest.NewRequest("GET", loc, nil)
w = httptest.NewRecorder()
handler.ServeHTTP(w, r)
if err := checkBanner(w.Result().Body, val); err != errNoBanner {
t.Fatalf("banner #2: got %v, want %v", err, errNoBanner)
}
}

})
}
}
Expand All @@ -1329,6 +1359,24 @@ func findCookie(name string, cookies []*http.Cookie) *http.Cookie {
return nil
}

var errNoBanner = errors.New("no redirect banner")

func checkBanner(body io.ReadCloser, path string) error {
doc, err := html.Parse(body)
if err != nil {
return err
}
_ = body.Close()

if in(".UnitHeader-redirectedFromBanner--none")(doc) == nil {
return errNoBanner
}
if err := in(".UnitHeader-redirectedFromBanner", hasText(path))(doc); err != nil {
return err
}
return nil
}

func mustRequest(urlPath string, t *testing.T) *http.Request {
t.Helper()
r, err := http.NewRequest(http.MethodGet, "http://localhost"+urlPath, nil)
Expand Down Expand Up @@ -1390,7 +1438,7 @@ func TestTagRoute(t *testing.T) {
}
}

func newTestServer(t *testing.T, proxyModules []*proxy.Module, experimentNames ...string) (*Server, http.Handler, func()) {
func newTestServer(t *testing.T, proxyModules []*proxy.Module, redisClient *redis.Client, experimentNames ...string) (*Server, http.Handler, func()) {
t.Helper()
proxyClient, teardown := proxy.SetupTestClient(t, proxyModules)
sourceClient := source.NewClient(sourceTimeout)
Expand All @@ -1413,7 +1461,7 @@ func newTestServer(t *testing.T, proxyModules []*proxy.Module, experimentNames .
t.Fatal(err)
}
mux := http.NewServeMux()
s.Install(mux.Handle, nil, nil)
s.Install(mux.Handle, redisClient, nil)

var exps []*internal.Experiment
for _, n := range experimentNames {
Expand All @@ -1424,6 +1472,7 @@ func newTestServer(t *testing.T, proxyModules []*proxy.Module, experimentNames .
t.Fatal(err)
}
mw := middleware.Chain(
middleware.RedirectedFrom(),
middleware.Experiment(exp),
middleware.LatestVersions(s.GetLatestInfo))
return s, mw(mux), func() {
Expand Down

0 comments on commit 365e265

Please sign in to comment.