func main() { dbMap := InitDB() defer dbMap.Db.Close() dbMap.TraceOn("[gorp]", log.New(os.Stdout, "scribble: ", log.Lmicroseconds)) ctx := context.Background() kami.Context = context.WithValue(ctx, "db", dbMap) // Middlwares kami.Use("/api/", auth.AuthMiddleware) // Authentication APIs kami.Post("/api/register", handler.Register) kami.Post("/api/login", handler.Login) kami.Post("/api/logout", handler.Logout) // Note APIs kami.Get("/api/notes", handler.ListNotes) kami.Post("/api/notes", handler.AddNote) kami.Get("/api/notes/:noteId", handler.GetNote) kami.Put("/api/notes/:noteId", handler.UpdateNote) kami.Delete("/api/notes/:noteId", handler.DeleteNote) kami.Serve() }
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 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 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 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 main() { ctx := context.Background() kami.Context = ctx log.Println("start dispatcher...") StartDispatcher(2048) kami.Post("/work", greet) kami.Serve() }
func main() { var mongoUrl = flag.String("db", "petrucho-db", "MongoDB URL") flag.Parse() ctx := context.Background() ctx = db.OpenMongoDB(ctx, "main", *mongoUrl) defer db.Close(ctx) kami.Context = ctx secret := func(email, realm string) string { u := User{} users := userStorage(ctx) err := users.Find(bson.M{"email": email, "confirmed": true}).One(&u) if err != nil { return "" } return u.Password } authenticator := auth.NewBasicAuthenticator("Restricted", secret) kami.Get("/", homeHandler) kami.Get("/register", registrationForm) kami.Post("/register", registerUser) kami.Get("/confirm/:token", confirmRegistration) kami.Get("/users", viewAllUsers) kami.Get("/users/:email", viewUser) kami.Use("/users/:email/edit", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { var username string authenticator.Wrap(func(w http.ResponseWriter, r *auth.AuthenticatedRequest) { username = r.Username })(w, r) if len(username) == 0 { return nil } return context.WithValue(ctx, "auth", username) }) kami.Get("/users/:email/edit", editProfileForm) kami.Post("/users/:email/edit", updateProfile) kami.Serve() }
func main() { dbcon := PrePareDB() tmpls := template.Must(template.ParseGlob("./template/*.html")) ctx := context.Background() ctx = db.WithSQL(ctx, "main", dbcon) ctx = view.NewContext(ctx, tmpls) // dbを閉じる defer db.CloseSQLAll(ctx) // 神コンテキスト! kami.Context = ctx kami.Get("/", todo.Index) kami.Post("/create", todo.Create) kami.Post("/finish", todo.Finish) kami.Post("/delete", todo.Delete) kami.Serve() }
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 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 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 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 main() { runtime.GOMAXPROCS(30) sig := make(chan os.Signal) signal.Notify(sig, os.Interrupt) signal.Notify(sig, syscall.SIGTERM) ctx := context.Background() kami.Context = ctx kami.Post("/work", work) go func() { kami.Serve() }() <-sig }
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 main() { kami.Get("/", web.Form) kami.Post("/keyring", web.KeychainHandler) kami.Serve() }