package main import ( "bytes" "database/sql" "net/http" "net/http/httptest" "testing" ) type Handler func(db *sql.DB) http.Handler type httpCase struct { name string method string input string output string status int } func testHandler( t *testing.T, handler Handler, cases []httpCase, setup func(t *testing.T) *sql.DB, ) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { db := setup(t) in := bytes.NewReader([]byte(c.input)) rr := httptest.NewRecorder() req, err := http.NewRequest("POST", "/", in) if err != nil { t.Fatal(err) } handler(db).ServeHTTP(rr, req) if rr.Code != c.status { t.Errorf("handler returned wrong status code: got %v want %v", rr.Code, c.status) } if rr.Body.String() != string(c.output) { t.Errorf("handler returned unexpected body: got %v want %v", rr.Body.String(), string(c.output)) } }) } } func TestApiVersion(t *testing.T) { cases := []httpCase{ {"basic", "GET", ``, versionTxt, http.StatusOK}, } setup := func(t *testing.T) *sql.DB { return nil } testHandler(t, ApiVersion, cases, setup) } func TestApiAuthenticate(t *testing.T) { cases := []httpCase{ {"basic", "POST", `{"username":"testuser","password":"mypass"}`, "", http.StatusOK}, {"missing-password", "POST", `{"username":"testuser"}`, "", http.StatusBadRequest}, {"missing-username", "POST", `{"password":"mypass"}`, "", http.StatusBadRequest}, {"unknown-field", "POST", `{"username":"testuser","password":"mypass","foo":"bar"}`, "", http.StatusBadRequest}, {"invalid-json", "POST", `{username":"testuser","password":"mypass"}`, "", http.StatusBadRequest}, {"wrong-username", "POST", `{"username":"wronguser","password":"mypass"}`, "", http.StatusUnauthorized}, {"wrong-password", "POST", `{"username":"testuser","password":"wrongpass"}`, "", http.StatusUnauthorized}, } setup := func(t *testing.T) *sql.DB { db, _ := emptyDB(t) err := MigrateToLatest(db) if err != nil { t.Fatalf("Could not migrate test database: %v", err) } err = Register(db, "testuser", "mypass") if err != nil { t.Fatalf("Failed to register test user: %v", err) } return db } testHandler(t, ApiAuthentication, cases, setup) }