package service import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestAuthFlowRegisterLoginAndMe(t *testing.T) { previous := backendStore backendStore = newTestGORMStore(t) defer func() { backendStore = previous }() handler := NewHandler(Config{Name: "Auth Service", Domain: "auth"}) register := performJSONRequest(t, handler, http.MethodPost, "/api/auth/register", map[string]string{ "login": "qa_user", "password": "verysecret", "name": "QA User", }, "") if register.Code != http.StatusCreated { t.Fatalf("register status = %d body=%s", register.Code, register.Body.String()) } login := performJSONRequest(t, handler, http.MethodPost, "/api/auth/login", map[string]string{ "login": "qa_user", "password": "verysecret", }, "") if login.Code != http.StatusOK { t.Fatalf("login status = %d body=%s", login.Code, login.Body.String()) } token := readTokenFromResponse(t, login.Body.Bytes()) me := performJSONRequest(t, handler, http.MethodGet, "/api/auth/me", nil, token) if me.Code != http.StatusOK { t.Fatalf("me status = %d body=%s", me.Code, me.Body.String()) } var payload map[string]map[string]any if err := json.Unmarshal(me.Body.Bytes(), &payload); err != nil { t.Fatalf("decode me response: %v", err) } if payload["user"]["login"] != "qa_user" { t.Fatalf("expected qa_user, got %#v", payload["user"]["login"]) } } func TestAuthChangePassword(t *testing.T) { previous := backendStore backendStore = newTestGORMStore(t) defer func() { backendStore = previous }() handler := NewHandler(Config{Name: "Auth Service", Domain: "auth"}) login := performJSONRequest(t, handler, http.MethodPost, "/api/auth/login", map[string]string{ "login": "demo_admin", "password": "demo_password", }, "") if login.Code != http.StatusOK { t.Fatalf("initial login status = %d body=%s", login.Code, login.Body.String()) } token := readTokenFromResponse(t, login.Body.Bytes()) change := performJSONRequest(t, handler, http.MethodPost, "/api/auth/change-password", map[string]string{ "nextPassword": "demo_password_new", }, token) if change.Code != http.StatusOK { t.Fatalf("change password status = %d body=%s", change.Code, change.Body.String()) } oldLogin := performJSONRequest(t, handler, http.MethodPost, "/api/auth/login", map[string]string{ "login": "demo_admin", "password": "demo_password", }, "") if oldLogin.Code != http.StatusUnauthorized { t.Fatalf("old password login status = %d body=%s", oldLogin.Code, oldLogin.Body.String()) } newLogin := performJSONRequest(t, handler, http.MethodPost, "/api/auth/login", map[string]string{ "login": "demo_admin", "password": "demo_password_new", }, "") if newLogin.Code != http.StatusOK { t.Fatalf("new password login status = %d body=%s", newLogin.Code, newLogin.Body.String()) } } func performJSONRequest(t *testing.T, handler http.Handler, method, path string, body any, token string) *httptest.ResponseRecorder { t.Helper() var reader *bytes.Reader if body == nil { reader = bytes.NewReader(nil) } else { payload, err := json.Marshal(body) if err != nil { t.Fatalf("marshal request: %v", err) } reader = bytes.NewReader(payload) } recorder := httptest.NewRecorder() request := httptest.NewRequest(method, path, reader) if body != nil { request.Header.Set("Content-Type", "application/json") } if token != "" { request.Header.Set("Authorization", "Bearer "+token) } handler.ServeHTTP(recorder, request) return recorder } func readTokenFromResponse(t *testing.T, body []byte) string { t.Helper() var payload map[string]any if err := json.Unmarshal(body, &payload); err != nil { t.Fatalf("decode token response: %v", err) } token, _ := payload["token"].(string) if token == "" { t.Fatalf("expected token in response: %s", string(body)) } return token }