// Copyright 2015 The Go Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd. package talksapp import ( "fmt" "net/http" "net/http/httptest" "net/url" "strings" "testing" "time" "google.golang.org/appengine" "google.golang.org/appengine/aetest" "google.golang.org/appengine/memcache" "github.com/golang/gddo/gosrc" ) const importPath = "github.com/user/repo/path/to/presentation.slide" func TestHome(t *testing.T) { do(t, "GET", "/", func(r *http.Request) { w := httptest.NewRecorder() handlerFunc(serveRoot).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code) } if !strings.Contains(w.Body.String(), "go-talks.appspot.org") { t.Fatal("expected response to contain: go-talks.appspot.org") } }) } func TestPresentation(t *testing.T) { presentationTitle := "My awesome presentation!" presentationSrc := []byte(presentationTitle + ` Subtitle * Slide 1 - Foo - Bar - Baz `) originalGetPresentation := getPresentation getPresentation = func(client *http.Client, importPath string) (*gosrc.Presentation, error) { return &gosrc.Presentation{ Filename: "presentation.slide", Files: map[string][]byte{ "presentation.slide": presentationSrc, }, }, nil } defer func() { getPresentation = originalGetPresentation }() do(t, "GET", "/"+importPath, func(r *http.Request) { w := httptest.NewRecorder() handlerFunc(serveRoot).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code) } if !strings.Contains(w.Body.String(), presentationTitle) { t.Fatalf("unexpected response body: %s", w.Body) } c := appengine.NewContext(r) _, err := memcache.Get(c, importPath) if err == memcache.ErrCacheMiss { t.Fatal("expected result to be cached") } if err != nil { t.Fatalf("expected no error, got: %s", err) } }) } func TestPresentationCacheHit(t *testing.T) { do(t, "GET", "/"+importPath, func(r *http.Request) { cachedPresentation := "
My Presentation
" c := appengine.NewContext(r) memcache.Add(c, &memcache.Item{ Key: importPath, Value: []byte(cachedPresentation), Expiration: time.Hour, }) w := httptest.NewRecorder() handlerFunc(serveRoot).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code) } if w.Body.String() != cachedPresentation { t.Fatal("response does not matched cached presentation") } }) } func TestPresentationNotFound(t *testing.T) { originalGetPresentation := getPresentation getPresentation = func(client *http.Client, importPath string) (*gosrc.Presentation, error) { return nil, gosrc.NotFoundError{} } defer func() { getPresentation = originalGetPresentation }() do(t, "GET", "/"+importPath, func(r *http.Request) { w := httptest.NewRecorder() handlerFunc(serveRoot).ServeHTTP(w, r) if w.Code != http.StatusBadRequest { t.Fatalf("expected status: %d, got: %d", http.StatusBadRequest, w.Code) } }) } func TestWrongMethod(t *testing.T) { do(t, "POST", "/", func(r *http.Request) { w := httptest.NewRecorder() handlerFunc(serveRoot).ServeHTTP(w, r) if w.Code != http.StatusMethodNotAllowed { t.Fatalf("expected status %d", http.StatusMethodNotAllowed) } }) } func TestCompile(t *testing.T) { version := "2" body := ` package main import "fmt" func main() { fmt.fmtPrintln("Hello, playground") } ` responseJSON := `{"Errors":"","Events":[{"Message":"Hello, playground\n","Kind":"stdout","Delay":0}]}` server := httptest.NewServer( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { formVersion := r.FormValue("version") formBody := r.FormValue("body") if formVersion != version { t.Fatalf("expected version sent to play.golang.org to be: %s, was: %s", version, formVersion) } if formBody != body { t.Fatalf("expected body sent to play.golang.org to be: %s, was: %s", body, formBody) } w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) fmt.Fprintln(w, responseJSON) }), ) defer server.Close() defer func(old string) { playCompileURL = old }(playCompileURL) playCompileURL = server.URL do(t, "POST", "/compile", func(r *http.Request) { r.PostForm = url.Values{ "version": []string{version}, "body": []string{body}, } w := httptest.NewRecorder() handlerFunc(serveCompile).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code) } contentType := w.Header().Get("Content-Type") if w.Header().Get("Content-Type") != "application/json" { t.Fatalf("unexpected Content-Type: %s", contentType) } if strings.TrimSpace(w.Body.String()) != responseJSON { t.Fatalf("unexpected response body: %s", w.Body) } }) } func TestBot(t *testing.T) { do(t, "GET", "/bot.html", func(r *http.Request) { w := httptest.NewRecorder() handlerFunc(serveBot).ServeHTTP(w, r) if w.Code != http.StatusOK { t.Fatalf("expected status: %d, got: %d", http.StatusOK, w.Code) } if !strings.Contains(w.Body.String(), contactEmail) { t.Fatalf("expected body to contain %s", contactEmail) } }) } func do(t *testing.T, method, path string, f func(*http.Request)) { i, err := aetest.NewInstance(nil) if err != nil { t.Fatal(err) } defer i.Close() r, err := i.NewRequest(method, path, nil) if err != nil { t.Fatal(err) } f(r) }