/
t3
/
mock-server
Обзор
Документация
Войти
/
t3
/
mock-server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
tests/user_api_test.go
353 строки
9 KB
Ivan
tests
02 июл 2026, 17:21
02 июл 2026, 17:21
d287a7e
Код
Авторство
О чём код?
package tests import ( "encoding/json" "io" "net/http" "net/http/httptest" "strings" "testing" "gitverse.ru/t3/mock-server/internal/application" "gitverse.ru/t3/mock-server/internal/domain/handler" "gitverse.ru/t3/mock-server/internal/domain/repository" "gitverse.ru/t3/mock-server/internal/domain/service" ) type testUser struct { ID string `json:"id"` Name string `json:"name"` Created int64 `json:"created"` } func setupServer() *httptest.Server { userRepo := repository.NewMemoryUserRepo() userService := service.NewUserService(userRepo) userHandler := handler.NewUserHandler(userService) router := application.NewRouter(userHandler) return httptest.NewServer(router) } func parseUserList(t *testing.T, body string) []testUser { t.Helper() var users []testUser if err := json.Unmarshal([]byte(body), &users); err != nil { t.Fatalf("failed to unmarshal user list: %v", err) } return users } func parseUser(t *testing.T, body string) testUser { t.Helper() var user testUser if err := json.Unmarshal([]byte(body), &user); err != nil { t.Fatalf("failed to unmarshal user: %v", err) } return user } func mustRequest(t *testing.T, method, url, contentType, body string) *http.Response { t.Helper() req, err := http.NewRequest(method, url, strings.NewReader(body)) if err != nil { t.Fatalf("failed to create request: %v", err) } if contentType != "" { req.Header.Set("Content-Type", contentType) } resp, err := http.DefaultClient.Do(req) if err != nil { t.Fatalf("request failed: %v", err) } return resp } // GET /users — empty list func TestListUsers_Empty(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "GET", srv.URL+"/users", "", "") defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("expected 200, got %d", resp.StatusCode) } users := parseUserList(t, respString(t, resp)) if len(users) != 0 { t.Fatalf("expected empty list, got %d users", len(users)) } } // GET /users — with users func TestListUsers_WithUsers(t *testing.T) { srv := setupServer() defer srv.Close() // create two users user1 := createUser(t, srv, "Alice") user2 := createUser(t, srv, "Bob") resp := mustRequest(t, "GET", srv.URL+"/users", "", "") defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("expected 200, got %d", resp.StatusCode) } users := parseUserList(t, respString(t, resp)) if len(users) != 2 { t.Fatalf("expected 2 users, got %d", len(users)) } // verify both users are present names := make(map[string]bool) for _, u := range users { names[u.Name] = true } if !names[user1.Name] || !names[user2.Name] { t.Fatalf("expected both Alice and Bob in the list, got %v", names) } } // GET /user/{id} — success func TestFindUserByID_Success(t *testing.T) { srv := setupServer() defer srv.Close() created := createUser(t, srv, "Charlie") resp := mustRequest(t, "GET", srv.URL+"/user/"+created.ID, "", "") defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("expected 200, got %d", resp.StatusCode) } user := parseUser(t, respString(t, resp)) if user.ID != created.ID { t.Fatalf("expected id %q, got %q", created.ID, user.ID) } if user.Name != "Charlie" { t.Fatalf("expected name 'Charlie', got %q", user.Name) } if user.Created <= 0 { t.Fatal("expected created timestamp > 0") } } // GET /user/{id} — not found func TestFindUserByID_NotFound(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "GET", srv.URL+"/user/00000000-0000-0000-0000-000000000000", "", "") defer resp.Body.Close() if resp.StatusCode != http.StatusNotFound { t.Fatalf("expected 404, got %d", resp.StatusCode) } } // POST /users — success func TestCreateUser_Success(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "POST", srv.URL+"/users", "application/json", `{"name":"Ivan Ivanov"}`) defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("expected 200, got %d", resp.StatusCode) } user := parseUser(t, respString(t, resp)) if user.ID == "" { t.Fatal("expected non-empty id") } if user.Name != "Ivan Ivanov" { t.Fatalf("expected name 'Ivan Ivanov', got %q", user.Name) } if user.Created <= 0 { t.Fatal("expected created timestamp > 0") } // verify user can be found resp2 := mustRequest(t, "GET", srv.URL+"/user/"+user.ID, "", "") defer resp2.Body.Close() if resp2.StatusCode != http.StatusOK { t.Fatalf("expected 200 when finding created user, got %d", resp2.StatusCode) } } // POST /users — empty name func TestCreateUser_EmptyName(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "POST", srv.URL+"/users", "application/json", `{"name":""}`) defer resp.Body.Close() if resp.StatusCode != http.StatusBadRequest { t.Fatalf("expected 400, got %d", resp.StatusCode) } } // POST /users — invalid JSON func TestCreateUser_InvalidJSON(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "POST", srv.URL+"/users", "application/json", `{invalid}`) defer resp.Body.Close() if resp.StatusCode != http.StatusBadRequest { t.Fatalf("expected 400, got %d", resp.StatusCode) } } // POST /users — wrong Content-Type func TestCreateUser_WrongContentType(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "POST", srv.URL+"/users", "text/plain", `{"name":"Ivan"}`) defer resp.Body.Close() if resp.StatusCode != http.StatusUnsupportedMediaType { t.Fatalf("expected 415, got %d", resp.StatusCode) } } // DELETE /user/{id} — success func TestDeleteUser_Success(t *testing.T) { srv := setupServer() defer srv.Close() created := createUser(t, srv, "Dave") resp := mustRequest(t, "DELETE", srv.URL+"/user/"+created.ID, "", "") defer resp.Body.Close() if resp.StatusCode != http.StatusNoContent { t.Fatalf("expected 204, got %d", resp.StatusCode) } // verify user is gone resp2 := mustRequest(t, "GET", srv.URL+"/user/"+created.ID, "", "") defer resp2.Body.Close() if resp2.StatusCode != http.StatusNotFound { t.Fatalf("expected 404 after delete, got %d", resp2.StatusCode) } } // DELETE /user/{id} — non-existent func TestDeleteUser_NonExistent(t *testing.T) { srv := setupServer() defer srv.Close() resp := mustRequest(t, "DELETE", srv.URL+"/user/00000000-0000-0000-0000-000000000000", "", "") defer resp.Body.Close() // current implementation returns 204 even for non-existent users if resp.StatusCode != http.StatusNoContent { t.Fatalf("expected 204, got %d", resp.StatusCode) } } // DELETE /users — delete all func TestDeleteAllUsers(t *testing.T) { srv := setupServer() defer srv.Close() createUser(t, srv, "Alice") createUser(t, srv, "Bob") resp := mustRequest(t, "DELETE", srv.URL+"/users", "", "") defer resp.Body.Close() if resp.StatusCode != http.StatusNoContent { t.Fatalf("expected 204, got %d", resp.StatusCode) } // verify list is empty resp2 := mustRequest(t, "GET", srv.URL+"/users", "", "") defer resp2.Body.Close() users := parseUserList(t, respString(t, resp2)) if len(users) != 0 { t.Fatalf("expected empty list after delete all, got %d users", len(users)) } } // Sequential scenario: create → list → find → delete → list func TestFullScenario(t *testing.T) { srv := setupServer() defer srv.Close() // 1. list is empty resp1 := mustRequest(t, "GET", srv.URL+"/users", "", "") defer resp1.Body.Close() users := parseUserList(t, respString(t, resp1)) if len(users) != 0 { t.Fatalf("expected 0 users initially, got %d", len(users)) } // 2. create a user user := createUser(t, srv, "Eve") // 3. list has 1 user resp3 := mustRequest(t, "GET", srv.URL+"/users", "", "") defer resp3.Body.Close() users = parseUserList(t, respString(t, resp3)) if len(users) != 1 { t.Fatalf("expected 1 user, got %d", len(users)) } // 4. find by id resp4 := mustRequest(t, "GET", srv.URL+"/user/"+user.ID, "", "") defer resp4.Body.Close() if resp4.StatusCode != http.StatusOK { t.Fatalf("expected 200, got %d", resp4.StatusCode) } found := parseUser(t, respString(t, resp4)) if found.Name != "Eve" { t.Fatalf("expected name 'Eve', got %q", found.Name) } // 5. delete resp5 := mustRequest(t, "DELETE", srv.URL+"/user/"+user.ID, "", "") defer resp5.Body.Close() if resp5.StatusCode != http.StatusNoContent { t.Fatalf("expected 204, got %d", resp5.StatusCode) } // 6. list is empty again resp6 := mustRequest(t, "GET", srv.URL+"/users", "", "") defer resp6.Body.Close() users = parseUserList(t, respString(t, resp6)) if len(users) != 0 { t.Fatalf("expected 0 users after delete, got %d", len(users)) } } // helpers func createUser(t *testing.T, srv *httptest.Server, name string) testUser { t.Helper() resp := mustRequest(t, "POST", srv.URL+"/users", "application/json", `{"name":"`+name+`"}`) defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("create user failed: expected 200, got %d", resp.StatusCode) } return parseUser(t, respString(t, resp)) } func respString(t *testing.T, resp *http.Response) string { t.Helper() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("failed to read body: %v", err) } return string(body) }