package handler import ( "dal-license-server/internal/model" "dal-license-server/internal/service" "encoding/json" "net/http" "net/http/httptest" "testing" ) func TestWriteJSON(t *testing.T) { w := httptest.NewRecorder() data := map[string]string{"key": "value"} writeJSON(w, http.StatusOK, data) if w.Code != http.StatusOK { t.Errorf("status: ocekivano 200, dobijeno %d", w.Code) } if ct := w.Header().Get("Content-Type"); ct != "application/json" { t.Errorf("Content-Type: ocekivano 'application/json', dobijeno %q", ct) } var result map[string]string json.Unmarshal(w.Body.Bytes(), &result) if result["key"] != "value" { t.Errorf("body: ocekivano 'value', dobijeno %q", result["key"]) } } func TestWriteJSON_StatusCreated(t *testing.T) { w := httptest.NewRecorder() writeJSON(w, http.StatusCreated, map[string]int{"id": 1}) if w.Code != http.StatusCreated { t.Errorf("status: ocekivano 201, dobijeno %d", w.Code) } } func TestWriteJSON_NilData(t *testing.T) { w := httptest.NewRecorder() writeJSON(w, http.StatusOK, nil) if w.Code != http.StatusOK { t.Errorf("status: ocekivano 200, dobijeno %d", w.Code) } } func TestWriteJSON_EmptySlice(t *testing.T) { w := httptest.NewRecorder() writeJSON(w, http.StatusOK, []string{}) body := w.Body.String() if body != "[]\n" { t.Errorf("body: ocekivano '[]\\n', dobijeno %q", body) } } func TestWriteError(t *testing.T) { w := httptest.NewRecorder() writeError(w, http.StatusBadRequest, "INVALID_KEY", "Kljuc nije pronadjen") if w.Code != http.StatusBadRequest { t.Errorf("status: ocekivano 400, dobijeno %d", w.Code) } var resp model.ErrorResponse json.Unmarshal(w.Body.Bytes(), &resp) if resp.Error.Code != "INVALID_KEY" { t.Errorf("error code: ocekivano 'INVALID_KEY', dobijeno %q", resp.Error.Code) } if resp.Error.Message != "Kljuc nije pronadjen" { t.Errorf("error message: ocekivano 'Kljuc nije pronadjen', dobijeno %q", resp.Error.Message) } } func TestWriteError_Unauthorized(t *testing.T) { w := httptest.NewRecorder() writeError(w, http.StatusUnauthorized, "UNAUTHORIZED", "Neautorizovan pristup") if w.Code != http.StatusUnauthorized { t.Errorf("status: ocekivano 401, dobijeno %d", w.Code) } } func TestWriteError_InternalServerError(t *testing.T) { w := httptest.NewRecorder() writeError(w, http.StatusInternalServerError, "INTERNAL_ERROR", "Nesto je poslo naopako") if w.Code != http.StatusInternalServerError { t.Errorf("status: ocekivano 500, dobijeno %d", w.Code) } } func TestWriteLicenseError(t *testing.T) { w := httptest.NewRecorder() err := &service.LicenseError{ Code: "ALREADY_ACTIVATED", Message: "Licenca je vec aktivirana", Details: map[string]interface{}{"activated_on": "PC-1"}, } writeLicenseError(w, err) if w.Code != http.StatusBadRequest { t.Errorf("status: ocekivano 400, dobijeno %d", w.Code) } var resp model.ErrorResponse json.Unmarshal(w.Body.Bytes(), &resp) if resp.Error.Code != "ALREADY_ACTIVATED" { t.Errorf("error code: ocekivano 'ALREADY_ACTIVATED', dobijeno %q", resp.Error.Code) } } func TestWriteLicenseError_GenericError(t *testing.T) { w := httptest.NewRecorder() writeLicenseError(w, &genericError{"some error"}) if w.Code != http.StatusInternalServerError { t.Errorf("status: ocekivano 500, dobijeno %d", w.Code) } var resp model.ErrorResponse json.Unmarshal(w.Body.Bytes(), &resp) if resp.Error.Code != "INTERNAL_ERROR" { t.Errorf("generic error mora vratiti INTERNAL_ERROR, dobijeno %q", resp.Error.Code) } } type genericError struct{ msg string } func (e *genericError) Error() string { return e.msg } func TestClientIP_RemoteAddr(t *testing.T) { req := httptest.NewRequest("GET", "/", nil) req.RemoteAddr = "1.2.3.4:5678" ip := clientIP(req) if ip != "1.2.3.4:5678" { t.Errorf("ocekivano '1.2.3.4:5678', dobijeno %q", ip) } } func TestClientIP_XForwardedFor(t *testing.T) { req := httptest.NewRequest("GET", "/", nil) req.RemoteAddr = "10.0.0.1:1234" req.Header.Set("X-Forwarded-For", "5.5.5.5") ip := clientIP(req) if ip != "5.5.5.5" { t.Errorf("ocekivano '5.5.5.5', dobijeno %q", ip) } } func TestClientIP_XRealIP(t *testing.T) { req := httptest.NewRequest("GET", "/", nil) req.RemoteAddr = "10.0.0.1:1234" req.Header.Set("X-Real-IP", "8.8.8.8") ip := clientIP(req) if ip != "8.8.8.8" { t.Errorf("ocekivano '8.8.8.8', dobijeno %q", ip) } } func TestClientIP_XForwardedFor_Priority(t *testing.T) { req := httptest.NewRequest("GET", "/", nil) req.RemoteAddr = "10.0.0.1:1234" req.Header.Set("X-Forwarded-For", "1.1.1.1") req.Header.Set("X-Real-IP", "2.2.2.2") ip := clientIP(req) if ip != "1.1.1.1" { t.Errorf("X-Forwarded-For mora imati prioritet, ocekivano '1.1.1.1', dobijeno %q", ip) } }