func TestGetNote(t *testing.T) { assert := assert.New(t) dbMap := initDb() defer dbMap.Db.Close() ctx := context.Background() ctx = context.WithValue(ctx, "db", dbMap) ctx = context.WithValue(ctx, "auth", &auth.AuthContext{}) dbMap.Insert(&model.Note{ Id: 0, Title: "Test Title 1", Content: "lorem ipsum dolor sit amet consetetur.", OwnerId: 0, CreatedAt: 1442284669000, UpdatedAt: 1442292926000, }) kami.Reset() kami.Context = ctx kami.Post("/api/notes/:noteId", GetNote) server := httptest.NewServer(kami.Handler()) defer server.Close() resp := request(t, server.URL+"/api/notes/1", http.StatusOK, nil) assert.NotNil(resp) note := resp.(map[string]interface{}) assert.Equal("Test Title 1", note["title"]) assert.Equal("lorem ipsum dolor sit amet consetetur.", note["content"]) assert.EqualValues(0, note["ownerId"]) assert.EqualValues(1442284669000, note["createdAt"]) assert.EqualValues(1442292926000, note["updatedAt"]) }
func TestPanickingLogger(t *testing.T) { kami.Reset() kami.LogHandler = func(ctx context.Context, w mutil.WriterProxy, r *http.Request) { t.Log("log handler") panic("test panic") } kami.PanicHandler = kami.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { t.Log("panic handler") err := kami.Exception(ctx) if err != "test panic" { t.Error("unexpected exception:", err) } w.WriteHeader(500) w.Write([]byte("error 500")) }) kami.Post("/test", noop) resp := httptest.NewRecorder() req, err := http.NewRequest("POST", "/test", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != 500 { t.Error("should return HTTP 500", resp.Code, "≠", 500) } }
func TestNotFound(t *testing.T) { kami.Reset() kami.Use("/missing/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "ok", true) }) kami.NotFound(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { ok, _ := ctx.Value("ok").(bool) if !ok { w.WriteHeader(500) return } w.WriteHeader(420) }) resp := httptest.NewRecorder() req, err := http.NewRequest("GET", "/missing/hello", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != 420 { t.Error("should return HTTP 420", resp.Code, "≠", 420) } }
func BenchmarkMiddleware5(b *testing.B) { kami.Reset() numbers := []int{1, 2, 3, 4, 5} for _, n := range numbers { n := n // wtf kami.Use("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, n, n) }) } kami.Get("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { for _, n := range numbers { if ctx.Value(n) != n { w.WriteHeader(501) return } } }) for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/test", nil) kami.Handler().ServeHTTP(resp, req) if resp.Code != 200 { panic(resp.Code) } } }
func TestDeleteNote(t *testing.T) { assert := assert.New(t) dbMap := initDb() defer dbMap.Db.Close() ctx := context.Background() ctx = context.WithValue(ctx, "db", dbMap) ctx = context.WithValue(ctx, "auth", &auth.AuthContext{}) dbMap.Insert(&model.Note{ Id: 0, Title: "Test Title 1", Content: "lorem ipsum dolor sit amet consetetur.", OwnerId: 0, CreatedAt: 1442284669000, UpdatedAt: 1442292926000, }) count, err := dbMap.SelectInt("SELECT COUNT(id) FROM notes") assert.Nil(err) assert.EqualValues(1, count) kami.Reset() kami.Context = ctx kami.Post("/api/notes/:noteId", DeleteNote) server := httptest.NewServer(kami.Handler()) defer server.Close() request(t, server.URL+"/api/notes/1", http.StatusOK, nil) count, err = dbMap.SelectInt("SELECT COUNT(id) FROM notes") assert.Nil(err) assert.EqualValues(0, count) }
func BenchmarkMiddleware5Afterware1(b *testing.B) { kami.Reset() numbers := []int{1, 2, 3, 4, 5} for _, n := range numbers { n := n // wtf kami.Use("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, n, n) }) } kami.After("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { for _, n := range numbers { if ctx.Value(n) != n { panic(n) } } return ctx }) kami.Get("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { for _, n := range numbers { if ctx.Value(n) != n { w.WriteHeader(http.StatusServiceUnavailable) return } } }) req, _ := http.NewRequest("GET", "/test", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func TestLoggerAndPanic(t *testing.T) { kami.Reset() // test logger with panic status := 0 kami.LogHandler = func(ctx context.Context, w mutil.WriterProxy, r *http.Request) { status = w.Status() } kami.PanicHandler = kami.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { err := kami.Exception(ctx) if err != "test panic" { t.Error("unexpected exception:", err) } w.WriteHeader(http.StatusServiceUnavailable) }) kami.Post("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { panic("test panic") }) kami.Put("/ok", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) expectResponseCode(t, "POST", "/test", http.StatusServiceUnavailable) if status != http.StatusServiceUnavailable { t.Error("log handler received wrong status code", status, "≠", http.StatusServiceUnavailable) } // test loggers without panics expectResponseCode(t, "PUT", "/ok", http.StatusOK) if status != http.StatusOK { t.Error("log handler received wrong status code", status, "≠", http.StatusOK) } }
func TestMethodNotAllowedDefault(t *testing.T) { kami.Reset() kami.Post("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { panic("test panic") }) expectResponseCode(t, "GET", "/test", http.StatusMethodNotAllowed) }
func BenchmarkParameter(b *testing.B) { kami.Reset() kami.Get("/hello/:name", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { kami.Param(ctx, "name") }) req, _ := http.NewRequest("GET", "/hello/bob", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func routeBench(b *testing.B, route string) { kami.Reset() kami.Use("/Z/", noopMW) kami.After("/Z/", noopMW) kami.Get(route, noop) req, _ := http.NewRequest("GET", route, nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func BenchmarkStaticRoute(b *testing.B) { kami.Reset() kami.Get("/hello", noop) for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/hello", nil) kami.Handler().ServeHTTP(resp, req) if resp.Code != 200 { panic(resp.Code) } } }
func TestLoggerAndPanic(t *testing.T) { kami.Reset() // test logger with panic status := 0 kami.LogHandler = func(ctx context.Context, w mutil.WriterProxy, r *http.Request) { status = w.Status() } kami.PanicHandler = kami.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { err := kami.Exception(ctx) if err != "test panic" { t.Error("unexpected exception:", err) } w.WriteHeader(500) w.Write([]byte("error 500")) }) kami.Post("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { panic("test panic") }) kami.Put("/ok", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }) resp := httptest.NewRecorder() req, err := http.NewRequest("POST", "/test", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != 500 { t.Error("should return HTTP 500", resp.Code, "≠", 500) } if status != 500 { t.Error("should return HTTP 500", status, "≠", 500) } // test loggers without panics resp = httptest.NewRecorder() req, err = http.NewRequest("PUT", "/ok", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != 200 { t.Error("should return HTTP 200", resp.Code, "≠", 200) } if status != 200 { t.Error("should return HTTP 200", status, "≠", 200) } }
func BenchmarkParameter5(b *testing.B) { kami.Reset() kami.Get("/:a/:b/:c/:d/:e", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { for _, v := range []string{"a", "b", "c", "d", "e"} { kami.Param(ctx, v) } }) req, _ := http.NewRequest("GET", "/a/b/c/d/e", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func TestNotFoundDefault(t *testing.T) { kami.Reset() resp := httptest.NewRecorder() req, err := http.NewRequest("GET", "/missing/hello", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != 404 { t.Error("should return HTTP 404", resp.Code, "≠", 404) } }
func TestUpdateNote(t *testing.T) { assert := assert.New(t) dbMap := initDb() defer dbMap.Db.Close() ctx := context.Background() ctx = context.WithValue(ctx, "db", dbMap) ctx = context.WithValue(ctx, "auth", &auth.AuthContext{}) dbMap.Insert(&model.Note{ Id: 0, Title: "Test Title 1", Content: "lorem ipsum dolor sit amet consetetur.", OwnerId: 0, CreatedAt: 1442284669000, UpdatedAt: 1442292926000, }) kami.Reset() kami.Context = ctx kami.Post("/api/notes/:noteId", UpdateNote) server := httptest.NewServer(kami.Handler()) defer server.Close() resp := request(t, server.URL+"/api/notes/1", http.StatusOK, map[string]interface{}{ "title": "Test Title 2", "content": "hoge piyo hoge piyo.", "ownerId": 1, }) assert.NotNil(resp) note := resp.(map[string]interface{}) assert.Equal("Test Title 2", note["title"]) assert.Equal("hoge piyo hoge piyo.", note["content"]) assert.EqualValues(1, note["ownerId"]) assert.EqualValues(1442284669000, note["createdAt"]) count, err := dbMap.SelectInt("SELECT COUNT(id) FROM notes") assert.Nil(err) assert.EqualValues(1, count) n := new(model.Note) err = dbMap.SelectOne(n, "SELECT * FROM notes") assert.Nil(err) assert.Equal("Test Title 2", n.Title) assert.Equal("hoge piyo hoge piyo.", n.Content) assert.EqualValues(1, n.OwnerId) assert.EqualValues(1442284669000, n.CreatedAt) }
func TestNotFound(t *testing.T) { kami.Reset() kami.Use("/missing/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "ok", true) }) kami.NotFound(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { ok, _ := ctx.Value("ok").(bool) if !ok { w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusTeapot) }) expectResponseCode(t, "GET", "/missing/hello", http.StatusTeapot) }
func TestEnableMethodNotAllowed(t *testing.T) { kami.Reset() kami.Post("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { panic("test panic") }) // Handling enabled by default expectResponseCode(t, "GET", "/test", http.StatusMethodNotAllowed) // Not found deals with it when handling disabled kami.EnableMethodNotAllowed(false) expectResponseCode(t, "GET", "/test", http.StatusNotFound) // And MethodNotAllowed status when handling enabled kami.EnableMethodNotAllowed(true) expectResponseCode(t, "GET", "/test", http.StatusMethodNotAllowed) }
func BenchmarkMiddleware(b *testing.B) { kami.Reset() kami.Use("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test", "ok") }) kami.Get("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { if ctx.Value("test") != "ok" { w.WriteHeader(http.StatusServiceUnavailable) } }) req, _ := http.NewRequest("GET", "/test", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func TestCloseHandler(t *testing.T) { called := false closeHandler := func(ctx context.Context, r *http.Request) { called = true } kami.Reset() kami.CloseHandler = closeHandler kami.Get("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { t.Log("TestCloseHandler") }) expectResponseCode(t, "GET", "/test", http.StatusOK) if called != true { t.Fatal("expected closeHandler to be called") } }
// This tests just the URL walking middleware engine. func BenchmarkMiddlewareAfterwareMiss(b *testing.B) { kami.Reset() kami.Use("/dog/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return nil }) kami.After("/dog/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return nil }) kami.Get("/a/bbb/cc/d/e", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) req, _ := http.NewRequest("GET", "/a/bbb/cc/d/e", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func TestPanickingLogger(t *testing.T) { kami.Reset() kami.LogHandler = func(ctx context.Context, w mutil.WriterProxy, r *http.Request) { t.Log("log handler") panic("test panic") } kami.PanicHandler = kami.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { t.Log("panic handler") err := kami.Exception(ctx) if err != "test panic" { t.Error("unexpected exception:", err) } w.WriteHeader(http.StatusServiceUnavailable) w.Write([]byte("error 503")) }) kami.Post("/test", noop) expectResponseCode(t, "POST", "/test", http.StatusServiceUnavailable) }
func BenchmarkMiddleware(b *testing.B) { kami.Reset() kami.Use("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test", "ok") }) kami.Get("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { if ctx.Value("test") != "ok" { w.WriteHeader(501) } }) for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/test", nil) kami.Handler().ServeHTTP(resp, req) if resp.Code != 200 { panic(resp.Code) } } }
func TestKami(t *testing.T) { kami.Reset() kami.Use("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test1", "1") }) kami.Use("/v2/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test2", "2") }) kami.Get("/v2/papers/:page", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { page := kami.Param(ctx, "page") if page == "" { panic("blank page") } io.WriteString(w, page) test1 := ctx.Value("test1").(string) test2 := ctx.Value("test2").(string) if test1 != "1" || test2 != "2" { t.Error("unexpected ctx value:", test1, test2) } }) resp := httptest.NewRecorder() req, err := http.NewRequest("GET", "/v2/papers/3", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != http.StatusOK { t.Error("should return HTTP OK", resp.Code, "≠", http.StatusOK) } data, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } if string(data) != "3" { t.Error("expected page 3, got", string(data)) } }
func TestMethodNotAllowed(t *testing.T) { kami.Reset() kami.Use("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "ok", true) }) kami.Post("/test", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { panic("test panic") }) kami.MethodNotAllowed(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { ok, _ := ctx.Value("ok").(bool) if !ok { w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusTeapot) }) expectResponseCode(t, "GET", "/test", http.StatusTeapot) }
func TestListNotesPagination(t *testing.T) { assert := assert.New(t) dbMap := initDb() defer dbMap.Db.Close() ctx := context.Background() ctx = context.WithValue(ctx, "db", dbMap) for i := 0; i < 100; i++ { dbMap.Insert(&model.Note{ Id: 0, Title: fmt.Sprintf("Test Title %d", i), Content: "lorem ipsum dolor sit amet consetetur.", OwnerId: 0, CreatedAt: 1442284669000, UpdatedAt: 1442284669000, }) } kami.Reset() kami.Context = ctx kami.Post("/api/notes", ListNotes) server := httptest.NewServer(kami.Handler()) defer server.Close() resp := request(t, server.URL+"/api/notes", http.StatusOK, nil) assert.NotNil(resp) assert.EqualValues(10, len(resp.([]interface{}))) resp = request(t, server.URL+"/api/notes?limit=25", http.StatusOK, nil) assert.NotNil(resp) assert.EqualValues(25, len(resp.([]interface{}))) resp = request(t, server.URL+"/api/notes?limit=50", http.StatusOK, nil) assert.NotNil(resp) assert.EqualValues(50, len(resp.([]interface{}))) }
func TestNotFoundDefault(t *testing.T) { kami.Reset() expectResponseCode(t, "GET", "/missing/hello", http.StatusNotFound) }