package Api import ( "encoding/json" "errors" "fmt" "math/rand" "net/http" "net/http/httptest" "os" "path" "runtime" "strings" "testing" "time" "git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Api/Auth" "git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Database" "git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Models" "github.com/gorilla/mux" ) func init() { // Fix working directory for tests _, filename, _, _ := runtime.Caller(0) dir := path.Join(path.Dir(filename), "..") err := os.Chdir(dir) if err != nil { panic(err) } Database.InitTest() r = mux.NewRouter() } var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") func randString(n int) string { b := make([]rune, n) for i := range b { b[i] = letterRunes[rand.Intn(len(letterRunes))] } return string(b) } func createTestUser(random bool) (Models.User, error) { now := time.Now() email := "email@email.com" if random { email = fmt.Sprintf("%s@email.com", randString(16)) } password, err := Auth.HashPassword("password") if err != nil { return Models.User{}, err } userData := Models.User{ Email: email, Password: password, LastLogin: &now, FirstName: "Hugh", LastName: "Mann", } err = Database.CreateUser(&userData) return userData, err } func login() (*http.Cookie, Models.User, error) { var ( c *http.Cookie u Models.User ) r.HandleFunc("/admin/login", Auth.Login).Methods("POST") ts := httptest.NewServer(r) defer ts.Close() u, err := createTestUser(true) if err != nil { return c, u, err } postJson := ` { "email": "%s", "password": "password" } ` postJson = fmt.Sprintf(postJson, u.Email) res, err := http.Post(ts.URL+"/admin/login", "application/json", strings.NewReader(postJson)) if err != nil { return c, u, err } if res.StatusCode != http.StatusOK { return c, u, errors.New("Invalid res.StatusCode") } if len(res.Cookies()) != 1 { return c, u, errors.New("Invalid cookies length") } return res.Cookies()[0], u, nil } func Test_getUser(t *testing.T) { t.Log("Testing getUser...") r.HandleFunc("/user/{userID}", getUser).Methods("GET") ts := httptest.NewServer(r) defer ts.Close() c, u, err := login() if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } req, err := http.NewRequest("GET", fmt.Sprintf( "%s/user/%s", ts.URL, u.ID, ), nil) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } req.AddCookie(c) res, err := http.DefaultClient.Do(req) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) t.FailNow() } getUserData := new(Models.User) err = json.NewDecoder(res.Body).Decode(getUserData) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } if getUserData.Email != u.Email { t.Errorf("Expected email \"%s\", recieved %s", u.Email, getUserData.Email) t.FailNow() } if getUserData.FirstName != u.FirstName { t.Errorf("Expected email \"%s\", recieved %s", u.FirstName, getUserData.FirstName) t.FailNow() } if getUserData.LastName != u.LastName { t.Errorf("Expected email \"%s\", recieved %s", u.LastName, getUserData.LastName) t.FailNow() } } func Test_getUsers(t *testing.T) { t.Log("Testing getUsers...") r.HandleFunc("/user", getUsers).Methods("GET") ts := httptest.NewServer(r) defer ts.Close() c, _, err := login() if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } for i := 0; i < 20; i++ { createTestUser(true) } req, err := http.NewRequest("GET", ts.URL+"/user?page=1&pageSize=10", nil) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } req.AddCookie(c) res, err := http.DefaultClient.Do(req) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) t.FailNow() } getUsersData := new([]Models.User) err = json.NewDecoder(res.Body).Decode(getUsersData) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } if len(*getUsersData) != 10 { t.Errorf("Expected 10, recieved %d", len(*getUsersData)) t.FailNow() } } func Test_createUser(t *testing.T) { t.Log("Testing createUser...") r.HandleFunc("/user", createUser).Methods("POST") ts := httptest.NewServer(r) defer ts.Close() email := fmt.Sprintf("%s@email.com", randString(16)) postJson := ` { "email": "%s", "password": "password", "confirm_password": "password", "first_name": "Hugh", "last_name": "Mann" } ` postJson = fmt.Sprintf(postJson, email) res, err := http.Post(ts.URL+"/user", "application/json", strings.NewReader(postJson)) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) return } if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) return } } func Test_updateUser(t *testing.T) { t.Log("Testing updateUser...") r.HandleFunc("/user/{userID}", updateUser).Methods("PUT") ts := httptest.NewServer(r) defer ts.Close() c, u, err := login() if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } email := fmt.Sprintf("%s@email.com", randString(16)) postJson := ` { "email": "%s", "first_name": "first", "last_name": "last" } ` postJson = fmt.Sprintf(postJson, email) req, err := http.NewRequest("PUT", fmt.Sprintf( "%s/user/%s", ts.URL, u.ID, ), strings.NewReader(postJson)) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } req.AddCookie(c) // Fetch Request res, err := http.DefaultClient.Do(req) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } defer res.Body.Close() if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) } updateUserData := new(Models.User) err = json.NewDecoder(res.Body).Decode(updateUserData) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } if updateUserData.Email != email { t.Errorf("Expected email \"%s\", recieved %s", email, updateUserData.Email) } if updateUserData.FirstName != "first" { t.Errorf("Expected FirstName \"first\", recieved %s", updateUserData.FirstName) } if updateUserData.LastName != "last" { t.Errorf("Expected LastName \"last\", recieved %s", updateUserData.LastName) } } func Test_deleteUser(t *testing.T) { t.Log("Testing deleteUser...") r.HandleFunc("/user/{userID}", deleteUser).Methods("DELETE") ts := httptest.NewServer(r) defer ts.Close() c, _, err := login() if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } userData, err := createTestUser(true) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) t.FailNow() } req, err := http.NewRequest("DELETE", fmt.Sprintf( "%s/user/%s", ts.URL, userData.ID, ), nil) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } req.AddCookie(c) // Fetch Request res, err := http.DefaultClient.Do(req) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) return } defer res.Body.Close() if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) } }